123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- (defmodule game
- (export all))
- ;; Creates:
- ;; make-exit
- ;; exit-direction
- ;; exit-object
- ;; exit-destination
- ;; set-exit
- ;; set-exit-direction
- ;; set-exit-object
- ;; set-exit-destination
- ;; match-exit
- ;; ...
- (defrecord exit
- direction
- object
- destination)
- (defrecord place
- name
- description
- exits)
- (defrecord object
- name
- location)
- (defrecord goal
- name
- achieved?)
- (defrecord state
- objects
- places
- player-location
- goals)
- (set objects
- (list (make-object name 'whiskey-bottle location 'living-room)
- (make-object name 'bucket location 'living-room)
- (make-object name 'frog location 'garden)
- (make-object name 'chain location 'garden)))
- (set living-room
- (make-place
- name 'living-room
- description (++ "You are in the living-room of a wizard's house. "
- "There is a wizard snoring loudly on the couch.")
- exits (list
- (make-exit
- direction "west"
- object "door"
- destination 'garden)
- (make-exit
- direction "upstairs"
- object "stairway"
- destination 'attic))))
- (set garden
- (make-place
- name 'garden
- description (++ "You are in a beautiful garden. "
- "There is a well in front of you.")
- exits (list
- (make-exit
- direction "east"
- object "door"
- destination 'living-room))))
- (set attic
- (make-place
- name 'attic
- description (++ "You are in the attic of the wizard's house. "
- "There is a giant welding torch in the corner.")
- exits (list
- (make-exit
- direction "downstairs"
- object "stairway"
- destination 'living-room))))
- (set netherworld
- (make-place
- name 'netherworld
- description (++ "Everything is misty and vague. "
- "You seem to be in the netherworld.\n"
- "There are no exits.\n"
- "You could be here for a long, long time ...")
- exits '()))
- (set goals
- (list (make-goal name 'weld-chain achieved? 'false)
- (make-goal name 'dunk-bucket achieved? 'false)
- (make-goal name 'splash-wizard achieved? 'false)))
- (set state (make-state
- objects objects
- places (list living-room garden attic netherworld)
- player-location 'living-room
- goals goals))
- (defun here?
- ((loc (match-place name place-name)) (when (== loc place-name))
- 'true)
- ((_ _)
- 'false))
- (defun get-here
- (((match-state
- player-location player-loc
- places locs))
- (car (lists:filter
- (lambda (loc)
- (here? player-loc loc))
- locs))))
- (defun describe-location (game-state)
- (++ (place-description (get-here game-state)) "\n"))
- (defun describe-exit
- (((match-exit object obj direction dir))
- (++ "There is a " obj " going " dir " from here.")))
- (defun describe-exits (game-state)
- (string:join
- (lists:map
- #'describe-exit/1
- (place-exits (get-here game-state)))
- " "))
- (defun item-there?
- ((loc (match-object location obj-loc)) (when (== loc obj-loc))
- 'true)
- ((_ _)
- 'false))
- (defun whats-here?
- (((match-state player-location player-loc objects objs))
- (lists:filter
- (lambda (obj)
- (item-there? player-loc obj))
- objs)))
- (defun display-scene (game-state)
- (io:format
- "~n~s~s~s"
- (list (describe-location game-state)
- (describe-items game-state)
- (describe-exits game-state))))
- (defun display-exits (game-state)
- (io:format
- "~n~s"
- (list (describe-exits game-state))))
- (defun get-valid-moves (exits)
- (lists:map
- (lambda (x)
- (list_to_atom (exit-direction x)))
- exits))
- (defun match-directions
- ((player-dir (match-exit direction dir))
- (if (== dir (atom_to_list player-dir))
- 'true
- 'false)))
- (defun get-new-location (player-dir exits)
- (exit-destination
- (car
- (lists:filter
- (lambda (exit) (match-directions player-dir exit))
- exits))))
- (defun good-move (game-state)
- (display-scene game-state)
- game-state)
- (defun bad-move (game-state)
- (io:format "~nYou can't go that way.~n")
- game-state)
- (defun walk-direction (direction game-state)
- (let ((exits (place-exits (get-here game-state))))
- (case (lists:member direction (get-valid-moves exits))
- ('true (good-move
- (set-state-player-location
- game-state
- (get-new-location direction exits))))
- ('false (bad-move game-state)))))
- (defmacro defspel body `(defmacro ,@body))
- (defspel walk (direction game-state)
- `(walk-direction ',direction ,game-state))
- (defun good-pick (item-name)
- (io:format "~nYou are now carrying the ~s.~n"
- (list (atom_to_list item-name))))
- (defun check-item
- ((item-name (= (match-object name obj-name) obj)) (when (== item-name obj-name))
- (good-pick item-name)
- (set-object-location obj 'player))
- ((_ obj) obj))
- (defun update-items (item-name game-state)
- (lists:map
- (lambda (obj) (check-item item-name obj))
- (state-objects game-state)))
- (defun get-item-names (game-state)
- (lists:map
- (lambda (x) (object-name x))
- (whats-here? game-state)))
- (defun bad-pick ()
- (io:format "~nThat item is not here.~n"))
- (defun pickup-item
- ((item-name (= (match-state player-location player-loc objects objs) game-state))
- (case (lists:member item-name (get-item-names game-state))
- ('true
- (set-state-objects
- game-state (update-items item-name game-state)))
- ('false
- (bad-pick)
- game-state))))
- (defspel pickup (item-name game-state)
- `(pickup-item ',item-name ,game-state))
- (defun inv-obj
- (((match-state objects objs))
- (lists:filter
- (match-lambda
- (((match-object location 'player)) 'true)
- ((_) 'false))
- objs)))
- (defun inv-name (game-state)
- (lists:map
- (lambda (x) (object-name x))
- (inv-obj game-state)))
- (defun get-inv-str (game-state)
- (string:join
- (lists:map
- (lambda (x) (++ " - " (atom_to_list x) "\n"))
- (inv-name game-state))
- ""))
- (defun display-inv (game-state)
- (let ((inv-str (get-inv-str game-state)))
- (case inv-str
- ('() (io:format "~nYou are not carrying anything.~n"))
- (_ (io:format "~nYou are carrying the following:~n~s"
- (list inv-str))))))
- (defun inv? (item-name game-state)
- (lists:member item-name (inv-name game-state)))
- (defun goal-matches?
- ((goal-name (= (match-goal name name) goal)) (when (== goal-name name))
- `#(true ,goal))
- ((_ _)
- 'false))
- (defun filter-goals (goal-name game-state)
- (lists:filtermap
- (lambda (x) (goal-matches? goal-name x))
- (state-goals state)))
- (defun extract-goal
- (('())
- 'undefined)
- ((`(,goal))
- goal))
- (defun get-goal (goal-name game-state)
- (extract-goal (filter-goals goal-name game-state)))
- (defun goal-met? (goal-name game-state)
- (let ((goal (get-goal goal-name game-state)))
- (if (== goal 'undefined)
- goal
- (goal-achieved? goal))))
- (defun good-goal (item-name)
- (io:format "~nYou have achieved the '~s' goal!~n"
- (list (atom_to_list item-name))))
- (defun check-goal
- ((goal-name (= (match-goal name g-name) goal)) (when (== goal-name g-name))
- (good-goal goal-name)
- (set-goal-achieved? goal 'true))
- ((_ goal) goal))
- (defun update-goals (goal-name game-state)
- (set-state-goals
- game-state
- (lists:map
- (lambda (goal) (check-goal goal-name goal))
- (state-goals game-state))))
- (defun weld-ready? (game-state)
- (andalso (inv? 'bucket game-state)
- (inv? 'chain game-state)
- (== (state-player-location game-state) 'attic)))
- (defun weld-not-ready ()
- (io:format "~nYou seem to be missing a key condition for welding ...~n"))
- (defun cant-weld ()
- (io:format "~nYou can't weld like that ...~n"))
- (defun good-weld (game-state)
- (io:format "~nThe chain is now securely welded to the bucket.~n")
- game-state)
- (defun already-welded ()
- (io:format "~nYou have already welded the bucket and chain!~n"))
- (defun weld-them
- (('chain 'bucket game-state)
- (let ((ready? (weld-ready? game-state)))
- (cond ((goal-met? 'weld-chain game-state)
- (already-welded)
- game-state)
- ((not ready?)
- (weld-not-ready)
- game-state)
- (ready?
- (good-weld
- (update-goals 'weld-chain game-state))))))
- ((_ _ game-state)
- (cant-weld)
- game-state))
- (defun dunk-ready? (game-state)
- (andalso (inv? 'bucket game-state)
- (goal-met? 'weld-chain game-state)
- (== (state-player-location game-state) 'garden)))
- (defun dunk-not-ready ()
- (io:format "~nYou seem to be missing a key condition for dunking ...~n"))
- (defun cant-dunk ()
- (io:format "~nYou can't dunk like that ...~n"))
- (defun good-dunk (game-state)
- (io:format "~nThe bucket is now full of water.~n")
- game-state)
- (defun already-dunked ()
- (io:format "~nYou filled the bucket. Again.~n"))
- (defun dunk-it
- (('bucket 'well game-state)
- (let ((ready? (dunk-ready? game-state)))
- (cond ((goal-met? 'dunk-bucket game-state)
- (already-dunked)
- game-state)
- ((not ready?)
- (dunk-not-ready)
- game-state)
- (ready?
- (good-dunk
- (update-goals 'dunk-bucket game-state))))))
- ((_ _ game-state)
- (cant-dunk)
- game-state))
|