Created
February 22, 2024 11:49
-
-
Save annh3/886b4e62701cebbcd3c53d04e072a67e to your computer and use it in GitHub Desktop.
tic tac toe game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Game: | |
def __init__(self, nrounds: int=1): | |
self.board = [[-1]*3 for _ in range(3)] | |
self.nrounds = nrounds | |
self.turn = 0 # either player 0 or 1 | |
self.player_scores = {0:0, 1:0} | |
def check_valid_position(self, x: int, y: int) -> bool: | |
"""Check that the location is in bounds and empty.""" | |
return x >= 0 and x < 3 and y >= 0 and y < 3 and self.board[x][y] == -1 | |
def check_end_state(self) -> int: | |
"""Returns the winner, 2 if end state and no winner, or -1 if it is not an end state.""" | |
# 1. Check winner exists | |
for i in range(3): | |
row_set = set(self.board[i][:]) | |
row_set_list = list(row_set) | |
if len(row_set_list) == 1 and row_set_list[0] != -1: | |
return row_set_list[0] | |
col_set = set(self.board[:][i]) | |
col_set_list = list(col_set) | |
if len(col_set_list) == 1 and col_set_list[0] != -1: | |
return col_set_list[0] | |
x = list(range(3)) | |
y = list(range(3)) | |
# top-left to bottom-right | |
values = [self.board[x_coord][y_coord] for x_coord,y_coord in zip(x,y)] | |
values = list(set(values)) | |
if len(values) == 1 and values[0] != -1: | |
return values[0] | |
# top-right to bottom-left | |
y = reversed(y) | |
values = [self.board[x_coord][y_coord] for x_coord,y_coord in zip(x,y)] | |
values = list(set(values)) | |
if len(values) == 1 and values[0] != -1: | |
return values[0] | |
# 2. Check that board is filled | |
board_set = set() | |
for i in range(3): | |
row = set(self.board[i][:]) | |
board_set = board_set.union(row) | |
if -1 not in board_set: | |
return 2 | |
return -1 | |
def print_board(self): | |
#TODO(annhe): consider formatting the printing | |
for row in self.board: | |
print(row) | |
print('\n') | |
def run_game(self): | |
for round in range(self.nrounds): | |
print(f'Starting round {round}...') | |
while True: | |
player_turn = True | |
x,y = None, None | |
while player_turn: | |
print(f'Player {self.turn}, please input a valid position, x coord, comma, y coord: ') | |
try: | |
player_input = input() | |
x,y = player_input.split(',') | |
x = int(x) | |
y = int(y) | |
if self.check_valid_position(x,y): | |
player_turn = False | |
except: | |
pass # TODO(annhe): is this questionable practice? | |
self.board[x][y] = self.turn | |
state = self.check_end_state() | |
self.print_board() | |
if state == 1 or state == 0: | |
print(f'Player {state} has won the game') | |
self.player_scores[state] += 1 | |
break | |
if state == 2: | |
print('The game is in an end state') | |
self.player_scores[state] += 1 | |
break | |
self.turn = (self.turn + 1) % 2 | |
print(f'The games have ended...Player 0:{self.player_scores[0]} Player 1:{self.player_scores[1]}') | |
def main(): | |
game = Game() | |
game.run_game() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment