import random board = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] wincombs = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)) player1 = 'x' player2 = 'o' def render(board): print(f''' {board[0]} │ {board[1]} │ {board[2]} ───┼───┼─── {board[3]} │ {board[4]} │ {board[5]} ───┼───┼─── {board[6]} │ {board[7]} │ {board[8]}''') def evaluate(board): for wincomb in wincombs: if board[wincomb[0]] == board[wincomb[1]] == board[wincomb[2]] == player1: return 1 if board[wincomb[0]] == board[wincomb[1]] == board[wincomb[2]] == player2: return -1 if all(cell in {player1, player2} for cell in board): return 0 def askmove(board): for _ in range(3): # 3 attempts userinput = input('\nWhere do you want to place your x? > ') if userinput in {'1', '2', '3', '4', '5', '6', '7', '8', '9'}: idx = int(userinput) - 1 if board[idx] not in {player1, player2}: return idx print('\nInvalid input') return askmove(board) exit(0) def emptycells(board): for cell in board: if cell not in {player1, player2}: yield cell def checkposition(board): eval = evaluate(board) if eval is not None: render(board) if eval == 0: print('\nDRAW\n') if eval == 1: print(f'\n{player1} won the game!\n') if eval == -1: print(f'\n{player2} won the game!\n') exit(0) def minimax(board, ismax, alpha = -float('inf'), beta = float('inf')): eval = evaluate(board) if eval is not None: return eval if ismax: bestvalue = -float('inf') for cell in emptycells(board): idx = int(cell) - 1 board[idx] = player1 minimaxvalue = minimax(board, False, alpha, beta) board[idx] = cell if minimaxvalue > bestvalue: bestvalue = minimaxvalue alpha = max(alpha, bestvalue) if alpha >= beta: break else: bestvalue = float('inf') for cell in emptycells(board): idx = int(cell) - 1 board[idx] = player2 minimaxvalue = minimax(board, True, alpha, beta) board[idx] = cell if minimaxvalue < bestvalue: bestvalue = minimaxvalue beta = min(beta, bestvalue) if alpha >= beta: break return bestvalue def bestmoves(board, ismax): bestmovelist = [] if ismax: bestvalue = -float('inf') for cell in emptycells(board): idx = int(cell) - 1 board[idx] = player1 minimaxvalue = minimax(board, False) board[idx] = cell if minimaxvalue == bestvalue: bestmovelist.append(cell) elif minimaxvalue > bestvalue: bestvalue = minimaxvalue bestmovelist = [cell] else: bestvalue = float('inf') for cell in emptycells(board): idx = int(cell) - 1 board[idx] = player2 minimaxvalue = minimax(board, True) board[idx] = cell if minimaxvalue == bestvalue: bestmovelist.append(cell) elif minimaxvalue < bestvalue: bestvalue = minimaxvalue bestmovelist = [cell] return bestmovelist import time if __name__ == '__main__': while True: starttime = time.time() bestmoves_list = bestmoves(board, False) computermove = random.choice(bestmoves_list) exectime = time.time() - starttime print('exectime >', exectime) input() render(board) usermove = askmove(board) board[usermove] = player1 checkposition(board) bestmoves_list = bestmoves(board, False) computermove = random.choice(bestmoves_list) idx = int(computermove) - 1 board[idx] = player2 checkposition(board)