def test_result(self): board = initial_state() result_board = [[EMPTY, EMPTY, EMPTY], [EMPTY, X, EMPTY], [EMPTY, EMPTY, EMPTY]] self.assertEqual(result(board, (1, 1)), result_board) board = result_board result_board = [[EMPTY, EMPTY, EMPTY], [EMPTY, X, O], [EMPTY, EMPTY, EMPTY]] self.assertEqual(result(board, (1, 2)), result_board)
def test_result_initial_state(self): board = initial_state() action = (0, 0) expected = [[X, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] self.assertEqual(result(board, action), expected)
def minimax(board): """ Returns the optimal action for the current player on the board. """ if terminal(board) is True: return None # Code for player O if player(board) is O: v = float("inf") optimal = [] for action in actions(board): actionvalue = MaxValue(result(board, action)) if actionvalue < v: optimal.clear() optimal.append(action) v = actionvalue elif actionvalue == v: optimal.append(action) i = random.randrange(len(optimal)) return optimal[i] # Code for player X else: """ As any first move is expected to tie playing optimally, just randomize the first move to be quicker To make it more interesting, we take a random move between all the optimal sollutions so that the computer wont always play the same game. """ if board == [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]]: return (random.randrange(3), random.randrange(3)) else: v = float("-inf") optimal = [] for action in actions(board): actionvalue = MinValue(result(board, action)) if actionvalue > v: optimal.clear() optimal.append(action) v = actionvalue elif actionvalue == v: optimal.append(action) i = random.randrange(len(optimal)) return optimal[i]
def test_player_o_result(self): board = [[EMPTY, O, EMPTY], [X, EMPTY, EMPTY], [EMPTY, X, EMPTY]] result_board = [[EMPTY, O, EMPTY], [X, EMPTY, O], [EMPTY, X, EMPTY]] self.assertEqual(result(board, (1, 2)), result_board)
def test_result(self): board = [[tictactoe.EMPTY, tictactoe.EMPTY, tictactoe.EMPTY], [tictactoe.EMPTY, tictactoe.EMPTY, tictactoe.EMPTY], [tictactoe.EMPTY, tictactoe.EMPTY, tictactoe.EMPTY]] newBoard = tictactoe.result(board, (0, 2)) print(newBoard)
def make_move(): btn_text.set(tictactoe.player(self.state)) btn["state"] = "disabled" self.state = tictactoe.result(self.state, (x, y)) if tictactoe.terminal(self.state): self.game_over() return self.opponent_plays()
def test_board_move(coord): init = ttt.initial_state() new_state = ttt.result(init, coord) xs, os, empty = ttt._coords(new_state) assert len(xs) == 1 assert len(os) == 0 assert len(empty) == 8 assert ttt._is_empty(init), "initial board unmodified"
def test_result(self): action_1 = (1, 2) result_1 = ttt.result(self.board_1, action_1) self.assertEqual( result_1, [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, X], [EMPTY, EMPTY, EMPTY]]) action_2 = (2, 2) result_2 = ttt.result(self.board_2, action_2) self.assertEqual(result_2, [[EMPTY, EMPTY, O], [EMPTY, X, EMPTY], [X, EMPTY, O]]) action_3 = (2, 0) result_3 = ttt.result(self.board_3, action_3) self.assertEqual(result_3, [[O, X, O], [X, O, EMPTY], [X, EMPTY, EMPTY]]) action_4 = (0, 0) self.assertRaises(ValueError, ttt.result, self.board_3, action_4)
def test_result(): board = [["X", "O", "X"], ["O", "O", "X"], ["X", EMPTY, "O"]] possibleMoves = ttt.actions(board) expected = [["X", "O", "X"], ["O", "O", "X"], ["X", "X", "O"]] initBoard = copy.deepcopy(board) assert ttt.result(board, possibleMoves.pop()) == expected assert board == initBoard
def test_result(self): board = [ [tictactoe.X, tictactoe.O, tictactoe.EMPTY], [tictactoe.O, tictactoe.O, tictactoe.X], [tictactoe.X, tictactoe.EMPTY, tictactoe.EMPTY], ] # Check first move result = tictactoe.result(board, (0, 2)) self.assertEqual( result, [ [tictactoe.X, tictactoe.O, tictactoe.X], [tictactoe.O, tictactoe.O, tictactoe.X], [tictactoe.X, tictactoe.EMPTY, tictactoe.EMPTY], ], ) # Check second move board[0][2] = tictactoe.X result = tictactoe.result(board, (2, 1)) self.assertEqual( result, [ [tictactoe.X, tictactoe.O, tictactoe.X], [tictactoe.O, tictactoe.O, tictactoe.X], [tictactoe.X, tictactoe.O, tictactoe.EMPTY], ], ) # Check third move board[2][1] = tictactoe.O result = tictactoe.result(board, (2, 2)) self.assertEqual( result, [ [tictactoe.X, tictactoe.O, tictactoe.X], [tictactoe.O, tictactoe.O, tictactoe.X], [tictactoe.X, tictactoe.O, tictactoe.X], ], )
def test_result_valid_action(self): player_board = \ [[self.X, self.O, self.X], [self.O, self.O, self.EMPTY], [self.X, self.EMPTY, self.EMPTY]] player_move = (1, 2) resulting_board = \ [[self.X, self.O, self.X], [self.O, self.O, self.X], [self.X, self.EMPTY, self.EMPTY]] self.assertEqual(resulting_board, ttt.result(player_board, player_move))
def minimax(board): """ Returns the optimal action for the current player on the board. To be quicker if we detect a winning move we take it, not taking into account other moves """ if terminal(board) is True: return None # Code for player O if player(board) is O: v = float("inf") for action in actions(board): actionvalue = MaxValue(result(board, action)) if actionvalue == -1: return action if actionvalue < v: optimal = action v = actionvalue return optimal # Code for player X else: """ As any first move is expected to tie playing optimally, just randomize the first move to be quicker """ if board == [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]]: return (random.randrange(3), random.randrange(3)) else: v = float("-inf") for action in actions(board): actionvalue = MinValue(result(board, action)) if actionvalue == 1: return action if actionvalue > v: optimal = action v = actionvalue return optimal
def max_value(state, depth=0): if ttt.terminal(state): return (None, ttt.utility(state)) v = (None, -2) for action in ttt.actions(state): v = max( v, (action, min_value(ttt.result(state, action), depth + 1)[1] - (depth / 10)), key=lambda x: x[1]) return v
def opponent_plays(self): player = tictactoe.player(self.state) if player == tictactoe.PLAYER_O: _, action = tictactoe.min_value(self.state) else: _, action = tictactoe.max_value(self.state) btn, btn_text = self.buttons[action] btn_text.set(player) btn["state"] = "disabled" self.state = tictactoe.result(self.state, action) if tictactoe.terminal(self.state): self.game_over()
def rollout(self, node): """ Randomly plays from the state defined by node until the end of the game, returning the final outcome. """ # Available moves from this point board = node.board moves = ttt.actions(board) # Used to store the winner w = None # Play until there's a winner while w is None: # Pick a random move n = randint(low=0, high=len(moves)) action = moves[n] # Update the board (result automatically checks # whose go it is) board = ttt.result(board, action) # List all possible moves moves = ttt.actions(board) # See if anyone has won w = ttt.winner(board) # Break if we've run out of moves if len(moves) == 0: break if w is 'O': reward = 2 elif w is None: reward = 1 elif w is 'X': reward = 0 return reward
def next(): # Parse data currentBoard = request.form["board"] compSymbol = request.form["comp-symbol"] simulation = request.form["simulation"] erase = request.form["erase"] # Erase previous board history if new simulation game if erase == "true": session["previousBoard"] = {"x": None, "o": None} # Get new board after computer's move gamevars.setPreviousBoard(session) newBoard = tictactoe.computerTurn(currentBoard, compSymbol) newProb = gamevars.boardTree[compSymbol].search(newBoard).prob gameOver = tictactoe.gameOver(newBoard) # Save previous board into session cookie session["previousBoard"] = gamevars.previousBoard # If simulated game, update other computer's last probability if simulation == "true" and gameOver: opponent = [player for i, player in enumerate(gamevars.players) if player != compSymbol][0] if tictactoe.win(newBoard, compSymbol): tictactoe.learnFromLoss(opponent) elif tictactoe.tie(newBoard): tictactoe.learnFromTie(opponent) # If not a simulation, send back game status and computer's probability of winning if gameOver and simulation == "false": gamevars.setPlayerSymbols(session) msg = tictactoe.result(newBoard) elif simulation =="false": msg = newProb else: msg = "" data = json.dumps({"board": newBoard, "over": gameOver, "msg": msg}) return data
def test_result_input_board_unmodified(self): board = initial_state() action = (0, 0) result(board, action) self.assertEqual(board, initial_state())
from tictactoe import initial_state, player, actions, result, winner, minimax board = result(initial_state(), (0, 0)) print(minimax(board))
import tictactoe as t board = t.initial_state() board[0][2] = t.X board[1][1] = t.X board[2][0] = t.X print(t.utility(board)) print(t.terminal(board)) print(board) for row in board: print(row.count(t.O)) print (t.player(board)) print(t.actions(board)) for a in t.actions(board): print(t.result(board,a))
def test_result_throws_error(): board = [["X", "O", "X"], ["O", "O", "X"], ["X", EMPTY, "O"]] with pytest.raises(ValueError): ttt.result(board, (1, 1))
def test_result_mid_game(self): board = [[X, EMPTY, X], [O, O, EMPTY], [X, EMPTY, EMPTY]] action = (1, 2) expected = [[X, EMPTY, X], [O, O, O], [X, EMPTY, EMPTY]] self.assertEqual(result(board, action), expected)
import tictactoe as ttt board = ttt.test_state() while not (ttt.terminal(board)): move = ttt.minimax(board) print(ttt.player(board)) print(move) board = ttt.result(board, move) print(board) print(f"The winner is {ttt.winner(board)}")
title = f"Game Over: {winner} wins." elif user == player: title = f"Play as 1" else: title = f"Computer thinking..." title = largeFont.render(title, True, white) titleRect = title.get_rect() titleRect.center = ((width / 2), 30) screen.blit(title, titleRect) # Check for AI move if user != player and not game_over: if ai_turn: time.sleep(0.5) move = ttt.minimax(board) board = ttt.result(board, move, False) # False for ai ai_turn = False else: ai_turn = True # Check for a user move click, _, _ = pygame.mouse.get_pressed() if click == 1 and user == player and not game_over: mouse = pygame.mouse.get_pos() for i in range(3): for j in range(3): if (board[i][j] == ttt.EMPTY and tiles[i][j].collidepoint(mouse)): board = ttt.result(board, (i, j), True) # true for player
def test_first_move(self): before = [["X", EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] after = [["X", EMPTY, EMPTY], ["O", EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] self.assertEqual(result(before, (1, 0)), after)
def test_play_actions(self): before = [[EMPTY, EMPTY, "O"], ["O", "X", "X"], ["X", "O", "X"]] after = [[EMPTY, "O", "O"], ["O", "X", "X"], ["X", "O", "X"]] self.assertEqual(result(before, (0, 1)), after)
from tictactoe import initial_state import tictactoe as ttt EMPTY = None board = initial_state() board = [['X', 'X', 'O'], [EMPTY, 'O', EMPTY], [EMPTY, EMPTY, EMPTY]] player = ttt.player(board) moves = ttt.actions(board) print(f'board: {board}') while True: if ttt.terminal(board): break optimal = ttt.minimax(board) print(optimal) board = ttt.result(board, optimal) print(f'board: {board}') # print(ttt.utility(board))
from tictactoe import initial_state from tictactoe import player from tictactoe import actions from tictactoe import result from tictactoe import winner from tictactoe import terminal from tictactoe import utility from tictactoe import maxvalue from tictactoe import minvalue from tictactoe import minimax board=[[None, None, None], [None, None, None], [None, None, None]] print(result(board,(2,2)))
title = f"Play as {user}" else: title = f"Computer thinking..." title = largeFont.render(title, True, white) titleRect = title.get_rect() titleRect.center = ((width / 2), 30) screen.blit(title, titleRect) # Check for AI move if user != player and not game_over: if ai_turn: logging.debug("ai_turn with user = %s", user) time.sleep(0.5) move = ttt.minimax(board, ai_player) logging.debug("ai move from minimax %s", move) board = ttt.result(board, move, ai_player) ai_turn = False else: ai_turn = True # Check for a user move click, _, _ = pygame.mouse.get_pressed() if click == 1 and user == player and not game_over: mouse = pygame.mouse.get_pos() for i in range(3): for j in range(3): if (board[i][j] == ttt.EMPTY and tiles[i][j].collidepoint(mouse)): board = ttt.result(board, (i, j), user) if game_over:
title = f"Game Over: {winner} wins." elif user == player: title = f"Play as {user}" else: title = f"Computer thinking..." title = largeFont.render(title, True, white) titleRect = title.get_rect() titleRect.center = ((width / 2), 30) screen.blit(title, titleRect) # Check for AI move if user != player and not game_over: if ai_turn: time.sleep(0.5) move = ttt.minimax(board) board = ttt.result(board, move) ai_turn = False else: ai_turn = True # Check for a user move click, _, _ = pygame.mouse.get_pressed() if click == 1 and user == player and not game_over: mouse = pygame.mouse.get_pos() for i in range(3): for j in range(3): if (board[i][j] == ttt.EMPTY and tiles[i][j].collidepoint(mouse)): board = ttt.result(board, (i, j)) if game_over: againButton = pygame.Rect(width / 3, height - 65, width / 3, 50)
from tictactoe import result, X, O, EMPTY emptyBoard = [[EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] Board1 = [[EMPTY, X, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] Board2 = [[EMPTY, X, EMPTY], [EMPTY, EMPTY, O], [EMPTY, EMPTY, EMPTY]] if result(emptyBoard, (0, 1)) == Board1 and emptyBoard != Board1: print("works") else: print("check failed") if result(Board1, (1, 2)) == Board2: print("works") else: print("check 2 failed")