Skip to content

pushing tictactoe.py changes from local to remote repository #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 76 additions & 156 deletions tictactoe/tictactoe.py
Original file line number Diff line number Diff line change
@@ -1,205 +1,125 @@
"""
Tic Tac Toe Player
"""
import copy
from math import inf

X = "X"
O = "O"
EMPTY = None


def initial_state():
"""
Returns starting state of the board.
"""
return [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]]
"""Returns the starting state of the board."""
return [[EMPTY, EMPTY, EMPTY] for _ in range(3)]


def player(board):
"""
Returns player who has the next turn on a board.
"""
count = [0, 0]
for i in range(3):
for j in range(3):
if board[i][j] == "X":
count[0] = count[0] + 1
elif board[i][j] == "O":
count[1] = count[1] + 1

if count[0] > count[1]:
return O
else:
return X
"""Returns the player who has the next turn on the board."""
x_count = sum(row.count(X) for row in board)
o_count = sum(row.count(O) for row in board)
return O if x_count > o_count else X


def actions(board):
"""
Returns set of all possible actions (i, j) available on the board.
"""
possible_action = []
for i in range(3):
for j in range(3):
if board[i][j] == None:
possible_action.append((i, j))

return possible_action
"""Returns a list of all possible actions (i, j) available on the board."""
return [(i, j) for i in range(3) for j in range(3) if board[i][j] is EMPTY]


def result(board, action):
"""
Returns the board that results from making move (i, j) on the board.
"""
copy_board = copy.deepcopy(board)

if copy_board[action[0]][action[1]] is None:
a = player(copy_board)
copy_board[action[0]][action[1]] = a
return copy_board
else:
raise "eror"
"""Returns the board that results from making move (i, j) on the board."""
if board[action[0]][action[1]] is not EMPTY:
raise ValueError("Invalid action")

new_board = copy.deepcopy(board)
new_board[action[0]][action[1]] = player(board)
return new_board


def winner(board):
"""
Returns the winner of the game, if there is one.
"""
"""Returns the winner of the game, if there is one."""
# Check rows, columns, and diagonals
for i in range(3):
if (
board[i][0] == board[i][1]
and board[i][0] == board[i][2]
and board[i][0] != None
):
if board[i][0] == "X":
return X
elif board[i][0] == "O":
return O
else:
return None
if board[i][0] == board[i][1] == board[i][2] != EMPTY:
return board[i][0]
if board[0][i] == board[1][i] == board[2][i] != EMPTY:
return board[0][i]

for i in range(3):
if (
board[0][i] == board[1][i]
and board[1][i] == board[2][i]
and board[0][i] != None
):
if board[0][i] == "X":
return X
elif board[0][i] == "O":
return O
else:
return None

if (
board[0][0] == board[1][1]
and board[1][1] == board[2][2]
and board[0][0] != None
):
if board[0][0] == "X":
return X
elif board[0][0] == "O":
return O
else:
return None

if (
board[2][0] == board[1][1]
and board[1][1] == board[0][2]
and board[2][0] != None
):
if board[2][0] == "X":
return X
elif board[2][0] == "O":
return O
else:
return None
if board[0][0] == board[1][1] == board[2][2] != EMPTY:
return board[0][0]
if board[2][0] == board[1][1] == board[0][2] != EMPTY:
return board[2][0]

return None


def terminal(board):
"""
Returns True if game is over, False otherwise.
"""
if winner(board) == "X":
return True
elif winner(board) == "O":
return True

for i in range(3):
for j in range(3):
if board[i][j] == None:
return False
return True
"""Returns True if the game is over, False otherwise."""
return winner(board) is not None or all(cell is not EMPTY for row in board for cell in row)


def utility(board):
"""
Returns 1 if X has won the game, -1 if O has won, 0 otherwise.
"""
if winner(board) == "X":
return 1
elif winner(board) == "O":
return -1
else:
return 0
"""Returns 1 if X has won, -1 if O has won, 0 otherwise."""
win = winner(board)
return 1 if win == X else -1 if win == O else 0


def minimax(board):
"""
Returns the optimal move for the current player on the board.
"""
# Check for terminal state
"""Returns the optimal move for the current player on the board."""
if terminal(board):
return None

# If X's turn
elif player(board) == X:
options = []
for action in actions(board):
score = min_value(result(board, action))
# Store options in list
options.append([score, action])
# Return highest value action
return sorted(options, reverse=True)[0][1]

# If O's turn
if player(board) == X:
return max_move(board)
else:
options = []
for action in actions(board):
score = max_value(result(board, action))
# Store options in list
options.append([score, action])
# Return lowest value action
return sorted(options)[0][1]
return min_move(board)


def max_move(board):
"""Finds the best move for player X."""
best_value = -float('inf')
best_action = None
for action in actions(board):
value = min_value(result(board, action))
if value > best_value:
best_value = value
best_action = action
return best_action


def min_move(board):
"""Finds the best move for player O."""
best_value = float('inf')
best_action = None
for action in actions(board):
value = max_value(result(board, action))
if value < best_value:
best_value = value
best_action = action
return best_action


def max_value(board):
"""
Returns the highest value option of a min-value result
"""
# Check for terminal state
"""Returns the maximum value (for X) of a move."""
if terminal(board):
return utility(board)

# Loop through possible steps
v = -inf
value = -float('inf')
for action in actions(board):
v = max(v, min_value(result(board, action)))
return v
value = max(value, min_value(result(board, action)))
return value


def min_value(board):
"""
Returns the smallest value option of a max-value result
"""
# Check for terminal state
"""Returns the minimum value (for O) of a move."""
if terminal(board):
return utility(board)

# Loop through possible steps
v = inf
value = float('inf')
for action in actions(board):
v = min(v, max_value(result(board, action)))
return v
value = min(value, max_value(result(board, action)))
return value


if __name__ == "__main__":
board = initial_state()
while not terminal(board):
move = minimax(board)
board = result(board, move)
print(f"Player {player(board)} made move: {move}")
for row in board:
print(row)