oberon/isola.py

141 lines
5.6 KiB
Python

class Isola:
def __init__(self, data):
self.pieces = [' X ', ' O ']
self.game_id = data['id']
self.p1 = data['p1']
self.p2 = data['p2']
self.board = data['board']['board']
self.turn_number = data['turn_number']
self.winner = data['winner']
self.current_player = data['current_ps_turn']
self.piece = self.pieces[data['piece_index']]
self.instructions = 'Instructions:\nOn your turn, move to any adjacent tile (shown as: - ),\nthen destroy any unocupied tile on the baord. The loser is the first to have nowhere to move on their turn.'
self.directions = [[1,0],[1,-1],[0,-1],[-1,-1]]
self.game_name = '\nIsola\n'
self.p1coords = data['board']['p1']
self.p2coords = data['board']['p2']
def print_challenge_text(self):
print(self.game_name)
if self.winner:
print('{} vs. {}: {} won!'.format(self.p1, self.p2, self.winner))
else:
print('{} vs. {}: {}\'s turn {}'.format(self.p1, self.p2, self.current_player, self.piece))
def print_board(self):
print('\n\n ' + ''.join([' ' + str(i) + ' ' for i in range(7)]))
for x in range(7):
print(' ' + str(x) + ''.join(self.board[x]))
print('')
def get_input(self):
move_type = ['MOVEMENT', 'DESTRUCTION']
move_phase = 0
print('Enter your move (or destruction) as row-column (ex. 4-5)')
print('Or (q)uit, (f)orfeit, (i)nstructions.\n')
while True:
move = input('{} > '.format(move_type[move_phase]))
if move in ['q', 'quit', 'exit']:
return False
elif move in ['f', 'forfeit']:
while True:
verify = input('Are you sure (y/n)? ')
if verify in ['y', 'yes']:
self.winner = self.p1 if self.p2 == self.current_player else self.p2
res = {'winner': self.winner, 'board': self.board, 'move': False, 'message': '{} forfeit, {} wins!'.format(self.current_player, self.winner)}
return res
elif verify in ['n', 'no']:
print('Forfeit canceled')
return False
elif move in ['i', 'instructions']:
print(self.instructions)
continue
else:
move = move.split('-')
if not len(move) == 2:
print('Invalid entry!')
continue
try:
row = int(move[0])
col = int(move[1])
except ValueError:
print('Invalid entry!')
continue
if not move_phase:
if self.validate_move([row, col]):
self.do_move([row, col])
move_phase = 1
continue
else:
print('That is not a legal move. Try again.')
continue
else:
if self.validate_destruction([row, col]):
self.do_destruction([row, col])
else:
print('That is not a legal square to destroy. Try again.')
continue
res_board_data = {'board': self.board, 'p1': self.p1coords, 'p2': self.p2coords}
res = {'winner': self.winner, 'board': res_board_data, 'move': True}
if self.game_over():
res['winner'] = self.current_player
res['message'] = '{} won the match!'.format(self.current_player)
else:
res['message'] = 'Your move has been placed.'
return res
def validate_move(self, mov):
old_position = self.p1coords if self.piece == self.pieces[0] else self.p2coords
if mov[0] < 0 or mov[0] > 6 or mov[1] < 0 or mov[1] > 6 or self.board[mov[0]][mov[1]] != ' - ':
return False
if abs(mov[0] - old_position[0]) > 1 or abs(mov[1] - old_position[1]) > 1:
return False
return True
def do_move(self, mov):
old_position = self.p1coords if self.piece == self.pieces[0] else self.p2coords
if self.turn_number < 3:
self.board[old_position[0]][old_position[1]] = ' '
else:
self.board[old_position[0]][old_position[1]] = ' - '
self.board[mov[0]][mov[1]] = self.piece
if self.turn_number % 2 != 0:
self.p1coords = mov
else:
self.p2coords = mov
def validate_destruction(self, des):
if des[0] < 0 or des[0] > 6 or des[1] < 0 or des[1] > 6 or self.board[des[0]][des[1]] != ' - ':
return False
return True
def do_destruction(self, des):
self.board[des[0]][des[1]] = ' '
def game_over(self):
board = self.board
enemy_coords = self.p1coords if self.piece == self.pieces[1] else self.p2coords
row = enemy_coords[0]
col = enemy_coords[1]
if (row + 1 <= 6 and board[row + 1][col] == ' - ') or (col + 1 <= 6 and board[row][col + 1] == ' - ') or (row - 1 >= 0 and board[row - 1][col] == ' - ') or (col - 1 >= 0 and board[row][col - 1] == ' - ') or (row - 1 >= 0 and col - 1 >= 0 and board[row - 1][col - 1] == ' - ') or (row + 1 <= 6 and col + 1 <= 6 and board[row + 1][col + 1] == ' - ') or (row + 1 <= 6 and col - 1 >= 0 and board[row + 1][col - 1] == ' - ') or (row - 1 >= 0 and col + 1 <= 6 and board[row - 1][col + 1] == ' - '):
return False
return True