model.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. """Classes representing Adventure game components.
  2. Copyright 2010-2015 Brandon Rhodes. Licensed as free software under the
  3. Apache License, Version 2.0 as detailed in the accompanying README.txt.
  4. """
  5. class Move(object):
  6. """An entry in the travel table."""
  7. is_forced = False
  8. verbs = []
  9. condition = None
  10. action = None
  11. def __repr__(self):
  12. verblist = [ verb.text for verb in self.verbs ]
  13. c = self.condition[0]
  14. if c is None:
  15. condition = ''
  16. elif c == '%':
  17. condition = ' %d%% of the time' % self.condition[1]
  18. elif c == 'not_dwarf':
  19. condition = ' if not a dwarf'
  20. elif c == 'carrying':
  21. condition = ' if carrying %s' % self.condition[1]
  22. elif c == 'carrying_or_in_room_with':
  23. condition = ' if carrying or in room with %s' % self.condition[1]
  24. elif c == 'prop!=':
  25. condition = ' if prop %d != %d' % self.condition[1:]
  26. if isinstance(self.action, Room):
  27. action = 'moves to %r' % (self.action.short_description
  28. or self.action.long_description[:20]).strip()
  29. elif isinstance(self.action, Message):
  30. action = 'prints %r' % self.action.text
  31. else:
  32. action = 'special %d' % self.action
  33. return '<{}{} {}>'.format('|'.join(verblist), condition, action)
  34. class Room(object):
  35. """A location in the game."""
  36. long_description = ''
  37. short_description = ''
  38. times_described = 0
  39. visited = False
  40. is_light = False
  41. is_forbidden_to_pirate = False
  42. liquid = None
  43. trying_to_get_into_cave = False
  44. trying_to_catch_bird = False
  45. trying_to_deal_with_snake = False
  46. lost_in_maze = False
  47. pondering_dark_room = False
  48. at_witts_end = False
  49. def __init__(self):
  50. self.travel_table = []
  51. def __repr__(self):
  52. return '<room {} at {}>'.format(self.n, hex(id(self)))
  53. @property
  54. def is_forced(self):
  55. return self.travel_table and self.travel_table[0].is_forced
  56. @property
  57. def is_aboveground(self):
  58. return 1 <= self.n <= 8
  59. @property
  60. def is_before_hall_of_mists(self):
  61. return self.n < 15
  62. @property
  63. def is_after_hall_of_mists(self):
  64. return self.n >= 15
  65. @property
  66. def is_dark(self):
  67. return not self.is_light
  68. class Word(object):
  69. """A word that can be used as part of a command."""
  70. text = None
  71. kind = None
  72. default_message = None
  73. def __init__(self):
  74. self.synonyms = [ self ]
  75. def __repr__(self):
  76. return '<Word {}>'.format(self.text)
  77. def __eq__(self, text):
  78. return any( word.text == text for word in self.synonyms )
  79. def add_synonym(self, other):
  80. """Every word in a group of synonyms shares the same list."""
  81. self.synonyms.extend(other.synonyms)
  82. other.synonyms = self.synonyms
  83. class Object(object):
  84. """An object in the game, like a grate, or a rod with a rusty star."""
  85. def __init__(self):
  86. self.is_fixed = False
  87. self.is_treasure = False
  88. self.inventory_message = ''
  89. self.messages = {}
  90. self.names = []
  91. self.prop = 0
  92. self.rooms = []
  93. self.starting_rooms = []
  94. self.is_toting = False
  95. self.contents = None # so the bottle can hold things
  96. def __repr__(self):
  97. return '<Object %d %s %x>' % (self.n, '/'.join(self.names), id(self))
  98. def __hash__(self):
  99. return self.n
  100. def __eq__(self, other):
  101. return any( text == other for text in self.names )
  102. def is_at(self, room):
  103. return room in self.rooms
  104. def carry(self):
  105. self.rooms[:] = []
  106. self.is_toting = True
  107. def drop(self, room):
  108. self.rooms[:] = [ room ]
  109. self.is_toting = False
  110. def hide(self):
  111. self.rooms[:] = []
  112. self.is_toting = False
  113. def destroy(self):
  114. self.hide()
  115. class Message(object):
  116. """A message for printing."""
  117. text = ''
  118. def __str__(self):
  119. return self.text
  120. class Hint(object):
  121. """A hint offered if the player loiters in one area too long."""
  122. turns_needed = 0
  123. turn_counter = 0
  124. penalty = 0
  125. question = None
  126. message = None
  127. used = False
  128. def __init__(self):
  129. self.rooms = []
  130. class Dwarf(object):
  131. is_dwarf = True
  132. is_pirate = False
  133. def __init__(self, room):
  134. self.start_at(room)
  135. self.has_seen_adventurer = False
  136. def start_at(self, room):
  137. self.room = room
  138. self.old_room = room
  139. def can_move(self, move):
  140. if not isinstance(move.action, Room):
  141. return False
  142. room = move.action
  143. return (room.is_after_hall_of_mists
  144. and not room.is_forced
  145. and not move.condition == ('%', 100))
  146. class Pirate(Dwarf):
  147. is_dwarf = False
  148. is_pirate = True