los-torreros.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. #!/usr/bin/env python3
  2. license = '''
  3. Copyright 2013, 2014, 2015 Jason MacDuffie.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. '''
  15. author = '''
  16. Contact information:
  17. email: taknamay@gmail.com
  18. '''
  19. objective = '''
  20. You must walk around the castle fighting monsters to find Bellamor.
  21. Once you meet Bellamor, you must kill him to win the game.
  22. Hint: If you leave the room after battling Bellamor without
  23. defeating him, he will still be damaged!
  24. '''
  25. intro = '''
  26. *** Welcome to Los Torreros ***
  27. Copyright 2013, 2014, 2015 Jason MacDuffie.
  28. '''
  29. import random
  30. def read(prompt):
  31. try:
  32. return input(prompt)
  33. except EOFError:
  34. print("\n")
  35. print("Good bye! Please play another time.")
  36. end()
  37. def end():
  38. print("\nPress enter to close the program at any time... ")
  39. try:
  40. input()
  41. except EOFError:
  42. pass
  43. exit()
  44. # Define a method for fleeing combat.
  45. def flees_combat():
  46. global hp
  47. if (combat_state == 0):
  48. return True
  49. elif (combat_state == 1):
  50. escape_roll = random.randint(1, 6) + evasion_mod
  51. if (escape_roll <= 3):
  52. damage_in = random.randint(1, 4) + 1
  53. hp -= damage_in
  54. print("\nYou failed to escape! Your enemy strikes, dealing " + str(damage_in) + " damage to you.")
  55. return False
  56. else:
  57. print("\nYou successfully fled the enemy!")
  58. return True
  59. else:
  60. escape_roll = random.randint(1, 6) + evasion_mod
  61. if (escape_roll <= 4):
  62. damage_in = random.randint(1, 6) + 2
  63. hp -= damage_in
  64. print("\nYou failed to escape! Your enemy strikes, dealing " + str(damage_in) + " damage to you.")
  65. return False
  66. else:
  67. print("\nYou successfully fled the enemy!")
  68. return True
  69. # Create an array with a description for every room.
  70. room_descriptions = [
  71. "\nYou are currently in the northwest watchtower. You see the knight\nUnpensador lying in the corner. He is gravely wounded. Around here\nyou see boxes of alchemical ingredients, as that is the knight's\nspecialty. This room appears safe enough to rest in. To the east is the\nnorth wing of the castle. To the south is the west wing of the castle.",
  72. "\nYou are currently in the north wing of the castle, in the west side.\nThe corridor is long and barren. A window is broken, letting the\ncold air in. It is frigid enough that you can see your own breath. To\nthe west is the northwest watchtower. To the east is the other side\nof the north wing. To the south is the chapel.",
  73. "\nYou are currently in the north wing of the castle, in the east side.\nThe moon shines brightly through a large window. You quickly pray\nthat you will live to see tomorrow's sun. To the west is the other\nside of the north wing. To the south is south is the throne room.\nTo the east is the northwest watchtower.",
  74. "\nYou are currently in the northeast watchtower. You see the knight\nTormenta wounded and lying on the ground, struggling to survive. A\nhuge armory lines the walls, including maces, axes, and swords. You\ndo not know how to use any of these weapons, so you are content to\nuse your spear. Tormenta knows how to use all these weapons, but\nunfortunately she cannot fight any more. This room appears safe\nenough to rest in. To the west is the north wing. To the south is\nthe royal quarters.",
  75. "\nYou are currently in the west wing of the castle, in the north side.\nThere are visible puddles of blood on the floor, with one large\ntrail of blood leading north. It looks like the blood came from someone\nstruggling to crawl to a safe place. To the north is the northwest\nwatchtower. To the south is the other side of the west wing. To the\neast is the chapel.",
  76. "\nYou are currently in the chapel. There are no worshippers here on\nthis dreaded day. The stained glass windows that promise a savior\nare almost ironic. This room appears safe enough to rest in. To the\nnorth is the north wing of the castle. To the west is the west wing\nof the castle. To the south is the garden. To the east is the throne\nroom.",
  77. "\nYou are currently in the throne room. The king is, unfortunately,\ndead. You take a moment of silence to mourn his loss, and appreciate\nhis efforts to unite the city-states under one banner while still\nrespecting the role of local governments. You have hope that his legacy\nwill not be in vain. To the north is the north wing of the castle.\nTo the west is the chapel. To the south is the garden. To the east is\nthe royal quarters.",
  78. "\nYou are currently in the royal quarters. Each bedroom is decorated\nbeautifully, but you do not have time to appreciate that now. Rather\nthan being filled with awe at its beauty, you are filled with dread\nthat the monsters will destroy the wealth that the kingdom worked so\nhard to create. To the north is the northeast watchtower. To the\nwest is the throne room. To the south is the servant quarters.",
  79. "\nYou are currently in the west wing of the castle, in the south side.\nYou hear scratching on the walls but you cannot tell if it is a\ntree branch or something more sinister. Of course, supposing that it may\nonly be a tree branch is just wishful thinking. To the north is the\nother side of the west wing. To the south is the southwest watchtower.\nTo the east is the garden.",
  80. "\nYou are currently in the garden, in the west side. The area once\nfilled with life has now become a testament of death. The ground you\nwalk on is devoid of life, and only dirt, mud and sand remains. Some of\nthe species cultivated here were extinct in the wild, which worries\nyou. To the north is the chapel. To the west is the west wing of\nthe castle. To the south is the entrance of the castle. To the east is\nthe other side of the garden.",
  81. "\nYou are currently in the garden, in the east side. The flowers and\nother plants here are wilted and smell of decay. Their current state\nof being is saddening to you. The damage is unlikely to ever be undone.\nTo the north is the throne room. To the west is the other side of the\ngarden. To the south is the dining hall. To the east is the\nservant quarters.",
  82. "You are in the servant quarters. Instead of being filled with the\nhustle and bustle of the daily work, this part of the castle is\nfrighteningly silent and still. You wonder what happened to the\nbodies of your deceased friends. To the north is the royal quarters.\nTo the west is the garden. To the south is the southeast watchtower.",
  83. "\nYou are currently in the southwest watchtower. You see the knight\nPacifica sitting on the stairs, breathing heavily and noticeably\ninjured. The torch on the wall has almost burned out. The flickering\nlight illuminates the piles of gold and other treasure scattered in\nthe room. Pacifica happens to be an accomplished merchant. This room\nappears safe enough to rest in. To the north is the west wing of the\ncastle. To the east is the entrance of the castle.",
  84. "\nYou are currently at the entrance of the castle. There is no escape,\nfor the door is sealed shut by some dark magic. Besides, there is\nno way you would abandon your friends. A gentle light source is coming\nfrom the west. Flickering shadows dance on the wall. You could tell\nyourself it is only mice, but you know better. To the north is the garden.\nTo the west is the southwest watchtower. To the east is the dining hall.",
  85. "\nYou are currently in the dining hall. There is no merriment here on\nthis day. Replacing the fragrant smell of delicious food is the smell\nof ashes. There are visible scorch marks on the wall. To the north is\nthe garden. To the west is the entrance to the castle. To the east is\nthe southeast watchtower.",
  86. "\nYou are currently in the southeast watchtower. You see the knight\nElbardo is seriously injured, and is nursing himself by the wall.\nScattered around the room are various musical instruments, but now\nis really not the time to ask Elbardo to play a tune for you. Wind\nhowls down the chamber from above you. This room appears safe enough\nto rest in. To the north is the servant quarters. To the west is the\ndining hall."
  87. ]
  88. room_entrance_message = [
  89. "\nYou enter the northwest watchtower.",
  90. "\nYou enter the west side of the north wing.",
  91. "\nYou enter the east side of the north wing.",
  92. "\nYou enter the northeast watchtower.",
  93. "\nYou enter the north side of the west wing.",
  94. "\nYou enter the chapel.",
  95. "\nYou enter the throne room.",
  96. "\nYou enter the royal quarters.",
  97. "\nYou enter the south side of the west wing.",
  98. "\nYou enter the west side of the garden.",
  99. "\nYou enter the east side of the garden.",
  100. "\nYou enter the servant quarters.",
  101. "\nYou enter the southwest watchtower.",
  102. "\nYou enter the castle entrance room.",
  103. "\nYou enter the dining hall.",
  104. "\nYou enter the southeast watchtower."
  105. ]
  106. room_name = [
  107. "Northwest watchtower",
  108. "North wing, west",
  109. "North wing, east",
  110. "Northeast watchtower",
  111. "West wing, north",
  112. "Chapel",
  113. "Throne room",
  114. "Royal quarters",
  115. "West wing, south",
  116. "Garden, west",
  117. "Garden, east",
  118. "Servant quarters",
  119. "Southwest watchtower",
  120. "Castle entrance",
  121. "Dining hall",
  122. "Southeast watchtower"
  123. ]
  124. print(
  125. "*** Welcome to Los Torreros ***\nCopyright 2013, 2014, 2015 Jason MacDuffie.\n")
  126. print("Greetings, player. What is your name?")
  127. pc_name = read(">>> ")
  128. while (len(pc_name) > 16):
  129. print("\nYour name cannot be more than 16 letters. What is your name?")
  130. pc_name = read(">>> ")
  131. # If the length is greater than 16 characters, ask for a shorter name.
  132. print(
  133. "\nHello, {0} You are a guardsperson of ".format(pc_name + ".")
  134. + "Gran Castillo. The\ncastle is under attack by strange and evil "
  135. + "monsters. It is your duty\nto protect to castle from these "
  136. + "threats. Search for the boss to drive\nout the monsters.")
  137. print(
  138. "\nPlease select your bonus stat: power, health, or intel. Power\n"
  139. + "increases the damage you deal to enemies. Health increases your\n"
  140. + "maximum hit points. Intel makes it easier to avoid and escape "
  141. + "combat.")
  142. # The player chooses a bonus stat.
  143. bonus_stat = read(">>> ").lower()
  144. while (bonus_stat != "power" and bonus_stat != "health" and
  145. bonus_stat != "intel"):
  146. print("\nPlease choose either power, health, or intel.")
  147. bonus_stat = read(">>> ").lower()
  148. print("\nYou have chosen the " + bonus_stat + " stat. Good choice!")
  149. # Initialize all player stats and modify the bonus stat.
  150. max_hp = 25
  151. damage_mod = 3
  152. evasion_mod = 1
  153. if (bonus_stat == "power"):
  154. damage_mod = 6
  155. elif (bonus_stat == "health"):
  156. max_hp = 40
  157. else:
  158. evasion_mod = 2
  159. hp = max_hp
  160. # Set the room to the chapel.
  161. current_room = 5
  162. # Randomize the location of the boss, Bellamor. The possible rooms
  163. # are 1, 2, 4, 6, 7, 8, 9, 10, 11, 13, and 14.
  164. boss_location = random.randint(1,11)
  165. if (boss_location >= 3):
  166. boss_location = boss_location + 1
  167. if (boss_location >= 5):
  168. boss_location = boss_location + 1
  169. if (boss_location >= 12):
  170. boss_location = boss_location + 1
  171. # Set the hints being given by Unpensador, Pacifica, Tormenta and Elbardo.
  172. if (boss_location == 1 or boss_location == 2 or boss_location == 6):
  173. unpensador_hint = "east"
  174. tormenta_hint = "west"
  175. pacifica_hint = "north"
  176. elbardo_hint = "north"
  177. elif (boss_location == 4 or boss_location == 8 or boss_location == 9):
  178. unpensador_hint = "south"
  179. tormenta_hint = "west"
  180. pacifica_hint = "north"
  181. elbardo_hint = "west"
  182. elif (boss_location == 7 or boss_location == 10 or boss_location == 11):
  183. unpensador_hint = "east"
  184. tormenta_hint = "south"
  185. pacifica_hint = "east"
  186. elbardo_hint = "north"
  187. else:
  188. unpensador_hint = "south"
  189. tormenta_hint = "south"
  190. pacifica_hint = "east"
  191. elbardo_hint = "west"
  192. # Set the boss's initial hit points.
  193. boss_health = 50
  194. # Game state: 0 = playing, 1 = quit, 2 = death, 3 = victory
  195. game_state = 0
  196. # Combat state: 0 = no enemy, 1 = basic enemy, 2 = boss
  197. combat_state = 0
  198. print("\nHint: For information about available commands, say 'help'.")
  199. # Begin the game loop.
  200. while (game_state == 0):
  201. moved_rooms = False
  202. command = read(">>> ").lower()
  203. # This begins the help options.
  204. if (command == "help"):
  205. print(
  206. "\nAvailable commands are look, move, talk, attack, status, "
  207. + "info, wait,\nand quit. For info about a specific "
  208. + "[command], type 'help [command]'.")
  209. elif (command == "help help"):
  210. print(
  211. "\nDisplay the available commands or information about a "
  212. + "specific command.")
  213. elif (command == "help look"):
  214. print("\nLook at your surroundings.")
  215. elif (command == "help move"):
  216. print(
  217. "\nType 'move n/s/e/w' to travel in a particular direction. "
  218. + "For example, to\ngo north, type 'move n'. You can also "
  219. + "simply type 'n' or 'north'.")
  220. elif (command == "help talk"):
  221. print("\nTalk to another character in the room.")
  222. elif (command == "help attack"):
  223. print("\nDeal damage to the enemy in the room.")
  224. elif (command == "help status"):
  225. print("\nDisplay the current status of your game.")
  226. elif (command == "help info"):
  227. print(
  228. "\nGet information about the game. Options are license, "
  229. + "objective, and\nauthor.")
  230. elif (command == "help wait"):
  231. print(
  232. "\nRest until you have maximum hit points. This is only "
  233. + "allowed in certain\nrooms.")
  234. elif (command == "help quit"):
  235. print(
  236. "\nImmediately end the game. The state of the game will "
  237. + "not be saved.")
  238. # This ends the help options.
  239. elif (command == "look"):
  240. print(room_descriptions[current_room])
  241. # This begins the move options.
  242. elif (command == "move"):
  243. print(
  244. "\nPlease say 'move [direction]' or just '[direction]' to "
  245. + "move. For\nexample, to go north, say 'move n' or 'n'.")
  246. elif (command == "move n" or command == "move north" or
  247. command == "n" or command == "north"):
  248. if (0 <= current_room < 4):
  249. print("\nYou cannot go north from here.")
  250. elif (flees_combat()):
  251. current_room = current_room - 4
  252. print(room_entrance_message[current_room])
  253. moved_rooms = True
  254. combat_state = 0
  255. elif (command == "move w" or command == "move west" or
  256. command == "w" or command == "west"):
  257. if (current_room % 4 == 0):
  258. print("\nYou cannot go west from here.")
  259. elif (flees_combat()):
  260. current_room = current_room - 1
  261. print(room_entrance_message[current_room])
  262. moved_rooms = True
  263. combat_state = 0
  264. elif (command == "move s" or command == "move south" or
  265. command == "s" or command == "south"):
  266. if (12 <= current_room < 16):
  267. print("\nYou cannot go south from here.")
  268. elif (flees_combat()):
  269. current_room = current_room + 4
  270. print(room_entrance_message[current_room])
  271. moved_rooms = True
  272. combat_state = 0
  273. elif (command == "move e" or command == "move east" or
  274. command == "e" or command == "east"):
  275. if (current_room % 4 == 3):
  276. print("\nYou cannot go east from here.")
  277. elif (flees_combat()):
  278. current_room = current_room + 1
  279. print(room_entrance_message[current_room])
  280. moved_rooms = True
  281. combat_state = 0
  282. elif (command[0:4] == "move"):
  283. print("\nThat is not a valid direction. Options are n, w, s, or e.")
  284. # This ends the move options.
  285. # This starts the talk dialog.
  286. elif (command == "talk"):
  287. if (current_room == 0):
  288. print("\nUnpensador: *Cough* Hey " + pc_name + "... I don't have much strength\nleft in me. Bellamor attacked me and fled " + unpensador_hint + " last I saw him. If only\nI had the strength to brew a healing potion... ")
  289. elif (current_room == 3):
  290. print("\nTormenta: Greetings, knight " + pc_name + ". Unfortunately I cannot\nhelp you fight ever since Bellamor wounded me. You need to track that\nmonster down and finish what I couldn't. I saw him running " + tormenta_hint + " after\nwe fought. I may not ever wield a blade again...")
  291. elif (current_room == 12):
  292. print("\nPacifica: " + pc_name + "... I'm in a lot of pain. Bellamor hurt me.\nI barely got away with my life. He was headed " + pacifica_hint + " after he struck\nme. He does not seem interested in gold, for he has not tried to enter\nthis room...")
  293. elif (current_room == 15):
  294. print("\nElbardo: Hello, " + pc_name + ". Looks like my right arm is no good\nanymore. Bellamor came out of nowhere and attacked me from behind.\nHave you checked " + elbardo_hint + " yet? That's where I saw him. Also, do you\nthink it's possible to play the mandolin with one arm? It would be\ngreat to have a song to cheer us up in these desperate times... Aha,\nI know what I can do! Now where is my harmonica...")
  295. elif (combat_state == 1):
  296. print("\nMonster: DIE DIE DIE DIE DIE DIE DIE")
  297. elif (combat_state == 2):
  298. print("\nBellamor: I don't make idle chit-chat with prey.")
  299. else:
  300. print("There is nobody to speak with.")
  301. # This ends the talk dialog.
  302. # This begins the attack command.
  303. elif (command == "attack"):
  304. if (combat_state == 0):
  305. print("\nThere is no enemy to attack here.")
  306. elif (combat_state == 1):
  307. damage_out = random.randint(1, 4) + damage_mod
  308. damage_in = random.randint(1, 4) + 1
  309. hp -= damage_in
  310. mob_health -= damage_out
  311. print("\nYou delivered " + str(damage_out) + " damage to the monster, and it delivered " + str(damage_in) + " damage to you!")
  312. else:
  313. damage_out = random.randint(1, 4) + damage_mod
  314. damage_in = random.randint(1, 6) + 2
  315. hp -= damage_in
  316. boss_health -= damage_out
  317. print("\nYou delivered " + str(damage_out) + " damage to Bellamor, and he delivered " + str(damage_in) + " damage to you!")
  318. # This ends the attack command.
  319. elif (command == "status"):
  320. print("\nHit Points: " + str(hp) + " / " + str(max_hp))
  321. print("Location: " + room_name[current_room])
  322. if (combat_state == 0):
  323. print("Combat: None")
  324. elif (combat_state == 1):
  325. print("Combat: Enemy")
  326. else:
  327. print("Combat: Boss")
  328. # This begins the info options.
  329. elif (command == "info"):
  330. print(
  331. "\nType 'info license' to display the copyright license "
  332. + "for this game.\nType 'info objective' to display the "
  333. + "objective of this game.\nType 'info author' to display "
  334. + "information about the author of this game.")
  335. elif (command == "info license"):
  336. print(license)
  337. elif (command == "info objective"):
  338. print(objective)
  339. elif (command == "info author"):
  340. print(author)
  341. elif (command[0:4] == "info"):
  342. print("\nThat is not a valid option for info. Type 'info' for a list "
  343. + "of options.")
  344. # This ends the info options.
  345. elif (command == "wait"):
  346. if (current_room == 0 or
  347. current_room == 3 or
  348. current_room == 5 or
  349. current_room == 12 or
  350. current_room == 15):
  351. if (hp < max_hp):
  352. hp = max_hp
  353. print("\nYou take a break here to regain your health.")
  354. else:
  355. print("\nYou are already fully rested.")
  356. else:
  357. print("\nYou are not in a safe place to wait.")
  358. elif (command == "quit"):
  359. game_state = 1
  360. else:
  361. if (command != ""):
  362. print(
  363. "\nThat is not a valid command. Type 'help' for "
  364. + "a list of commands.")
  365. # Post-command instructions
  366. if (combat_state == 1 and mob_health <= 0 and hp > 0):
  367. print("\nThe enemy is defeated!")
  368. combat_state = 0
  369. elif (boss_health <= 0 and hp > 0):
  370. print("\nThe enemy is defeated!")
  371. game_state = 3
  372. if (moved_rooms):
  373. if (current_room != boss_location):
  374. combat_roll = random.randint(1, 6) + evasion_mod
  375. if (combat_roll <= 2 and
  376. current_room != 0 and
  377. current_room != 3 and
  378. current_room != 5 and
  379. current_room != 12 and
  380. current_room != 15):
  381. combat_state = 1
  382. mob_health = 20
  383. print("\nYou encountered a monster!")
  384. else:
  385. combat_state = 2
  386. print("\nYou encountered Bellamor!")
  387. if (hp <= 0):
  388. game_state = 2
  389. if (game_state == 1):
  390. print("\nGood bye! Please play another time.")
  391. elif (game_state == 2):
  392. print("\nYou died! Now the kingdom is sure to fall to the monsters.")
  393. else:
  394. print("\nCongratulations! You have defeated Bellamor and saved the castle!\nEven though the king is dead, the kingdom will be restored to\npeace and normality, with the help of you and the remaining knights.")
  395. end()