from retro.errors import AgentNotFoundByName import random from common import TOKENS_PER_PLAYER, PLAYER_NAMES class GameMaster: def __init__(self, width): self.name = 'gm' self.display = False self.position=(0,0) self.state = 'welcome' self.player = 0 self.width = width self.current_token = None self.die_roll = 0 self.move_count = 0 self.completed_tokens = {0: 0, 1: 0} def message(self, game, msg1='', msg2=''): game.state['msg1'] = msg1.ljust(self.width) game.state['msg2'] = msg2.ljust(self.width) def play_turn(self, game): game.log(f'State is {self.state}') if self.state == 'welcome': self.message(game, 'Welcome to Yutnori!', 'Press ENTER to begin') game.state['Current Player'] = PLAYER_NAMES[self.player] return if self.state == 'ask_throw_sticks': color = PLAYER_NAMES[self.player] self.message(game, f'Player {color}, throw your sticks!', 'Press ENTER to throw') return if self.state == 'determine_path': tok = self.current_token if tok.path == 'none': tok.path = 'peri' tok.step = 0 self.state = 'moving_token' return if tok.path == 'peri': if tok.step == 5: self.state = 'prompt_lr_corner_path_choice' return if tok.step == 10: self.state = 'prompt_tr_corner_path_choice' return if tok.step == 15: self.state = 'prompt_tl_corner_path_choice' return self.state = 'moving_token' if 'diag' in tok.path: if tok.step == 3: self.state = 'prompt_center_choice' return self.state = 'moving_token' return if self.state == 'moving_token': if self.move_count == 0: self.current_token.kick_out_enemy_tokens(game) self.current_token.adjust_position(game) self.state = 'check_next_player' if not game.turn_number % 3: game.log(f'Moves remaining: {self.move_count}') self.current_token.step_forward(game) if self.current_token.step == 0 and self.current_token.path == 'peri': game.remove_agent(self.current_token) self.completed_tokens[self.player] = self.completed_tokens[self.player] + 1 self.state = 'check_next_player' return self.move_count = self.move_count - 1 return if self.state == 'prompt_lr_corner_path_choice': self.message(game, f'Where would you like to go?', '(P)erimeter or (D)iagonal?') if self.state == 'prompt_tr_corner_path_choice': self.message(game, f'Where would you like to go?', '(P)erimeter or (D)iagonal?') if self.state == 'prompt_tl_corner_path_choice': self.message(game, f'Where would you like to go?', '(P)erimeter or (D)iagonal?') if self.state == 'prompt_center_choice': msg1 = 'Where would you like to go?' if self.current_token.path == 'diag2': msg2 = '(H)ome, Top (L)eft, Top (R)ight' if self.current_token.path == 'diag1': msg2 = '(H)ome, Top (L)eft, Bottom (R)ight' if self.current_token.path == 'diag2rev': msg2 = '(H)ome, (T)op Right, (B)ottom Right' self.message(game, msg1, msg2) if self.state == 'check_next_player': # Check if this player has won if self.completed_tokens[self.player] == TOKENS_PER_PLAYER: self.message(game, 'CONGRATULATIONS!!', f'Player {self.player} wins Yutnori!!') game.end() # Check if the previous roll was a Yut if self.die_roll != 5: self.player = 0 if self.player == 1 else 1 game.state['Current Player'] = PLAYER_NAMES[self.player] self.state = 'ask_throw_sticks' def handle_keystroke(self, keystroke, game): if self.state == 'welcome': if keystroke.name == 'KEY_ENTER': self.state = 'ask_throw_sticks' game.log(f'State is {self.state}') return if self.state == 'ask_throw_sticks': if keystroke.name == 'KEY_ENTER': values = { 1: 'Pig', 2: 'Dog', 3: 'Lamb', 4: 'Cow', 5: 'Horse', } die = random.randint(1, 5) self.message(game, f'You rolled {die} ({values[die]})', 'Choose a token to move (1-4)') self.state = 'choose_token' self.die_roll = die self.move_count = die game.log(f'State is {self.state}') return if self.state == 'choose_token': if not keystroke.isdigit(): return try: self.current_token = game.get_agent_by_name(f'{self.player}_{keystroke}') except AgentNotFoundByName: return self.state = 'determine_path' if self.state == 'prompt_lr_corner_path_choice': if keystroke.lower() == 'p': self.current_token.path = 'peri' self.state = 'moving_token' elif keystroke.lower() == 'd': self.current_token.path = 'diag2' self.current_token.step = 0 self.state = 'moving_token' if self.state == 'prompt_tr_corner_path_choice': if keystroke.lower() == 'p': self.current_token.path = 'peri' self.state = 'moving_token' elif keystroke.lower() == 'd': self.current_token.path = 'diag1' self.current_token.step = 0 self.state = 'moving_token' if self.state == 'prompt_tl_corner_path_choice': if keystroke.lower() == 'p': self.current_token.path = 'peri' self.state = 'moving_token' elif keystroke.lower() == 'd': self.current_token.path = 'diag2rev' self.current_token.step = 6 self.state = 'moving_token' if self.state == 'prompt_center_choice': if keystroke.lower() == 'h': self.current_token.path = 'diag1' self.state = 'moving_token' if keystroke.lower() == 'l': self.current_token.path = 'diag2' self.state = 'moving_token' if keystroke.lower() in ['r', 't']: self.current_token.path = 'diag2rev' self.state = 'moving_token' if keystroke.lower() == 'b': self.current_token.path = 'diag1rev' self.state = 'moving_token'