#import "lib.ih" #import "doors.ih" #import "debug.ih" #import "switches.ih" ! Alice Through the Looking Glass Implementation ! Shamelessly stolen from Gareth Rees' tutorial to see if it ! was possible in IAGE. LibraryMessage 1 "
THROUGH THE LOOKING GLASS
An interactive tutorial by Gareth Rees" LibraryMessage 200 "

It's a cold winter day outside, but in the looking-glass house it's summer. All you need to do is pretend there's a way of getting through into it somehow...
" LibraryMessage 201 "
1. About this game
2. About the implementation of this game
3. What am I supposed to do?

Please enter 1, 2 or 3 ------->" LibraryMessage 202 "This game was written by Gareth Rees as a tutorial for the Inform design system.

The IAGE port was written by Robin Rawson-Tetley, partly as an aid for anyone wanting to write complex games with IAGE, and partly as a proof of concept to show how good IAGE is." LibraryMessage 203 "This implementation covers everything in Gareth's original tutorial (http://www.gnelson.demon.co.uk/inform/alice/index.html). I did not implement the mirror reflection code because the puzzle design ensures that you would never be able to see anything in the mirror anyway (so it made little sense to me)." LibraryMessage 204 "The objective is to enter the looking glass - you need to find some way of occupying the kittens to move the chair over to it..." GameCode { Name "Alice" MaxItemsCanCarry 10 MaxWeightCanCarry 10 MaxSizeCanCarry 10 StartingLocation drawingroom Verbose yes ShowAvailableExits no AllowPersist no SinglePlayerGame yes MaxUsers 1 OverrideSecondaryNouns "66 68 69" UsingIAGECombat no UsingIAGEMoney no WideInventoryDisplay yes RealTimeNPCs no PlayersStayDead yes NPCsStayDead yes Initialise: CodeExtend [ ' Verbs for untangling the worsted addverb 150 untangle addverb 150 wind ' Verbs for help menu addverb 4 about addverb 4 info ] Start: Override [ ' Change name currentplayer.name = "Alice" ' Opening message message(200).show ' Show the game version, the library version ' and output the start location to the player game.displayversion call StandardLib.DisplayLibraryVersion game.displaycurrentlocation ' default male/female pronouns call NPCPronouns.init ] Score: Override [ currentplayer.print |"Alice has made " & currentplayer.turns & " moves."| ] DisplayBanner: Override [ ' Display score / turns returnvalue = |"Moves: " & currentplayer.turns| ] AfterInput: Override [ ' Overriding this in library because I do not want tight ' scope checking - we will be handling this ourselves. ;help,about,info var pans = ask message(201).text if ( pans = 1 ) then message(202).show endif if ( pans = 2 ) then message(203).show endif if ( pans = 3 ) then message(204).show endif end endif ' This line calls the standard AfterInput library, which generates ' stock responses. You can edit these responses by changing the ' messages 1 - 200 call StandardLib.AfterInput ] } Location drawingroom "Drawing Room" { has light Nouns "snow" Description "The gentle sound of snow against the window pane suggests that it's cold outside, and you're glad to be here in the warmth. The drawing-room is reflected in the large looking-glass on the wall above the mantelpiece, and a very comfortable room it is too, with a warm hearth, a soft rug, and an arm-chair that you can curl up and sleep in." OnInput: [ ;examine else if ( input.noun = 0 ) or ( input.noun = 2 ) then end endif var nono = getitemfromnoun input.noun if ( nono <> 0 ) then if ( currentplayer.stateitem <> 0 ) and ( item(nono).currentlocation = drawingroom.id ) then if ( nono = mantelpiece.id ) or ( nono = armchair.id ) or ( nono = rug.id ) then end endif var psti = currentplayer.stateitem if ( nono = mirror.id ) and ( psti = mantelpiece.id ) then end endif currentplayer.print |"You can't reach the " & item(nono).thename & " from the " & item(psti).thename & "."| end endif endif endif ] } Item redqueen "a red queen" { Nouns "red" "queen" Description "She's a fierce little chess piece." OnAction: [ end proc before_displayinitial if ( whitekitten.getvalue(state) <> 2 ) and ( blackkitten.getvalue(state) <> 2 ) then returnvalue = "There is a red queen here." cancelevent else returnvalue = " " cancelevent endif end proc before_insert if ( input.noun2 = chessboard.nounid ) then returnvalue = "Alone on the chess board, the red queen is monarch of all she surveys." end endif end proc before_get if ( whitekitten.getvalue(state) = 2 ) then whitekitten.setvalue(state) = 1 endif if ( blackkitten.getvalue(state) = 2 ) then blackkitten.setvalue(state) = 1 endif end proc after_get this.movedfromoriginallocation = false end proc after_drop this.movedfromoriginallocation = false end ] } Item chessboard "a chess board" { StartsIn drawingroom Size 2 has supporter Nouns "chess" "board" "checker" "chequer" "chessboard" Initial "An abandoned chess board lies on the floor." Description "It's left here from the game you were playing just now, but the pieces are all missing - the kittens will insist on playing with them." } Item hearth "the hearth" { StartsIn drawingroom has scenery Nouns "hearth" "fire" "place" "fireplace" Description "Looking at the hearth, you wonder if they have a hearth in the looking-glass house. You can never tell by looking, unless your fire smokes, and then smoke comes up in the looking-glass room too - but that may be only pretence, just to make it look as if they had a fire." } Item rug "rug" { Nouns "hearthrug" "hearth-rug" "rug" "indian" "arabian" "beautiful" "soft" StartsIn drawingroom Size 2 StaticMessage "The rug is much too large and heavy for you to carry." has invisible static supporter stand sit lay Description "It's a beautiful rug, made in some far off country, perhaps India or Araby, wherever those might be." OnAction: [ ;push,pull currentplayer.print "But a hearth-rug is meant to be next to the hearth!" end endif ;look #under if ( currentplayer.stateitem = this.id ) then currentplayer.print "You try to lift up a corner of the rug, but fail. After a while, you realise that this is because you are on top of it. How curious the world is!" end else if ( this.getuserboolean(foundqueen) = false ) then currentplayer.print "You lift up a corner of the rug and, peering underneath, discover the red queen from the chess set.
(Taken)" redqueen.currentlocation = currentplayer.containerlocation end endif endif endif endif ] } Item armchair "arm-chair" { StartsIn drawingroom Size 2 has static invisible supporter stand sit lay Nouns "arm" "chair" "armchair" "arm-chair" Description "It's a huge arm-chair, the perfect place for a kitten or a little girl to curl up in and doze." OnAction: [ ;push,pull if ( currentplayer.stateitem <> 0 ) then currentplayer.print |"You'll have to get off the " & item(currentplayer.stateitem).thename & " first."| end endif if ( whitekitten.currentlocation = currentplayer.containerlocation ) or ( blackkitten.currentlocation = currentplayer.containerlocation ) then currentplayer.print "Not with a kitten in your arms!" end endif var kitway = 0 if ( whitekitten.getvalue(state) = 1 ) then kitway = whitekitten.id endif if ( blackkitten.getvalue(state) = 1 ) then kitway = blackkitten.id endif if ( kitway <> 0 ) then currentplayer.print |"You are about to start moving the chair when you notice that the " & item(kitway).thename & " is right in the way. It's a good thing you spotted it, or you would have squashed flat the poor little thing."| end endif if ( this.getuserboolean(byhearth) = true ) then currentplayer.print "You push the arm-chair away from the hearth." this.removeuserboolean(byhearth) end else currentplayer.print "You push the arm-chair over to the hearth." this.adduserboolean(byhearth) end endif endif ;examine var oput = "It's a huge arm-chair, the perfect place for a kitten or a little girl to curl up in and doze. It has been pushed over to the " if ( this.getuserboolean(byhearth) = true ) then oput = |oput & "fireplace."| else oput = |oput & "window."| endif currentplayer.print oput end endif ] } Item mantelpiece "mantelpiece" { StartsIn drawingroom has invisible supporter stand Size 2 Nouns "mantel" "mantelpiece" Description "It's higher off the ground than your head, but it looks wide enough and sturdy enough to support you." OnAction: [ ;climb,stand if ( currentplayer.stateitem <> armchair.id ) then currentplayer.print "The mantelpiece is much too high to climb up onto." end else if ( armchair.getuserboolean(byhearth) = false ) then currentplayer.print "You can't reach the mantelpiece from here." end endif if ( currentplayer.itemscarried > 0 ) then currentplayer.print "Your hands are too full." end endif endif endif ;put if ( currentplayer.stateitem <> armchair.id ) and ( currentplayer.stateitem <> mantelpiece.id ) then currentplayer.print "The mantelpiece is so high that you can't reach." end endif endif ] } Item mirror "the looking-glass" { StartsIn drawingroom has static invisible Nouns "mirror" "looking" "glass" "looking-glass" OnAction: [ ;examine if ( currentplayer.stateitem = mantelpiece.id ) then currentplayer.print "Strangely, the glass is beginning to melt away, just like a bright silvery mist." end endif if ( currentplayer.stateitem = armchair.id ) then currentplayer.print "In the looking-glass you can see the drawing-room of the looking-glass house. What you can see is very much the same as this drawing-room, only all reversed, left for right. But you are sure that out of the corners of the glass, where you can't see, the looking-glass world is quite different from yours." end endif currentplayer.print "In the looking-glass you can see the ceiling of the drawing-room of the looking-glass house. It looks much the same as the ceiling of your drawing-room." end endif ;throw currentplayer.print "You don't want seven years' bad luck, do you?" end endif if ( currentplayer.stateitem <> mantelpiece.id ) then currentplayer.print "You can't reach the looking-glass from where you're standing." end endif ;touch,pull,push currentplayer.print "Your hand goes right through the silvery mist!" end endif ;go,get #in currentplayer.print "Your hand goes right through the silvery mist, and in another moment the rest of you follows, and you are through the glass..." call StandardLib.Won end endif endif ] } Item worsted "a ball of worsted" StartsIn drawingroom Initial "Worsted" Nouns "ball" "of" "worsted" "fine" "blue" "wool" OnAction: [ ;examine if ( this.getuserboolean(rolledup) = false ) then currentplayer.print "It's in a terrible tangle. All that time you spent rolling it up, and now look at it!" end else currentplayer.print "It's a ball of fine blue wool, all rolled up in preparation for some embroidery." end endif endif ;untangle if ( this.getuserboolean(rolledup) = false ) then currentplayer.print "You're as quick as can be at rolling up balls of wool, though you say so yourself! Soon it's neat and tidy again." this.adduserboolean(rolledup) end else currentplayer.print "The worsted is already neatly rolled up." end endif endif end proc before_get if ( whitekitten.getvalue(state) = 3 ) then whitekitten.setvalue(state) = 1 endif if ( blackkitten.getvalue(state) = 3 ) then blackkitten.setvalue(state) = 1 endif end proc before_displayinitial if ( whitekitten.getvalue(state) <> 3 ) and ( blackkitten.getvalue(state) <> 3 ) then returnvalue = "A discarded ball of worsted lies on the floor here." cancelevent else returnvalue = " " cancelevent endif end proc after_get this.movedfromoriginallocation = false end proc after_drop this.movedfromoriginallocation = false end proc initialise this.adduserboolean(rolledup) end ] } ! Kitten class for creating kittens Item kitten "Kitten Class" { OnAction: [ ;examine var otkit = this.getvalue(otherkitten) currentplayer.print |"What a beautiful kitten the " & this.thename & " is. Why it's quite definitely your favourite of the pair, and much prettier than that naughty " & item(otkit).thename & "."| end endif ;ask,answer,order currentplayer.print |"The " & this.thename & " twitches its whiskers and looks at you with such a clever expression that you are certain it understands every word you are saying."| end endif ;kiss currentplayer.print |"You give the " & this.thename & " a little kiss on its nose, and it looks sweetly and demurely at you."| end endif ;attack currentplayer.print "You would never do such a beastly thing to such a defenceless little animal!" end endif ;show var shitem = 0 if ( input.noun > 0 ) and ( input.noun <> this.nounid ) then shitem = getitemfromnoun input.noun else if ( input.noun2 > 0 ) and ( input.noun2 <> this.nounid ) then shitem = getitemfromnoun input.noun2 endif endif if ( shitem > 0 ) then currentplayer.print |"The " & this.thename & " bats a paw at the " & item(shitem).thename & "."| end endif endif ;give,throw var givit = 0 if ( input.noun > 0 ) then givit = getitemfromnoun input.noun item(givit).currentlocation = drawingroom.id item(givit).movedfromoriginallocation = false if ( givit <> worsted.id ) and ( givit <> redqueen.id ) then currentplayer.print |"You toss the " & item(givit).thename & " onto the floor, but the " & this.thename & " just examines it with a quizzical expression."| end endif this.currentlocation = drawingroom.id this.movedfromoriginallocation = false currentplayer.print |"You toss the " & item(givit).thename & " onto the floor and the " & this.thename & " scampers after it."| if ( givit = worsted.id ) then currentplayer.print |"The " & this.thename & " quickly turns the neat ball into a tangle."| worsted.removeuserboolean(rolledup) this.setvalue(state) = 3 end else this.setvalue(state) = 2 end endif endif endif end proc initialise if ( this.id = blackkitten.id ) then this.setvalue(otherkitten) = whitekitten.id else this.setvalue(otherkitten) = blackkitten.id endif this.setvalue(state) = 1 end proc before_displayinitial if ( this.getvalue(state) = 2 ) then returnvalue = |"A " & this.thename & " is playing with the red queen."| cancelevent end endif if ( this.getvalue(state) = 3 ) then returnvalue = |"A " & this.thename & " is playing with a ball of worsted."| cancelevent end endif if ( this.getvalue(state) = 1 ) then var otkit = this.getvalue(otherkitten) if ( item(otkit).getvalue(state) = 1 ) then ' Make sure we didn't already display this if ( whitekitten.getuserboolean(displayedtwo) = false ) then whitekitten.adduserboolean(displayedtwo) returnvalue = "Two kittens, one white and one black, are playing together by the arm-chair." cancelevent else returnvalue = " " cancelevent endif else returnvalue = |"A " & this.thename & " is playing by the arm-chair."| cancelevent endif endif end proc before_get var otkit = this.getvalue(otherkitten) if ( item(otkit).currentlocation = currentplayer.containerlocation ) then returnvalue = "You can't hold two kittens at once!" cancelevent end else returnvalue = |"You pick up the " & this.thename & ". What a beautiful creature it is!"| this.setvalue(state) = 4 this.movedfromoriginallocation = false end endif end proc before_drop this.setvalue(state) = 1 returnvalue = |"The " & this.thename & " squirms out of your arms and scampers away."| this.movedfromoriginallocation = false end proc after_insert this.setvalue(state) = 1 this.currentlocation = drawingroom.id var cntnr = getitemfromnoun input.noun2 currentplayer.print |"The " & this.thename & " jumps off the " & item(cntnr).thename & ", landing lightly on the floor before scampering away."| end proc each_turn whitekitten.removeuserboolean(displayedtwo) if ( this.currentlocation = currentplayer.containerlocation ) then ' This offers 3/8 chance of no action var rndec = |8 * random + 1 + makeinteger| var oput = |"The " & this.thename| if ( rndec = 1 ) then oput = |oput & " mews plaintively."| endif if ( rndec = 2 ) then oput = |oput & " purrs quietly to itself."| endif if ( rndec = 3 ) then oput = |oput & " purrs contendly to itself."| endif if ( rndec = 4 ) then oput = |oput & " rubs its ears against you."| endif if ( rndec = 5 ) then oput = |oput & " squirms out of your arms and scampers away."| this.setvalue(state) = 1 this.currentlocation = drawingroom.id this.movedfromoriginallocation = false endif if ( rndec < 6 ) then currentplayer.print oput endif endif end ] } Item whitekitten "a white kitten" extends kitten { StartsIn drawingroom Nouns "white" "kitten" "kittens" "kitty" "cat" Initial "white" } Item blackkitten "a black kitten" extends kitten { StartsIn drawingroom Nouns "black" "kitten" "kittens" "kitty" "cat" Initial "black" } Item chesspieces "chess pieces" { StartsIn drawingroom Nouns "rook" "bishop" "knight" "king" "pawn" has scenery OnAction: [ currentplayer.print "Alas, that chess piece seems to be missing. Those naughty kittens!" ] } Item window "the window" { StartsIn drawingroom has scenery Nouns "window" "pane" Description "Outside the window it's snowing gently, and you're glad to be in here in the warmth." OnAction: [ ;open currentplayer.print "You wouldn't want to catch a chill, would you? Better leave the window shut." end endif ;search currentplayer.print this.defaultexamine end endif ] }