A code base (no slides) presentation on lisp flavored erlang for http://www.meetup.com/Arch-Lisp/

game.lfe 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. (defmodule game
  2. (export all))
  3. ;; Creates:
  4. ;; make-exit
  5. ;; exit-direction
  6. ;; exit-object
  7. ;; exit-destination
  8. ;; set-exit
  9. ;; set-exit-direction
  10. ;; set-exit-object
  11. ;; set-exit-destination
  12. ;; match-exit
  13. ;; ...
  14. (defrecord exit
  15. direction
  16. object
  17. destination)
  18. (defrecord place
  19. name
  20. description
  21. exits)
  22. (defrecord object
  23. name
  24. location)
  25. (defrecord goal
  26. name
  27. achieved?)
  28. (defrecord state
  29. objects
  30. places
  31. player-location
  32. goals)
  33. (set objects
  34. (list (make-object name 'whiskey-bottle location 'living-room)
  35. (make-object name 'bucket location 'living-room)
  36. (make-object name 'frog location 'garden)
  37. (make-object name 'chain location 'garden)))
  38. (set living-room
  39. (make-place
  40. name 'living-room
  41. description (++ "You are in the living-room of a wizard's house. "
  42. "There is a wizard snoring loudly on the couch.")
  43. exits (list
  44. (make-exit
  45. direction "west"
  46. object "door"
  47. destination 'garden)
  48. (make-exit
  49. direction "upstairs"
  50. object "stairway"
  51. destination 'attic))))
  52. (set garden
  53. (make-place
  54. name 'garden
  55. description (++ "You are in a beautiful garden. "
  56. "There is a well in front of you.")
  57. exits (list
  58. (make-exit
  59. direction "east"
  60. object "door"
  61. destination 'living-room))))
  62. (set attic
  63. (make-place
  64. name 'attic
  65. description (++ "You are in the attic of the wizard's house. "
  66. "There is a giant welding torch in the corner.")
  67. exits (list
  68. (make-exit
  69. direction "downstairs"
  70. object "stairway"
  71. destination 'living-room))))
  72. (set netherworld
  73. (make-place
  74. name 'netherworld
  75. description (++ "Everything is misty and vague. "
  76. "You seem to be in the netherworld.\n"
  77. "There are no exits.\n"
  78. "You could be here for a long, long time ...")
  79. exits '()))
  80. (set goals
  81. (list (make-goal name 'weld-chain achieved? 'false)
  82. (make-goal name 'dunk-bucket achieved? 'false)
  83. (make-goal name 'splash-wizard achieved? 'false)))
  84. (set state (make-state
  85. objects objects
  86. places (list living-room garden attic netherworld)
  87. player-location 'living-room
  88. goals goals))
  89. (defun here?
  90. ((loc (match-place name place-name)) (when (== loc place-name))
  91. 'true)
  92. ((_ _)
  93. 'false))
  94. (defun get-here
  95. (((match-state
  96. player-location player-loc
  97. places locs))
  98. (car (lists:filter
  99. (lambda (loc)
  100. (here? player-loc loc))
  101. locs))))
  102. (defun describe-location (game-state)
  103. (++ (place-description (get-here game-state)) "\n"))
  104. (defun describe-exit
  105. (((match-exit object obj direction dir))
  106. (++ "There is a " obj " going " dir " from here.")))
  107. (defun describe-exits (game-state)
  108. (string:join
  109. (lists:map
  110. #'describe-exit/1
  111. (place-exits (get-here game-state)))
  112. " "))
  113. (defun item-there?
  114. ((loc (match-object location obj-loc)) (when (== loc obj-loc))
  115. 'true)
  116. ((_ _)
  117. 'false))
  118. (defun whats-here?
  119. (((match-state player-location player-loc objects objs))
  120. (lists:filter
  121. (lambda (obj)
  122. (item-there? player-loc obj))
  123. objs)))
  124. (defun display-scene (game-state)
  125. (io:format
  126. "~n~s~s~s"
  127. (list (describe-location game-state)
  128. (describe-items game-state)
  129. (describe-exits game-state))))
  130. (defun display-exits (game-state)
  131. (io:format
  132. "~n~s"
  133. (list (describe-exits game-state))))
  134. (defun get-valid-moves (exits)
  135. (lists:map
  136. (lambda (x)
  137. (list_to_atom (exit-direction x)))
  138. exits))
  139. (defun match-directions
  140. ((player-dir (match-exit direction dir))
  141. (if (== dir (atom_to_list player-dir))
  142. 'true
  143. 'false)))
  144. (defun get-new-location (player-dir exits)
  145. (exit-destination
  146. (car
  147. (lists:filter
  148. (lambda (exit) (match-directions player-dir exit))
  149. exits))))
  150. (defun good-move (game-state)
  151. (display-scene game-state)
  152. game-state)
  153. (defun bad-move (game-state)
  154. (io:format "~nYou can't go that way.~n")
  155. game-state)
  156. (defun walk-direction (direction game-state)
  157. (let ((exits (place-exits (get-here game-state))))
  158. (case (lists:member direction (get-valid-moves exits))
  159. ('true (good-move
  160. (set-state-player-location
  161. game-state
  162. (get-new-location direction exits))))
  163. ('false (bad-move game-state)))))
  164. (defmacro defspel body `(defmacro ,@body))
  165. (defspel walk (direction game-state)
  166. `(walk-direction ',direction ,game-state))
  167. (defun good-pick (item-name)
  168. (io:format "~nYou are now carrying the ~s.~n"
  169. (list (atom_to_list item-name))))
  170. (defun check-item
  171. ((item-name (= (match-object name obj-name) obj)) (when (== item-name obj-name))
  172. (good-pick item-name)
  173. (set-object-location obj 'player))
  174. ((_ obj) obj))
  175. (defun update-items (item-name game-state)
  176. (lists:map
  177. (lambda (obj) (check-item item-name obj))
  178. (state-objects game-state)))
  179. (defun get-item-names (game-state)
  180. (lists:map
  181. (lambda (x) (object-name x))
  182. (whats-here? game-state)))
  183. (defun bad-pick ()
  184. (io:format "~nThat item is not here.~n"))
  185. (defun pickup-item
  186. ((item-name (= (match-state player-location player-loc objects objs) game-state))
  187. (case (lists:member item-name (get-item-names game-state))
  188. ('true
  189. (set-state-objects
  190. game-state (update-items item-name game-state)))
  191. ('false
  192. (bad-pick)
  193. game-state))))
  194. (defspel pickup (item-name game-state)
  195. `(pickup-item ',item-name ,game-state))
  196. (defun inv-obj
  197. (((match-state objects objs))
  198. (lists:filter
  199. (match-lambda
  200. (((match-object location 'player)) 'true)
  201. ((_) 'false))
  202. objs)))
  203. (defun inv-name (game-state)
  204. (lists:map
  205. (lambda (x) (object-name x))
  206. (inv-obj game-state)))
  207. (defun get-inv-str (game-state)
  208. (string:join
  209. (lists:map
  210. (lambda (x) (++ " - " (atom_to_list x) "\n"))
  211. (inv-name game-state))
  212. ""))
  213. (defun display-inv (game-state)
  214. (let ((inv-str (get-inv-str game-state)))
  215. (case inv-str
  216. ('() (io:format "~nYou are not carrying anything.~n"))
  217. (_ (io:format "~nYou are carrying the following:~n~s"
  218. (list inv-str))))))
  219. (defun inv? (item-name game-state)
  220. (lists:member item-name (inv-name game-state)))
  221. (defun goal-matches?
  222. ((goal-name (= (match-goal name name) goal)) (when (== goal-name name))
  223. `#(true ,goal))
  224. ((_ _)
  225. 'false))
  226. (defun filter-goals (goal-name game-state)
  227. (lists:filtermap
  228. (lambda (x) (goal-matches? goal-name x))
  229. (state-goals state)))
  230. (defun extract-goal
  231. (('())
  232. 'undefined)
  233. ((`(,goal))
  234. goal))
  235. (defun get-goal (goal-name game-state)
  236. (extract-goal (filter-goals goal-name game-state)))
  237. (defun goal-met? (goal-name game-state)
  238. (let ((goal (get-goal goal-name game-state)))
  239. (if (== goal 'undefined)
  240. goal
  241. (goal-achieved? goal))))
  242. (defun good-goal (item-name)
  243. (io:format "~nYou have achieved the '~s' goal!~n"
  244. (list (atom_to_list item-name))))
  245. (defun check-goal
  246. ((goal-name (= (match-goal name g-name) goal)) (when (== goal-name g-name))
  247. (good-goal goal-name)
  248. (set-goal-achieved? goal 'true))
  249. ((_ goal) goal))
  250. (defun update-goals (goal-name game-state)
  251. (set-state-goals
  252. game-state
  253. (lists:map
  254. (lambda (goal) (check-goal goal-name goal))
  255. (state-goals game-state))))
  256. (defun weld-ready? (game-state)
  257. (andalso (inv? 'bucket game-state)
  258. (inv? 'chain game-state)
  259. (== (state-player-location game-state) 'attic)))
  260. (defun weld-not-ready ()
  261. (io:format "~nYou seem to be missing a key condition for welding ...~n"))
  262. (defun cant-weld ()
  263. (io:format "~nYou can't weld like that ...~n"))
  264. (defun good-weld (game-state)
  265. (io:format "~nThe chain is now securely welded to the bucket.~n")
  266. game-state)
  267. (defun already-welded ()
  268. (io:format "~nYou have already welded the bucket and chain!~n"))
  269. (defun weld-them
  270. (('chain 'bucket game-state)
  271. (let ((ready? (weld-ready? game-state)))
  272. (cond ((goal-met? 'weld-chain game-state)
  273. (already-welded)
  274. game-state)
  275. ((not ready?)
  276. (weld-not-ready)
  277. game-state)
  278. (ready?
  279. (good-weld
  280. (update-goals 'weld-chain game-state))))))
  281. ((_ _ game-state)
  282. (cant-weld)
  283. game-state))
  284. (defun dunk-ready? (game-state)
  285. (andalso (inv? 'bucket game-state)
  286. (goal-met? 'weld-chain game-state)
  287. (== (state-player-location game-state) 'garden)))
  288. (defun dunk-not-ready ()
  289. (io:format "~nYou seem to be missing a key condition for dunking ...~n"))
  290. (defun cant-dunk ()
  291. (io:format "~nYou can't dunk like that ...~n"))
  292. (defun good-dunk (game-state)
  293. (io:format "~nThe bucket is now full of water.~n")
  294. game-state)
  295. (defun already-dunked ()
  296. (io:format "~nYou filled the bucket. Again.~n"))
  297. (defun dunk-it
  298. (('bucket 'well game-state)
  299. (let ((ready? (dunk-ready? game-state)))
  300. (cond ((goal-met? 'dunk-bucket game-state)
  301. (already-dunked)
  302. game-state)
  303. ((not ready?)
  304. (dunk-not-ready)
  305. game-state)
  306. (ready?
  307. (good-dunk
  308. (update-goals 'dunk-bucket game-state))))))
  309. ((_ _ game-state)
  310. (cant-dunk)
  311. game-state))