project_game/gm.py

183 lines
7.1 KiB
Python

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'