0
"""
Tic Tac Toe Player
"""

import math
import copy

X = "X"
O = "O"
EMPTY = None
util = 0

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.
    """
    initial = initial_state()
    xcount = 0
    ocount = 0
    if board == initial:
        return X
    for row in board:
        for i in range(3):
            if row[i] == "X":
                xcount += 1
            elif row[i] == "O":
                ocount += 1
    if terminal(board) == True:
        return X
    if xcount > ocount:
        return O
    else:
        return X


def actions(board):
    """
    Returns set of all possible actions (i, j) available on the board.
    """
    empty = []
    i = -1
    for row in board:
        i += 1
        for j in range(3):
            if row[j] == EMPTY:
                empty.append((i,j))
    if terminal(board) == True:
        return None
    return empty



def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    if action[0] not in range(0, 3) or action[1] not in range(0, 3) or board[action[0]][action[1]] is not EMPTY:
        raise Exception("Invalid move")
    copyboard = copy.deepcopy(board)
    i = action[0]
    j = action[1]
    currentplayer = player(board)
    copyboard[i][j] = currentplayer
    return copyboard

def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    xcounter = 0
    ocounter = 0
    columns = []
    if board[0][0] == board[0][1] == board[0][2]:
        return board[0][0]
    if board [1][0] == board[1][1] == board [1][2]:
        return board[1][0] 
    if board [2][0] == board[2][1] == board [2][2]:
        return board[2][0]
    if board [0][0] == board[1][0] == board [2][0]:
        return board[0][0]
    if board [0][1] == board[1][1] == board [2][1]:
        return board[0][1]
    if board [0][2] == board[1][2] == board [2][2]:
        return board[0][2]
    if board [0][0] == board[1][1] == board [2][2]:
        return board[0][0]
    if board [0][2] == board[1][1] == board [2][0]:
        return board[0][2]
def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    emptycount = 0
    if winner(board) in (X,O):
        return True
    for i in range(3):
        for j in range(3):
            if board[i][j] == EMPTY:
                emptycount += 1
    if not emptycount == 0:
        return False
    else:
        return True

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


def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """
    if terminal(board):
        return None
    move = set()
    if player(board) == X:
        move = maxmin(board, player="maxplayer")
        return move
    elif player(board) == O:
        move = maxmin(board, player="miplayer")
        return move
    

util = 0
def maxmin(board, player):
    if terminal(board) == True:
        return utility(board)
    if player == "maxplayer":
        maxmove = set()
        for move in actions(board):
            util = maxmin(result(board,move), player="minplayer")
            if util == 1:
                maxmove = move
            elif util == 0:
                maxmove = move
        return maxmove
    elif player == "minplayer":
        minmove = set()
        for move in actions(board):
            util = maxmin(result(board,move), player="maxplayer")
            if util == -1:
                minmove = move
            elif util == 0:
                minmove = move
        return minmove

Even though I realise this implementation of the minimax algorithm for the game of tic tac toe maybe completely absurd, I would like to know if there is any slight chance that this would work with tweaking or if I should completely rethink the entire implementation.

Although running the entire code gives me this Error:
line 66, in result if action[0] not in range(0, 3) or action[1] not in range(0, 3) or board[action[0]][action[1]] is not EMPTY: TypeError: 'NoneType' object is not subscriptable

You must log in to answer this question.

Browse other questions tagged .