After a certain number of moves my tictactoe program raise an exception
I'm trying to build an AI to play tictactoe(cs50ai pset0). i have built 7 essential functions for this purpose.
1.player function that takes as an argument a board and returns whose turn is it.
1. actions function that takes as an argument a board and returns the possible actions on the board as a set of tubles.
2. result function which takes an action and a board as arguments, and returns the new board caused of that action.
3. winner function which takes a board and returns whose the winner of that board if found, otherwise returns none.
4. 606
terminal functin which takes a board and determine if that board is a terminal board if so it will return True, otherwise it will return false. 6.utility function which takes a board and returns whose the utility of that board.
5. minimax function which takes a board and returns the optimal move for that board.
However, when i run my code sometimes after a number of moves it raise an exception(ActionError) i have tested all my function except mininmax and didn't catch the bug. Even though i can tell my minimax function doesn't choose the optimal move . """ Tic Tac Toe Player """
from math import inf
import copy
class ActionError(Exception):
pass
X = "X"
O = "O"
EMPTY = None
dictx = {}
dicto ={}
def initial_state():
"""
Returns starting state of the board.
"""
return [[EMPTY, EMPTY, EMPTY],
[EMPTY, EMPTY, EMPTY],
[EMPTY, EMPTY, EMPTY]]
def player(board):
"""
Returns player who has the next turn on a board.
"""
if not terminal(board):
x =0
o =0
for i in board:
for j in i:
if X == j:
x +=1
elif O == j:
o +=1
if o < x:
return O
else:
return X
def actions(board):
"""
Returns set of all possible actions (i, j) available on the board.
"""
if terminal(board):
return (0,0)
moves = set()
for i in range(len(board)):
for j in range(len(board)):
if board[i][j] == EMPTY:
moves.add((i,j))
return moves
def result(board, action):
"""
Returns the board that results from making move (i, j) on the board.
"""
play = player(board)
if action not in actions(board):
raise ActionError
new_board = copy.deepcopy(board)
for i in range(len(new_board)):
for j in range(len(new_board)):
if (i,j) == action:
new_board[i][j] = play
return new_board
def winner(board):
"""
Returns the winner of the game, if there is one.
"""
#horizontal
for i in board:
if i.count(X) == 3:
return X
if i.count(O) == 3:
return O
#vertical
v= set()
for i in range(3):
if len(v) == 1:
return list(v)[0]
v= set()
for j in range(3):
v.add(board[j][i])
#diagonal
n= set()
v= set()
for i in range(3):
for _ in range(1):
n.add(board[i][i])
v.add(board[i][2 - i])
if len(n) == 1:
return list(n)[0]
if len(v) == 1:
return list(v)[0]
return None
def terminal(board):
"""
Returns True if game is over, False otherwise.
"""
counter = 0
if winner(board) != None:
return True
for i in board:
for j in i:
if <PERSON> == EMPTY:
counter +=1
if winner(board) == None and counter == 0:
return True
return False
def utility(board):
"""
Returns 1 if X has won the game, -1 if O has won, 0 otherwise. 606