Advertisement
Guest User

Untitled

a guest
Jun 25th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.05 KB | None | 0 0
  1. Red [
  2. Title: "Hunt the Wumpus"
  3. ;Date: 25-Jun-2016
  4. Author: "Gregg Irwin"
  5. Version: 1.0.2
  6. Comment: {
  7. 2001 Notes:
  8. I found an old version, in C (by Eric Raymond), which was adapted from
  9. an even older version, in BASIC (by Magnus Olsson), that had been found
  10. in a SIMTEL archive. It's got lineage.
  11.  
  12. As of 22-Oct-2001, it appears to work, though I haven't traced the
  13. arrow path'ing logic yet nor made it smart. Arrows can go pretty much
  14. anywhere you tell them and, yes, you can shoot yourself as in the
  15. original.
  16.  
  17. I tweaked a few strings, but the instructions are almost unscathed.
  18.  
  19. Ahhh, it takes me back to my Dad's HP85 with the built-in 5 inch
  20. monochrome screen, tape drive, and thermal printer...
  21.  
  22. 2016 Notes: This was one of the very first programs I wrote in REBOL.
  23. I could update it, but we all have to start somewhere, and I think
  24. it has a certain charm. It is neither concise, nor idiomatic Redbol
  25. (a portmanteau of Red and Rebol), but making it so will be a good
  26. exercise for the reader, if they so choose. And if they don't, that's
  27. fine too, because you can write your Red code however you want.
  28.  
  29. And for the kids out there, my Dad's HP85 was a beast. He paid a LOT
  30. of money to get the extra 16K RAM module. 32K RAM total. Believe it.
  31. Only 36 years ago.
  32. }
  33. history: {
  34. 1.0.0 22-Mar-2001 {Initial Release}
  35. 1.0.1 11-Apr-2002 {Fixed bug where the Wumpus might eat you after you shot him.}
  36. 1.0.2 25-Jun-2016 {Ported to Red 0.6.1}
  37. }
  38. ]
  39.  
  40. ; Setup
  41. ; initialize arrow count
  42. ; randomly place bats, pits, wumpus, and player
  43. ; make a working copy of the starting locations.
  44. ; Check-for-hazards
  45. ; Each Turn
  46. ; ask player to move or shoot
  47. ; if shoot
  48. ; check for hit on self and wumpus
  49. ; move wumpus
  50. ; if move
  51. ; check-for-hazards
  52. ; until player dead, wumpus dead, or out of arrows
  53.  
  54. arrow-count: 0
  55.  
  56. ; indexes into location block
  57. player: 1
  58. wumpus: 2
  59. pit-1: 3
  60. pit-2: 4
  61. bats-1: 5
  62. bats-2: 6
  63.  
  64.  
  65. start-loc: []
  66. loc: []
  67. winner: none
  68. finished: false
  69.  
  70. ; The cave is a dodecahedron. Each block is a room containing the
  71. ; number for the rooms it is connected to.
  72. cave: [
  73. [2 5 8] [1 3 10] [2 4 12] [3 5 14] [1 4 6]
  74. [5 7 15] [6 8 17] [1 7 9] [8 10 18] [2 9 11]
  75. [10 12 19] [3 11 13] [12 14 20] [4 13 15] [6 14 16]
  76. [15 17 20] [7 16 18] [9 17 19] [11 18 20] [13 16 19]
  77. ]
  78.  
  79. random-room: does [random 20]
  80. random-direction: does [random 3]
  81.  
  82. get-num: func [prompt][
  83. if error? try [return to integer! ask prompt] [
  84. return 0
  85. ]
  86. ]
  87.  
  88. print-instructions: does [
  89. print {
  90. WELCOME TO 'HUNT THE WUMPUS' (love that all caps retro look)
  91.  
  92. THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM HAS 3 TUNNELS LEADING TO
  93. OTHER ROOMS.
  94.  
  95. HAZARDS:
  96. BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM. IF YOU GO THERE,
  97. YOU FALL INTO THE PIT (YOU LOSE!)
  98. SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU GO THERE, A BAT GRABS
  99. YOU AND TAKES YOU TO SOME OTHER ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)
  100.  
  101. WUMPUS: THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER FEET AND IS TOO
  102. BIG FOR A BAT TO LIFT). USUALLY HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOU
  103. SHOOTING AN ARROW OR YOU ENTERING HIS ROOM. IF THE WUMPUS WAKES HE MOVES
  104. ONE ROOM (75% chance) OR STAYS STILL (25% chance). AFTER THAT, IF HE IS
  105. WHERE YOU ARE, HE EATS YOU UP AND YOU LOSE!
  106.  
  107. YOU: EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW.
  108. MOVING: YOU CAN MOVE ONE ROOM (THROUGH ONE TUNNEL).
  109. ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT.
  110. EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING THE COMPUTER
  111. THE ROOMS YOU WANT THE ARROW TO GO TO. IF THE ARROW CAN'T GO THAT WAY
  112. (I.E. NO TUNNEL) IT MOVES AT RANDOM TO THE NEXT ROOM.
  113. * IF THE ARROW HITS THE WUMPUS, YOU WIN.
  114. * IF THE ARROW HITS YOU, YOU LOSE.
  115.  
  116. WARNINGS: WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD, THE COMPUTER SAYS:
  117. WUMPUS: 'YOU SMELL A WUMPUS'
  118. BAT : 'YOU HEAR BATS'
  119. PIT : 'YOU FEEL A DRAFT'
  120. }
  121.  
  122. ask "Press <Enter> when you're ready to start the game"
  123.  
  124. ]
  125.  
  126. check-for-hazards: func [/local i][
  127. print ""
  128. print ["You are in room " loc/:player]
  129. print ["Tunnels lead to " pick cave loc/:player]
  130. ; Look at each of the 3 rooms around the player to see if the contain
  131. ; the wumpus, a pit, or bats.
  132. repeat i 3 [
  133. room: pick pick cave loc/:player i
  134. if (room = loc/:wumpus) [print " You smell a wumpus!"]
  135. if any [(room = loc/:pit-1) (room = loc/:pit-2)] [
  136. print " You feel a draft!"
  137. ]
  138. if any [(room = loc/:bats-1) (room = loc/:bats-2)] [
  139. print " You hear bats!"
  140. ]
  141. ]
  142. print ""
  143. ]
  144.  
  145. move-or-shoot?: func [/local cmd][
  146. cmd: ask "Shoot or move (S/M)? "
  147. ; The default case handles bad inputs and prompts the user again.
  148. switch/default cmd [
  149. "S" ['shoot]
  150. "M" ['move]
  151. ][move-or-shoot?]
  152. ]
  153.  
  154. move-arrow: func [room path /local i rnd-rm][
  155. ;print reduce ["move arrow" room tab path] ; FOR DEBUG USE
  156. if not tail? path [
  157. ; If they gave us a bogus target room, pick a random one.
  158. either find cave/:room first path [
  159. ; Next room in path is valid
  160. check-for-arrow-hit first path
  161. if finished [exit]
  162. ; Recursive call
  163. move-arrow first path next path
  164. ][
  165. ; Pick a random direction
  166. i: random-direction
  167. check-for-arrow-hit rnd-rm: cave/:room/:i
  168. if finished [exit]
  169. ; Recursive call
  170. move-arrow rnd-rm next path
  171. ]
  172. ]
  173. ]
  174.  
  175. shoot: func [/local path][
  176. path: load ask "Enter 1 to 5 room numbers for the arrow's path: "
  177. path: compose [(path)] ; ensure it's a block, in case they entered only 1 number
  178. move-arrow loc/:player path
  179. if not finished [
  180. print "Your arrow missed"
  181. move-wumpus
  182. ]
  183. ; See if the Wumpus moved onto the player
  184. if finished [exit]
  185.  
  186. arrow-count: arrow-count - 1
  187. if (arrow-count <= 0) [
  188. print reduce [newline "You ran out of arrows..."]
  189. winner: 'wumpus
  190. finished: true
  191. exit
  192. ]
  193.  
  194. check-for-hazards
  195. ]
  196.  
  197. check-for-arrow-hit: func [room][
  198. if (room = loc/:wumpus) [
  199. print reduce [newline "You got the Wumpus!"]
  200. winner: 'player
  201. finished: true
  202. exit
  203. ]
  204. if (room = loc/:player) [
  205. print reduce [newline "You shot yourself!"]
  206. winner: 'arrow
  207. finished: true
  208. exit
  209. ]
  210. ]
  211.  
  212. ; 75% chance that it will move
  213. wumpus-moves?: does [either (random 4) < 4 [true][false]]
  214.  
  215. move-wumpus: does [
  216. if wumpus-moves? [loc/2: pick (pick cave loc/:wumpus) random-direction]
  217. if (loc/:wumpus = loc/:player) [
  218. winner: 'wumpus
  219. finished: true
  220. ]
  221. ]
  222.  
  223. move-player: func [/bat-move new-loc /local new-player-loc][
  224. either bat-move [
  225. loc/1: new-loc
  226. ][
  227. new-player-loc: get-num "To which room? "
  228. ; Call recursively, then bail, if bad input
  229. if any [(new-player-loc < 1) (new-player-loc > 20)] [
  230. move-player
  231. exit
  232. ]
  233. ; Call recursively, then bail, if illegal move
  234. if not find pick cave loc/:player new-player-loc [
  235. print "You can't move there, unless you plan to dig a new tunnel."
  236. move-player
  237. exit
  238. ]
  239. ; It was a legal move, so update the player's location.
  240. change at loc player new-player-loc
  241. ]
  242.  
  243. if (loc/:player = loc/:wumpus) [
  244. print "Yikes! You bumped the Wumpus!"
  245. move-wumpus
  246. ; See if the Wumpus moved onto the player
  247. if finished [exit]
  248. ]
  249. if any [(loc/:player = loc/:pit-1) (loc/:player = loc/:pit-2) ] [
  250. print reduce [newline "Aaiiiiieeeee....(you fell in a pit)"]
  251. winner: 'pit
  252. finished: true
  253. exit
  254. ]
  255. if any [(loc/:player = loc/:bats-1) (loc/:player = loc/:bats-2) ] [
  256. print "ZAP! Super-Bat snatch! Elsewhereville for you!"
  257. move-player/bat-move random-room
  258. exit
  259. ]
  260.  
  261. check-for-hazards
  262.  
  263. ]
  264.  
  265. ; This is ugly, but it works for now and avoids setup collisions.
  266. ; Don't really need items for this, but I'd like to improve it and then I might.
  267. init-locations: func [/local items avail-rooms result offset][
  268. random/seed now/time/precise
  269. items: [player wumpus pit-1 pit-2 bats-1 bats-2]
  270. avail-rooms: copy [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
  271. result: make block! length? items
  272. repeat i length? items [
  273. ; Too dense for one line?
  274. ;append result pick avail-rooms offset: random length? avail-rooms
  275. offset: random/secure length? avail-rooms
  276. append result pick avail-rooms offset
  277. remove at avail-rooms offset
  278. ]
  279. return result
  280. ]
  281.  
  282. setup: func [/same-as-last][
  283. ; Initialize arrow count.
  284. arrow-count: 5
  285. ; If we haven't setup before, or they want the same setup,
  286. ; there's no need to initialize.
  287. if any [(not same-as-last) (start-loc = none)] [
  288. ; Randomly place bats, pits, wumpus, and player
  289. start-loc: init-locations
  290. ]
  291. ; Make a working copy of the starting locations.
  292. loc: copy start-loc
  293. ]
  294.  
  295. do-game: func [/same-as-last][
  296. either same-as-last [
  297. setup/same-as-last
  298. ][
  299. setup
  300. ]
  301. check-for-hazards
  302. while [not finished][
  303. either move-or-shoot? = 'shoot [shoot][move-player]
  304. ]
  305. print switch winner [
  306. wumpus ["<SNARF> The Wumpus got you!!!"]
  307. player ["<BLARP> The Wumpus will get you next time!"]
  308. pit ["<SPLAT> Better luck next time"]
  309. arrow ["<GLURG> You really should be more careful"]
  310. ]
  311. print ""
  312. ]
  313.  
  314. start: does [
  315. if (ask "Would you like instructions (Y/N)? ") = "Y" [
  316. print-instructions
  317. ]
  318. play: "Y"
  319. same-setup: "N"
  320. while [play = "Y"][
  321. either same-setup = "N" [
  322. do-game
  323. ][
  324. do-game/same-as-last
  325. ]
  326. play: ask "Play again (Y/N)? "
  327. if play = "Y" [
  328. winner: none
  329. finished: false
  330. same-setup: ask "Same setup (Y/N)? "
  331. ]
  332. ]
  333. halt
  334. ]
  335.  
  336. start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement