class AdventureGame: def __init__(self,gamefile,sheet): self.player = player.Player(self) # pass self as controller - access to gameworld for Player.move() self.parser = Parser(self) self.initialize_world(gamefile, sheet) # load game dict, and define player start location self.valid_player_movements = [] # Assigned by generate valid movements. self.gamestate = 'normal' # Normal or Combat def get_command(self): # TODO: error check; if invalid choice, prompt again with valid choices. if self.gamestate == 'normal': self.valid_player_movements = self.generate_valid_player_movements() self.print_actions_and_objects() # Print movements and items to interact with. usrinput = input('>> ').lower() # TODO: implement 'help' command. selected_action = self.parser.parse_input(usrinput) while not selected_action: # Invalid input print(self.parser.error_message) self.print_actions_and_objects() usrinput = input('>> ').lower() selected_action = self.parser.parse_input(usrinput) if (self.player.current_location.is_locked and selected_action.__class__.__name__.startswith('Move')): test, error, success = self.player.current_location.exit_criteria if not test(): print(error) return else: print(success) self.player.take_action(selected_action) if selected_action in self.player.current_location.trigger_actions: consequences = self.player.current_location.trigger_actions[selected_action] for func in consequences: func() def print_actions_and_objects(self): print('\n' + '*' * 15) for m in self.valid_player_movements: print('\t\t{}'.format(m.name.title())) print('\t\tView Inventory') print("OBJECTS IN ROOM:\n") if not self.player.current_location.objects: print('\t\t None') else: for obj in self.player.current_location.objects: print('\t\t{}'.format(obj.name.title())) def check_location_exists(self,dx,dy): curr_x, curr_y = self.player.current_location.getcoords() new = (curr_x + dx, curr_y + dy) if self.gameworld.get(new, None): return True return False def generate_valid_player_movements(self): movements = [actions.MoveNorth, actions.MoveEast, actions.MoveSouth, actions.MoveWest] directions = [(0,-1), (1,0), (0,1), (-1,0)] valid_movements = [m() for (m,delta) in zip(movements,directions) if self.check_location_exists(*delta)] return valid_movements def run(self): while self.player.isalive(): self.get_command() def initialize_world(self, file, sheet): wb = xlrd.open_workbook(file) sheet = wb.sheet_by_name(sheet) self.gameworld = {} starting_location_found = False for rown in range(0,sheet.nrows): for coln in range(0,sheet.ncols): locname = sheet.cell(rown,coln).value if locname.startswith('!START'): if starting_location_found: # Duplicate starting declarations in game file print("""Game file {} contains multiple starting declarations! Please edit your file to include only a single starting location, declared with a "!START" location prefix""".format(file)) sys.exit(1) starting = (coln, rown) starting_location_found = True locname = locname[6:] # Strip !STARTING declaration location = getattr(importlib.import_module('locations'), locname, None) self.gameworld[coln, rown] = location(xcoord=coln, ycoord=rown, controller=self, name=locname) if location else None try: starting except NameError: print("""Game file {}, sheet {} does not include a starting location! Add declaration prefix "!START" to the location you wish player to begin in.""".format(file, sheet)) sys.exit(1) self.player.setlocation(self.gameworld[starting])
class AdventureGame: def __init__(self, gamefile, sheet): self.player = Player(self) # pass self as controller - access to gameworld for Player.move() self.parser = Parser(self) self.initialize_world(gamefile, sheet) # load game dict, and define player start location self.valid_player_movements = [] # Assigned by generate valid movements. self.gamestate = 'normal' # Normal or Combat self.action_log = deque(maxlen=5) self.combat = None def get_command(self): # TODO: error check; if invalid choice, prompt again with valid choices. usrinput = input('>> ').lower().strip() # TODO: implement 'help' command. selected_action = self.parser.parse_input(usrinput) while not selected_action: print(self.parser.error_message) usrinput = input('>> ').lower().strip() selected_action = self.parser.parse_input(usrinput) return (selected_action) # A method or tuple of method, target obj def execute_action(self, method_or_tuple): logging.debug('Arg is of type {}'.format(type(method_or_tuple))) if isinstance(method_or_tuple, tuple): method, target = method_or_tuple method = getattr(self.player, method.__name__) method(target) consequences = self.player.current_location.trigger_actions.get(method.__name__, {}).get(target, None) # Consequences? if consequences: logging.debug('CONSEQUENCES: {}'.format(consequences)) for func in consequences: func() else: method = getattr(self.player, method_or_tuple.__name__, None) or getattr(self, method_or_tuple.__name__) method() def print_actions_and_objects(self): print('\n' + '*' * 15) for m in self.valid_player_movements: print('\t\t{}'.format(m.name.title())) print('\t\tView Inventory') print("OBJECTS IN ROOM:\n") if not self.player.current_location.objects: print('\t\t None') else: for obj in self.player.current_location.objects: print('\t\t{}'.format(obj.name.title())) def check_location_exists(self,dx,dy): curr_x, curr_y = self.player.current_location.coords new = (curr_x + dx, curr_y + dy) if self.gameworld.get(new, None): return True return False def generate_valid_player_movements(self): movements = [actions.MoveNorth, actions.MoveEast, actions.MoveSouth, actions.MoveWest] directions = [(0,-1), (1,0), (0,1), (-1,0)] valid_movements = [m for (m,delta) in zip(movements,directions) if self.check_location_exists(*delta)] return valid_movements def run(self): while self.player.isalive(): # Separate combat vs. normal game state here? command = self.get_command() self.execute_action(command) def initialize_world(self, file, sheet): wb = xlrd.open_workbook(file) sheet = wb.sheet_by_name(sheet) self.gameworld = {} starting_location_found = False for rown in range(0,sheet.nrows): for coln in range(0,sheet.ncols): locname = sheet.cell(rown,coln).value if locname.startswith('!START'): if starting_location_found: # Duplicate starting declarations in game file print("""Game file {} contains multiple starting declarations! Please edit your file to include only a single starting location, declared with a "!START" location prefix""".format(file)) sys.exit(1) starting = (coln, rown) starting_location_found = True locname = locname[6:] # Strip !STARTING declaration location = getattr(importlib.import_module('locations'), locname, None) self.gameworld[coln, rown] = location(xcoord=coln, ycoord=rown, controller=self, name=locname) if location else None try: starting except NameError: print("""Game file {}, sheet {} does not include a starting location! Add declaration prefix "!START" to the location you wish player to begin in.""".format(file, sheet)) sys.exit(1) self.player.setlocation(self.gameworld[starting]) def quit(self): y_n = input("Are you sure you want to quit?").lower() if y_n in ('yes','y'): sys.exit() def log(self): for a in self.action_log: print(a+'\n') def help(self): print("Helping you! :)") def save(self): print('Saving game...') def startcombat(self, *enemies): self.combat = Combat(self, enemies) self.combat.start()