def test_whenSubBoardsArePlayedThenGetSubBoardReturnsCorrectly(): main_board = MainBoard(3) main_board = force_sub_board_win(main_board, 0, 0, Player.ME) sub_board = main_board.get_sub_board(MainBoardCoords(0, 0)) assert (sub_board.is_finished) assert (sub_board.winner == Player.ME) other_sub_board = main_board.get_sub_board(MainBoardCoords(0, 1)) assert (not other_sub_board.is_finished)
def test_row_col_checks_work(): main_board = MainBoard() for game_event in get_game_events('engine/tests/logs/diag_fail.gamelog'): main_board = main_board._add_move(game_event[0], game_event[1], game_event[2]) assert is_diagonal_won(main_board._board[0][1]._board, Player.OPPONENT) is True assert is_col_won(main_board._board[0][2]._board, MainBoardCoords(0, 1), Player.ME) is True assert is_row_won(main_board._board[2][1]._board, MainBoardCoords(1, 1), Player.ME) is True
def force_sub_board_tie(main_board, board_row, board_col): return main_board \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(0, 0), Player.ME) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(1, 1), Player.OPPONENT) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(2, 2), Player.ME) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(0, 2), Player.OPPONENT) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(2, 0), Player.ME) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(1, 0), Player.OPPONENT) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(1, 2), Player.ME) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(2, 1), Player.OPPONENT) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(0, 1), Player.ME)
def test_whenNextBoardIsFinishedThenAnyBoardCanBePlayed(): main_board = MainBoard() # Force some sub_board plays to finish a board finished_sub_board = main_board._board[2][2] \ .add_my_move(SubBoardCoords(0, 0)) \ .add_my_move(SubBoardCoords(1, 1)) \ .add_my_move(SubBoardCoords(2, 2)) # Set that sub-board where the sub_board_next_player_must_play will be main_board._board[2][2] = finished_sub_board # Play a move that will make the finished board the next board (Move 2, 2) main_board = main_board.add_my_move(MainBoardCoords(0, 0), SubBoardCoords(2, 2)) # Playing anywhere is now allowed assert main_board.sub_board_next_player_must_play == None assert main_board.is_playing_on_sub_board_allowed(MainBoardCoords(1, 1)) == True main_board.add_opponent_move(MainBoardCoords(0, 0), SubBoardCoords(1, 1))
def test_whenBoardIsPrettyPrintedThenItIsRenderedCorrectly(): string_board = str(MainBoard(3).add_my_move(MainBoardCoords(0, 0), SubBoardCoords(1, 1)) .add_opponent_move(MainBoardCoords(1, 1), SubBoardCoords(2, 2)) .add_opponent_move(MainBoardCoords(2, 2), SubBoardCoords(0, 0))) assert string_board == "0 0 0 | 0 0 0 | 0 0 0 \n" \ "0 1 0 | 0 0 0 | 0 0 0 \n" \ "0 0 0 | 0 0 0 | 0 0 0 \n" \ "- - - | - - - | - - - \n" \ "0 0 0 | 0 0 0 | 0 0 0 \n" \ "0 0 0 | 0 0 0 | 0 0 0 \n" \ "0 0 0 | 0 0 2 | 0 0 0 \n" \ "- - - | - - - | - - - \n" \ "0 0 0 | 0 0 0 | 2 0 0 \n" \ "0 0 0 | 0 0 0 | 0 0 0 \n" \ "0 0 0 | 0 0 0 | 0 0 0 \n"
def parse_move(received_move: str): main_board_coords_str, opponent_move_str = received_move.split(";") main_board_coords = MainBoardCoords( *map(int, main_board_coords_str.split(","))) sub_board_coords = SubBoardCoords( *map(int, opponent_move_str.split(","))) return main_board_coords, sub_board_coords
def get_game_events(filename): log_file = open(filename, 'r') lines = log_file.readlines() log_file.close() game_events = [] for line in lines: line = line.strip() player = Player.NONE if 'opponent' in line: player = Player.OPPONENT elif 'player' in line: player = Player.ME else: continue move_str = line[-7:] main_board_coords = MainBoardCoords(int(move_str[0]), int(move_str[2])) sub_board_coords = SubBoardCoords(int(move_str[4]), int(move_str[6])) game_events.append((main_board_coords, sub_board_coords, player)) return game_events
def read_move(input_line: str): received_move = input_line.split(" ")[1] main_board_coords_str, opponent_move_str = received_move.split(";") main_board_coords = MainBoardCoords( *map(int, main_board_coords_str.split(","))) sub_board_coords = SubBoardCoords( *map(int, opponent_move_str.split(","))) return main_board_coords, sub_board_coords
def test_whenNextBoardIsFinishedThenGetValidBoardsReturnsAllAvailableBoards(): main_board = MainBoard() # Force some sub_board plays to finish a board finished_sub_board = main_board._board[2][2] \ .add_my_move(SubBoardCoords(0, 0)) \ .add_my_move(SubBoardCoords(1, 1)) \ .add_my_move(SubBoardCoords(2, 2)) # Set that sub-board where the sub_board_next_player_must_play will be main_board._board[2][2] = finished_sub_board # Play a move that will make the finished board the next board (Move 2, 2) main_board = main_board.add_my_move(MainBoardCoords(0, 0), SubBoardCoords(2, 2)) # Playing anywhere is now allowed valid_boards = main_board.get_playable_coords() assert len(valid_boards) == 8 assert valid_boards == [MainBoardCoords(0, 0), MainBoardCoords(0, 1), MainBoardCoords(0, 2), MainBoardCoords(1, 0), MainBoardCoords(1, 1), MainBoardCoords(1, 2), MainBoardCoords(2, 0), MainBoardCoords(2, 1)]
def subBoardHeuristic(self, sub_board: SubBoard, coords): count = 0 tmpBoardMe = sub_board.add_my_move(coords) #if the move wins me the small board -> +1 if tmpBoardMe.is_finished: if tmpBoardMe.winner == Player.ME: count += 1 #if board is won by other player -1 if tmpBoardMe.is_finished and tmpBoardMe.winner == Player.OPPONENT: count -= 1 #if the current board can be won by them #if tmpBoardMe.is_finished and self.winnableBy(tmpBoardMe) == Player.OPPONENT: count -= 1 #board where they will get sent is winnable by them -1 if self.winnableBy( self.main_board.get_sub_board( MainBoardCoords(coords.row, coords.col))) == Player.OPPONENT: count -= 1 #board where they will get sent is winable by me if self.winnableBy( self.main_board.get_sub_board( MainBoardCoords(coords.row, coords.col))) == Player.ME: count += 1 #blocking the other player from wimnning tmpBoardOp = sub_board.add_opponent_move(coords) if tmpBoardOp.is_finished and tmpBoardOp.winner == Player.OPPONENT: count += 1 return count
def test_whenNextBoardIsAvailableThenGetValidBoardsReturnsOnlyThatBoard(): board = MainBoard().add_my_move(MainBoardCoords(0, 0), SubBoardCoords(2, 2)) # Only valid board now should be 2, 2 assert len(board.get_playable_coords()) == 1 assert board.get_playable_coords()[0] == MainBoardCoords(2, 2)
def test_whenNewMoveIsNotOnGameNextBoardThenExceptionRaised(): board = MainBoard().add_my_move(MainBoardCoords(0, 0), SubBoardCoords(1, 1)) # Move must now be on board at 1, 1 with pytest.raises(MoveNotOnNextBoardError): board.add_opponent_move(MainBoardCoords(1, 0), SubBoardCoords(1, 1))
def test_whenNewMoveIsOutsideValidSubBoardBoundsThenExceptionRaised(): with pytest.raises(MoveOutsideSubBoardError): MainBoard().add_my_move(MainBoardCoords(1, 1), SubBoardCoords(1, 3))
def test_whenNewMoveSubBoardCoordsAreOutOfBoundsThenExceptionRaised(): with pytest.raises(MoveOutsideMainBoardError): MainBoard().add_my_move(MainBoardCoords(1, 3), SubBoardCoords(0, 0)) with pytest.raises(MoveOutsideMainBoardError): MainBoard().add_opponent_move(MainBoardCoords(3, 1), SubBoardCoords(0, 0))
def force_sub_board_win(main_board, board_row, board_col, player): return main_board.copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(0, 0), player) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(1, 1), player) \ .copy_applying_move(MainBoardCoords(board_row, board_col), SubBoardCoords(2, 2), player)
def test_whenMainBoardIsFinishedThenNewMoveRaisesException(): main_board = MainBoard() main_board._is_finished = True with pytest.raises(MoveInFinishedBoardError): main_board.add_my_move(MainBoardCoords(1, 1), SubBoardCoords(1, 1))