From a55714f35ea866647e4c3d967d890aaf14312f9b Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Tue, 21 Oct 2025 13:57:03 +0200 Subject: [PATCH] ass3: init tic_tac_toe --- assignment3/tic_tac_toe.py | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 assignment3/tic_tac_toe.py diff --git a/assignment3/tic_tac_toe.py b/assignment3/tic_tac_toe.py new file mode 100644 index 0000000..d07fb5f --- /dev/null +++ b/assignment3/tic_tac_toe.py @@ -0,0 +1,78 @@ +from copy import deepcopy + +State = tuple[int, list[list[int | None]]] # Tuple of player (whose turn it is), +# and board +Action = tuple[int, int] # Where to place the player's piece + + +class Game: + def initial_state(self) -> State: + return (0, [[None, None, None], [None, None, None], [None, None, None]]) + + def to_move(self, state: State) -> int: + player_index, _ = state + return player_index + + def actions(self, state: State) -> list[Action]: + _, board = state + actions = [] + for row in range(3): + for col in range(3): + if board[row][col] is None: + actions.append((row, col)) + return actions + + def result(self, state: State, action: Action) -> State: + _, board = state + row, col = action + next_board = deepcopy(board) + next_board[row][col] = self.to_move(state) + return (self.to_move(state) + 1) % 2, next_board + + def is_winner(self, state: State, player: int) -> bool: + _, board = state + for row in range(3): + if all(board[row][col] == player for col in range(3)): + return True + for col in range(3): + if all(board[row][col] == player for row in range(3)): + return True + if all(board[i][i] == player for i in range(3)): + return True + return all(board[i][2 - i] == player for i in range(3)) + + def is_terminal(self, state: State) -> bool: + _, board = state + if self.is_winner(state, (self.to_move(state) + 1) % 2): + return True + return all(board[row][col] is not None for row in range(3) for col in range(3)) + + def utility(self, state, player): + assert self.is_terminal(state) + if self.is_winner(state, player): + return 1 + if self.is_winner(state, (player + 1) % 2): + return -1 + return 0 + + def print(self, state: State): + _, board = state + print() + for row in range(3): + cells = [ + " " if board[row][col] is None else "x" if board[row][col] == 0 else "o" + for col in range(3) + ] + print(f" {cells[0]} | {cells[1]} | {cells[2]}") + if row < 2: + print("---+---+---") + print() + if self.is_terminal(state): + if self.utility(state, 0) > 0: + print(f"P1 won") + elif self.utility(state, 1) > 0: + print(f"P2 won") + else: + print("The game is a draw") + else: + print(f"It is P{self.to_move(state)+1}'s turn to move")