def new_game(message):
	chat_id = message.chat.id
	new_game = Game()
	out = bot.send_message(chat_id, "```\n" + new_game.to_string() + "```", 
			reply_markup=markup, parse_mode="Markdown")
	
	games[out.message_id] = new_game
Exemple #2
0
    def test_game_run_with_ai(self, capsys):
        """Tests game run with 3 AI players and no human players."""
        config = GameConfig('tictactoe/tests/configs/config_with_3_ai.json')
        game = Game(config)

        with pytest.raises(SystemExit):
            game.run()
        captured = capsys.readouterr()

        # Assert game finished successfully and correct message is displayed.
        assert "Game finished" in captured.out and str(
            game.completed_turns) in captured.out
Exemple #3
0
    def test_winner_disordered(self):
        g = Game()
        g.place(0, 0, g.EX)
        g.place(1, 1, g.EX)
        g.place(2, 2, g.EX)

        g.place(1, 0, g.OH)
        g.place(0, 1, g.OH)

        self.assertTrue(g.is_valid_board())

        self.assertEqual(g.get_winning_player(), g.EX)
Exemple #4
0
def main(args=None):
    """Main program routine."""
    print(
        "=======================\nTic-Tac-Toe: Remastered\n======================="
    )

    config = GameConfig('config.json')
    # Note that config.json is exptected to be found in project root.

    if config.is_valid():
        # Intialize Game instance when we are sure the config is valid.
        game = Game(config)
        game.run()
Exemple #5
0
    def test_two_winners(self):
        g = Game()
        g.place(0, 0, g.EX)
        g.place(0, 1, g.EX)
        g.place(0, 2, g.EX)
        g.place(1, 0, g.OH)
        g.place(1, 1, g.OH)
        g.place(1, 2, g.OH)

        self.assertFalse(g.is_valid_board())
 def _train(self, size, dim):
     """Train the agent on a game with the given size and dimensions."""
     if self.q_matrix is None:
         self.q_matrix = defaultdict(lambda: {
             square: 0 for square in range(pow(size, dim))
         })
     self._trained = True
     training_game = Game(size, dim)
     print(f"Training {self.name} Agent")
     for epoch in tqdm(range(1, self._n + 1)):
         training_game.new_game()
         #print(f'Training epoch {epoch}')
         self._act(training_game)
         if epoch % 50 == 0:
             self._e = max(0.1, self._e - 0.01)
Exemple #7
0
    def test_game_initiation(self):
        """Tests game initiation with example config."""
        config = GameConfig('config_example.json')
        game = Game(config)

        # Assert grid was initiated according to config.
        assert isinstance(game.grid,
                          Grid) and game.grid.size == config['grid']['size']
        # Assert list of players were initiated according to config.
        assert isinstance(game.players, list) and len(game.players) == len(
            config['players'])
        # Assert referee was initiated.
        assert isinstance(game.referee, Referee)

        game.init_referee()
Exemple #8
0
 async def connect(self, msg):
     if msg == 'bot':
         self.game = Game()
         self.players = self, 0
         return True
     opponent = None
     for u in User._.values():
         if u.name.lower() == msg and not u.game:
             opponent = u
     if opponent:
         await opponent.send(
             f'You were invited to the game with {self.name}')
         self.game = opponent.game = Game()
         self.players = opponent.players = self, opponent
         return True
Exemple #9
0
def get_move_values(field, my_sign):
    move_values = []
    possible_moves = Game.free_spots(field)

    for current_move in possible_moves:
        new_array = np.copy(field)
        new_array[current_move[0]][current_move[1]] = my_sign
        # find the value of the move
        move_values.append(
            min_max_iteration(new_array, my_sign, Game.get_other_sign(my_sign), 1, len(possible_moves)))

    
    flattened_field = field.reshape(1,9).astype(int).tolist()
    if str(flattened_field) not in allmoves:
        allmoves[str(flattened_field)] = flattened_field,move_values

    return possible_moves, move_values
Exemple #10
0
 def test_invalid_four_moves(self):
     g = Game()
     g.place(0, 0, g.EX)
     g.place(1, 0, g.OH)
     g.place(0, 1, g.EX)
     g.place(2, 1, g.EX)
     self.assertFalse(g.is_valid_board())
Exemple #11
0
 def test_checkFinish_ThirdRowIsAllFirstPlayer_ReturnsFirstPlayerWon(self):
     game = Game()
     game.addFirstPlayerMove("C1")
     game.addFirstPlayerMove("C2")
     game.addFirstPlayerMove("C3")
     result = game.checkFinish()
     self.assertEqual(result, game.FirstPlayerWin,
                      'The first player should have won')
Exemple #12
0
def start(bot, update):
    chat_id = update.message.chat_id
    if chat_id not in games:
        game = Game()
        game.add_player(Player(chat_id))
        game.add_player(Player(0))
        game.start()
        games[chat_id] = game
        reply_markup = get_keyboard(game, False)
        bot.sendMessage(chat_id=chat_id,
                        text="Let's the game begin!",
                        reply_markup=reply_markup)
Exemple #13
0
 def test_checkFinish_LeftToRightDiagonalIsAllFirstPlayer_ReturnsFirstPlayerWon(
         self):
     game = Game()
     game.addFirstPlayerMove("A3")
     game.addFirstPlayerMove("B2")
     game.addFirstPlayerMove("C1")
     result = game.checkFinish()
     self.assertEqual(result, game.FirstPlayerWin,
                      'The first player should have won')
Exemple #14
0
 def test_checkFinish_FirstRowIsAllSecondPlayer_ReturnsSecondPlayerWon(
         self):
     game = Game()
     game.addSecondPlayerMove("A1")
     game.addSecondPlayerMove("A2")
     game.addSecondPlayerMove("A3")
     result = game.checkFinish()
     self.assertEqual(result, game.SecondPlayerWin,
                      'The second player should have won')
Exemple #15
0
def simulate(lineup, games, print_outcomes=True):
    winlog = []

    P1 = lineup[0]
    P2 = lineup[1]

    for _ in range(games):
        game = Game(P1, P2)
        game.play(print_board=False, record_history=False)

        winlog.append([P1.name(), P2.name(), game.winner.nr])

    winlog = pd.DataFrame(winlog, columns=['P1', 'P2', 'winner'])

    wins = round(100*len(winlog[winlog['winner']==1])/games, 1)
    lost = round(100*len(winlog[winlog['winner']==2])/games, 1)
    draw = round(100*len(winlog[winlog['winner']==0])/games, 1)
    if print_outcomes:
        print(f'P1 W: {wins} | D: {draw} | L: {lost}')

    return wins, draw, lost
	def test_checkFinish_LeftToRightDiagonalIsAllFirstPlayer_ReturnsFirstPlayerWon(self):
		game = Game()
		game.addFirstPlayerMove("A3")
		game.addFirstPlayerMove("B2")
		game.addFirstPlayerMove("C1")
		result = game.checkFinish()
		self.assertEqual(result, game.FirstPlayerWin, 'The first player should have won')
	def test_checkFinish_ThirdColumnIsAllFirstPlayer_ReturnsFirstPlayerWon(self):
		game = Game()
		game.addFirstPlayerMove("A3")
		game.addFirstPlayerMove("B3")
		game.addFirstPlayerMove("C3")
		result = game.checkFinish()
		self.assertEqual(result, game.FirstPlayerWin, 'The first player should have won')
	def test_checkFinish_FirstRowIsAllSecondPlayer_ReturnsSecondPlayerWon(self):
		game = Game()
		game.addSecondPlayerMove("A1")
		game.addSecondPlayerMove("A2")
		game.addSecondPlayerMove("A3")
		result = game.checkFinish()
		self.assertEqual(result, game.SecondPlayerWin, 'The second player should have won')
Exemple #19
0
def playMatchesBetweenVersions(env,
                               run_version,
                               player1version,
                               player2version,
                               EPISODES,
                               logger,
                               turns_until_tau0,
                               goes_first=0):
    env = Game()
    if player1version == -1:
        player1 = User("user1", env.state_size, env.action_size)
    else:
        player1_NN = Residual_CNN(config.REG_CONST, config.LEARNING_RATE,
                                  env.input_shape, env.action_size,
                                  config.HIDDEN_CNN_LAYERS)

        if player1version > 0:
            name = env.name + "{0:0>4}".format(player1version)
            if Provider.getNetByName(name) == None:
                return
            player1_network = player1_NN.read(env.name, run_version,
                                              player1version)
            player1_NN.model.set_weights(player1_network.get_weights())
        netName = env.name + "{0:0>4}".format(player1version)
        player1 = Agent(netName, env.state_size, env.action_size,
                        config.MCTS_SIMS, config.CPUCT, player1_NN)

    if player2version == -1:
        name = input('enter username: ')
        user2 = Provider.getPersonByName(name)
        player2 = User(user2.name, env.state_size, env.action_size)
    else:
        player2_NN = Residual_CNN(config.REG_CONST, config.LEARNING_RATE,
                                  env.input_shape, env.action_size,
                                  config.HIDDEN_CNN_LAYERS)

        if player2version > 0:
            name = env.name + "{0:0>4}".format(player2version)
            if Provider.getNetByName(name) == None:
                return
            player2_network = player2_NN.read(env.name, run_version,
                                              player2version)
            player2_NN.model.set_weights(player2_network.get_weights())
        net2Name = env.name + "{0:0>4}".format(player2version)
        player2 = Agent(net2Name, env.state_size, env.action_size,
                        config.MCTS_SIMS, config.CPUCT, player2_NN)

    scores, memory, points, sp_scores = playMatches(player1, player2, EPISODES,
                                                    logger, turns_until_tau0,
                                                    None, goes_first)

    return (scores, memory, points, sp_scores)
Exemple #20
0
def min_max_iteration(field, my_sign, current_sign, depth, maximum_depth):
    free_spots = Game.free_spots(field)
    if len(free_spots) == 0:
        return 0

    total = []
    for spot in free_spots:
        new_array = np.copy(field)
        new_array[spot[0]][spot[1]] = current_sign
        if Game.fast_is_won3x3(new_array, spot[0], spot[1]):
            if my_sign is current_sign:
                total.append(100000 / depth)
            else:
                total.append(-100000 / (maximum_depth - depth))
        else:
            total.append(min_max_iteration(new_array, my_sign, Game.get_other_sign(current_sign), depth + 1, maximum_depth))

    

    flattened_field = field.reshape(1,9).astype(int).tolist()

    minimum = np.amin(total)
    maximum = np.amax(total)
    normalize_range = maximum-minimum
    weights = np.array(-np.ones((3,3)))

    for index in range(0,len(free_spots)):
        if normalize_range < 0.0001:
            weights[free_spots[index][0]][free_spots[index][1]] = 1
        else:
            weights[free_spots[index][0]][free_spots[index][1]] = ((2 * (total[index] - minimum) / normalize_range) - 1)

    if str(flattened_field) not in allmoves and my_sign is current_sign:
       allmoves[str(flattened_field)] = flattened_field, weights.reshape(1,9).tolist()

    if my_sign is current_sign:
        return np.amax(total)
    else:
        return np.amin(total)
def play_game(game=Game(size=4, dim=3),
              players=(HumanPlayer('O'), NaiveBestFirstAgent('X')),
              display=True):

    assert len(players) == 2, 'Only two players'

    game.new_game()
    if display: game.display_board()

    turn = 0
    while 1:
        for player in players:
            turn += 1
            if display: print(f' Turn {turn}'.center(28, '-'))

            winner = game.take_turn(player.next_move(game))
            if display: game.display_board()

            if winner == 'C':
                if display: print("Cat's game...")
                return winner
            elif winner:
                if display: print(winner, 'is the winner!!!')
                return winner
#import code to be tested
from tictactoe import Game

g = Game()

# A smoke test
def test_smoke():
	assert True == True

#test to see if board is drawn
def test_board():
	assert Game.draw_board == "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
Exemple #23
0
class TicTacToeTest(unittest.TestCase):
    def setUp(self):
        self.game = Game("player 1", "player 2")

    def test_init(self):
        self.assertEqual(self.game.board,
                         [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]],
                         'Game board does not initialize to empty board')
        self.assertEqual(self.game.status, IN_PROGRESS,
                         'Game status does not initialize to in progress')
        self.assertEqual(self.game.move_count, 0,
                         'Game move does not initialize to 0')
        self.assertEqual(self.game.cur_player, self.game.players[0],
                         'Current player does not '
                         'initialize to player 1')

    def test_update_board(self):
        #Test updating the board at a specified row, col pair
        self.game.update_board(0, 0)
        self.assertEqual(self.game.board,
                         [["X", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]],
                         'Board updates incorrectly')

    def test_check_status_won(self):
        #Check if recognizes a winning configuration consisting of 3 X's in a row
        self.game.board = [["X", "X", "X"], ["-", "-", "-"], ["-", "-", "-"]]
        self.assertEqual(
            self.game.check_status(0, 0), WON,
            'Board doesnt recognize winning configuration across a row')

        # Check if recognizes a winning configuration of 3 O's in a column
        self.game.board = [["-", "O", "-"], ["-", "O", "-"], ["-", "O", "-"]]
        self.assertEqual(
            self.game.check_status(1, 1), WON,
            'Board doesnt recognize winning configuration across a column')

        # Check if recognizes a winning configuration of 3 X's across one diagonal
        self.game.board = [["X", "-", "-"], ["-", "X", "-"], ["-", "-", "X"]]
        self.assertEqual(
            self.game.check_status(2, 2), WON,
            'Board doesnt recognize winning configuration across diagonal from top-left'
            ' to bottom-right')

        # Check if recognizes a winning configuration of 3 O's across the other diagonal
        self.game.board = [["-", "-", "O"], ["-", "O", "-"], ["O", "-", "-"]]
        self.assertEqual(
            self.game.check_status(0, 2), WON,
            'Board doesnt recognize winning configuration across diagonal from top-right'
            ' to bottom-left')

        # Check if recognizes a tied configuration, where the board is full and nobody won
        self.game.board = [["X", "X", "O"], ["O", "X", "X"], ["X", "O", "O"]]
        self.game.move_count = 9
        self.assertEqual(self.game.check_status(1, 1), DRAW,
                         'Board does not recognize draw'
                         'configuration')

        # Check if recognizes nobody won and the game is still in progress because there is at least one empty space
        self.game.board = [["X", "X", "O"], ["O", "X", "X"], ["X", "O", "-"]]
        self.game.move_count = 8
        self.assertEqual(
            self.game.check_status(1, 1), IN_PROGRESS,
            'Board does not recognize'
            ' in progress configuration')

    def test_alternate_player(self):
        # Test if successfully alternates cur_player from player 1 to player 2
        self.game.cur_player = self.game.players[0]
        player = self.game.alternate_player()
        self.assertEqual(player, self.game.players[1],
                         'Alternate from player 1'
                         ' to player 2 not working')

        # Test if successfully alternates cur_player from player 2 to player 1
        self.game.cur_player = self.game.players[1]
        player = self.game.alternate_player()
        self.assertEqual(player, self.game.players[0],
                         'Alternate from player 2'
                         ' to player 1 not working')

    def test_reset(self):
        # Test resetting all board attributes after a game has been completed

        #First update the game to reflect a completed game
        self.game.status = 2
        self.game.board = [["X", "O", "-"], ["O", "X", "O"], ["-", "X", "X"]]
        self.game.move_count = 7
        self.game.cur_player = self.game.players[1]

        #Then reset the board and compare it to the desired values
        self.game.reset("name 1", "name 2")
        self.assertEqual(self.game.board,
                         [["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"]],
                         'Game board does not reset to empty board')
        self.assertEqual(self.game.status, IN_PROGRESS,
                         'Game status does not reset to in progress')
        self.assertEqual(self.game.move_count, 0,
                         'Game move does not reset to 0')
        self.assertEqual(self.game.cur_player, self.game.players[0],
                         'Current player does not '
                         'reset to player 1')

    def test_get_players(self):
        # Test that creates HumanPlayers and ComputerPlayers when appropriate and that they initialize correctly
        players = self.game.get_players("cpu", "human")
        self.assertEqual(
            players[0].is_human, False, "Creates a HumanPlayer when"
            "A ComputerPlayer should have been created")
        self.assertEqual(
            players[1].is_human, True, "Creates a ComputerPlayer when"
            "A HumanPlayer should have been created")
        self.assertEqual(players[0].id, 0, "Creates the wrong id for a player")
        self.assertEqual(players[1].letter, "O",
                         "Creates the wrong letter for a player")
        self.assertEqual(players[0].name, "cpu",
                         "Creates wrong name for a player")

    def test_alternate_letters(self):
        # Test that alternate from X to O correctly
        letter = ComputerPlayer.alternate_letters("X")
        self.assertEqual(letter, "O", "X did not alternate to O")

        # Test that alternate from O to X correctly
        letter = ComputerPlayer.alternate_letters("O")
        self.assertEqual(letter, "X", "O did not alternate to X")

    def test_evaluate_board(self):
        player = ComputerPlayer(0, "cpu", "X")

        # Check a win state
        win_board = [["X", "O", "-"], ["O", "X", "O"], ["-", "X", "X"]]
        value = player.evaluate_board(win_board, 2)
        self.assertEqual(value, WINNER,
                         "Didnt recognize a won board configuration")

        # Check a win state with a full board
        win_board = [["X", "O", "X"], ["O", "X", "O"], ["O", "X", "X"]]
        value = player.evaluate_board(win_board, 0)
        self.assertEqual(value, WINNER,
                         "Didnt recognize a won board configuration")

        # Check a loss state
        loss_board = [["-", "X", "O"], ["-", "O", "X"], ["O", "X", "-"]]
        value = player.evaluate_board(loss_board, 3)
        self.assertEqual(value, LOSER,
                         "Didnt recognize a lost board configuration")

        # Check a loss state with full board
        loss_board = [["X", "X", "O"], ["O", "O", "X"], ["O", "X", "X"]]
        value = player.evaluate_board(loss_board, 0)
        self.assertEqual(value, LOSER,
                         "Didnt recognize a lost board configuration")

        # Check a tie state
        tie_board = [["X", "X", "O"], ["O", "O", "X"], ["X", "O", "X"]]
        value = player.evaluate_board(tie_board, 0)
        self.assertEqual(value, TIED,
                         "Didnt recognize a tied board configuration")

        # Check an in progress state
        in_progress_board = [["X", "X", "O"], ["O", "X", "X"], ["X", "O", "-"]]
        value = player.evaluate_board(in_progress_board, 1)
        self.assertEqual(value, IN_PROGRESS,
                         "Didnt recognize an in progress board configuration")

    def test_minimax(self):
        # Check if chooses move to win
        player = ComputerPlayer(0, "cpu", "X")
        board = [["X", "-", "O"], ["X", "-", "O"], ["-", "-", "-"]]
        depth = 5
        best_move = player.minimax(board=board,
                                   depth=depth,
                                   maximizing=True,
                                   letter=player.letter,
                                   alpha=-100,
                                   beta=100)
        self.assertEqual(best_move, [2, 0, WINNER],
                         "Doesn't chose move that will win the game")

        # Checks if chooses move to prevent loss and win
        player = ComputerPlayer(0, "cpu", "X")
        board = [["-", "-", "X"], ["-", "O", "-"], ["X", "-", "O"]]
        depth = 5
        best_move = player.minimax(board=board,
                                   depth=depth,
                                   maximizing=True,
                                   letter=player.letter,
                                   alpha=-100,
                                   beta=100)
        row, col = best_move[0], best_move[1]
        self.assertEqual([row, col], [0, 0],
                         "Doesn't chose move that prevent a loss and win")

        # Checks if chooses move to prevent loss and tie
        player = ComputerPlayer(0, "cpu", "X")
        board = [["-", "-", "-"], ["-", "O", "X"], ["-", "X", "O"]]
        depth = 5
        best_move = player.minimax(board=board,
                                   depth=depth,
                                   maximizing=True,
                                   letter=player.letter,
                                   alpha=-100,
                                   beta=100)
        row, col = best_move[0], best_move[1]
        self.assertEqual([row, col], [0, 0],
                         "Doesn't chose move that prevent a loss")

        # Check if can see a few moves ahead and prevent opponent from forcing a victory
        player = ComputerPlayer(1, "cpu", "O")
        board = [["-", "-", "X"], ["-", "O", "-"], ["X", "-", "-"]]
        depth = 5
        best_move = player.minimax(board=board,
                                   depth=depth,
                                   maximizing=True,
                                   letter=player.letter,
                                   alpha=-100,
                                   beta=100)
        row, col = best_move[0], best_move[1]
        self.assertNotEqual(
            [row, col], [0, 0],
            "Chose move that allows opponent to force a victory")
        self.assertNotEqual(
            [row, col], [2, 2],
            "Chose move that allows opponent to force a victory")
Exemple #24
0
def train(players, size, in_a_row, agents, episodes):
    """ Сыграть несколько партий с agents """
    env = Game(players, size, in_a_row)

    wins = [0] * players
    loses = [0] * players
    draws = 0

    for episode in range(1, episodes + 1):
        done = [False] * players
        msgs = [None] * players
        state = env.reset().state
        while not min(done):
            # Пройти по всем пользователям, пока для всех не закончится партия
            for j, ag in enumerate(agents):
                if not done[j]:
                    action = ag.action(state)
                    new_map, reward, done[j], msgs[j] = env.action(action)
                    new_state = new_map.state
                    ag.fit(state, new_state, action, reward)
                    state = new_state
        else:
            for ag in agents:
                ag.decay(episode)

            if Message.DRAWMESSAGE in msgs:
                draws += 1
            else:
                # Посчитать победы
                for j, m in enumerate(msgs):
                    if m == Message.WINMESSAGE:
                        wins[j] += 1
                    elif m == Message.LOSEMESSAGE:
                        loses[j] += 1

            if episode % 10_000 == 0:
                # Отобразить статистику
                print(f"Игра №{episode}")
                for j in range(players):
                    print(
                        f"\tИгрок {j}. Побед: {wins[j]}. Поражений: {loses[j]}"
                    )
                print(f"\tНичьих: {draws}")

            if episode % 20_000 == 0 and (Message.WINMESSAGE in msgs
                                          or Message.DRAWMESSAGE in msgs):
                # Отобразить поле в конце партии
                if Message.DRAWMESSAGE in msgs:
                    print(Message.DRAWMESSAGE[1])
                else:
                    print(f"Игрок №{msgs.index(Message.WINMESSAGE)} выиграл")
                print(env.game_map)

            if episode % 200_000 == 0 and episode:
                # Сохранить Q-таблицы
                for j, ag in enumerate(agents):
                    # ag.save(f"dumps/Player{j}-{players}-{size[0]}x{size[1]}-{in_a_row}-{episode}eps-{int(time.time())}.pickle")
                    ag.save(
                        f"dumps/Player{j}-{players}-{size[0]}x{size[1]}-{in_a_row}-last.pickle"
                    )
                print("Q-таблицы сохранены")
	def test_validateInput_InputIsValid_returnsTrue(self):
		game = Game()
		result = game.validateInput("A1")
		self.assertTrue(result)
Exemple #26
0
 def test_check_game_when_not_enough_moves(self):
     game = Game(dimensions=(6,6))
     self.assertEqual(game.check_game_state(), None)
Exemple #27
0
def test_game():
    game = Game()
    assert game.players[0].name == "Player X"
    assert game.players[1].name == "Player O"

    assert not game.make_move(0)  # player 1

    assert game.is_position_taken(0)
    with pytest.raises(ValueError):
        assert game.is_position_taken(200)

    assert game.current_player == game.players[1]
    assert not game.make_move(4)  # player 2

    assert not game.make_move(1)  # player 1
    assert not game.make_move(5)  # player 2
    assert game.make_move(2)  # player 1
    assert game.get_winner() == game.players[0]
    assert game.is_end_of_game()
    assert not game.is_array_full()

    game2 = Game()

    # Cannot make a move to a position outside the game array limit
    with pytest.raises(ValueError):
        game2.make_move(123)

    assert not game2.make_move(0)  # player 1
    assert not game2.make_move(3)  # player 2
    assert not game2.make_move(1)  # player 1
    assert not game2.make_move(4)  # player 2
    assert not game2.make_move(8)  # player 1
    assert game2.make_move(5)  # player 2
    assert game2.get_winner() == game2.players[1]
    assert game.is_end_of_game()
    assert not game.is_array_full()
	def test_noMovesLeft_AllButOneMove_ReturnsFalse(self):
		game = Game()
		result = game.noMovesLeft()
		self.assertFalse(result)
Exemple #29
0
def playMatches(player1,
                player2,
                EPISODES,
                logger,
                turns_until_tau0,
                memory=None,
                goes_first=0):
    env = Game()
    scores = {player1.name: 0, "drawn": 0, player2.name: 0}
    sp_scores = {'sp': 0, "drawn": 0, 'nsp': 0}
    points = {player1.name: [], player2.name: []}

    for e in range(EPISODES):

        logger.info('====================')
        logger.info('EPISODE %d OF %d', e + 1, EPISODES)
        logger.info('====================')

        #        print (str(e+1) + ' ', end='\n')
        print(str(e + 1) + ' ', end='')

        state = env.reset()

        done = 0
        turn = 0
        player1.mcts = None
        player2.mcts = None

        if goes_first == 0:
            player1Starts = random.randint(0, 1) * 2 - 1
        else:
            player1Starts = goes_first

        if player1Starts == 1:
            players = {
                1: {
                    "agent": player1,
                    "name": player1.name
                },
                -1: {
                    "agent": player2,
                    "name": player2.name
                }
            }
            logger.info(player1.name + ' plays as X')
        else:
            players = {
                1: {
                    "agent": player2,
                    "name": player2.name
                },
                -1: {
                    "agent": player1,
                    "name": player1.name
                }
            }
            logger.info(player2.name + ' plays as X')
            logger.info('--------------')

        env.gameState.render(logger)
        env.gameState.render_print(logger)

        while done == 0:
            turn = turn + 1

            #### Run the MCTS algo and return an action
            if turn < turns_until_tau0:
                action, pi, MCTS_value, NN_value = players[
                    state.playerTurn]['agent'].act(state, 1)
            else:
                action, pi, MCTS_value, NN_value = players[
                    state.playerTurn]['agent'].act(state, 0)

            if memory != None:
                ####Commit the move to memory
                memory.commit_stmemory(env.identities, state, pi)

            logger.info('action: %d', action)
            for r in range(env.grid_shape[0]):
                logger.info([
                    '----' if x == 0 else '{0:.2f}'.format(np.round(x, 2))
                    for x in pi[env.grid_shape[1] * r:(env.grid_shape[1] * r +
                                                       env.grid_shape[1])]
                ])
            logger.info('MCTS perceived value for %s: %f',
                        state.pieces[str(state.playerTurn)],
                        np.round(MCTS_value, 2))
            logger.info('NN perceived value for %s: %f',
                        state.pieces[str(state.playerTurn)],
                        np.round(NN_value, 2))
            logger.info('====================')

            ### Do the action
            state, value, done, _ = env.step(
                action
            )  #the value of the newState from the POV of the new playerTurn i.e. -1 if the previous player played a winning move

            env.gameState.render(logger)
            env.gameState.render_print(logger)
            import datetime
            now = datetime.datetime.now()
            gameName = env.name
            if done == 1:
                if memory != None:
                    #### If the game is finished, assign the values correctly to the game moves
                    for move in memory.stmemory:
                        if move['playerTurn'] == state.playerTurn:
                            move['value'] = value
                        else:
                            move['value'] = -value

                    memory.commit_ltmemory()
                if value == 1:
                    logger.info('%s WINS!', players[state.playerTurn]['name'])
                    print('WINS!', players[state.playerTurn]['name'])
                    if player2.name.find(gameName) > -1:
                        if players[state.playerTurn]['name'] == player1.name:
                            Provider.addCompet(player1.name, player2.name,
                                               gameName, now, 1)
                        if players[state.playerTurn]['name'] == player2.name:
                            Provider.addCompet(player1.name, player2.name,
                                               gameName, now, 2)
                    else:
                        if players[state.playerTurn]['name'] == player1.name:
                            Provider.addCompetWithUser(player1.name,
                                                       player2.name, gameName,
                                                       now, 1)
                        if players[state.playerTurn]['name'] == player2.name:
                            Provider.addCompetWithUser(player1.name,
                                                       player2.name, gameName,
                                                       now, 2)
                    scores[players[state.playerTurn]['name']] = scores[players[
                        state.playerTurn]['name']] + 1

                    if state.playerTurn == 1:
                        sp_scores['sp'] = sp_scores['sp'] + 1

                    else:
                        sp_scores['nsp'] = sp_scores['nsp'] + 1

                elif value == -1:
                    logger.info('%s WINS!', players[-state.playerTurn]['name'])
                    print(' WINS!', players[-state.playerTurn]['name'])
                    if player2.name.find(gameName) > -1:
                        if players[-state.playerTurn]['name'] == player1.name:
                            Provider.addCompet(player1.name, player2.name,
                                               gameName, now, 2)
                        if players[-state.playerTurn]['name'] == player2.name:
                            Provider.addCompet(player1.name, player2.name,
                                               gameName, now, 1)
                    else:
                        if players[-state.playerTurn]['name'] == player1.name:
                            Provider.addCompetWithUser(player1.name,
                                                       player2.name, gameName,
                                                       now, 1)
                        if players[-state.playerTurn]['name'] == player2.name:
                            Provider.addCompetWithUser(player1.name,
                                                       player2.name, gameName,
                                                       now, 2)
                    scores[players[-state.playerTurn]['name']] = scores[
                        players[-state.playerTurn]['name']] + 1

                    if state.playerTurn == 1:
                        sp_scores['nsp'] = sp_scores['nsp'] + 1
                    else:
                        sp_scores['sp'] = sp_scores['sp'] + 1

                else:
                    logger.info('DRAW...')
                    print('DRAW...')
                    Provider.addCompet(player1.name, player2.name, gameName,
                                       now, 0)
                    scores['drawn'] = scores['drawn'] + 1
                    sp_scores['drawn'] = sp_scores['drawn'] + 1

                pts = state.score
                points[players[state.playerTurn]['name']].append(pts[0])
                points[players[-state.playerTurn]['name']].append(pts[1])

    return (scores, memory, points, sp_scores)
	def test_noMovesLeft_EmptyField_ReturnsFalse(self):
		game = Game()
		result = game.noMovesLeft()
		self.assertFalse(result)
	def test_validateInput_InputMoreThanTwoCharacters_ReturnsFalse(self):
		game = Game()
		result = game.validateInput("D43")
		self.assertFalse(result)
	def test_validateInput_RowInvalidNotABC_ReturnsFalse(self):
		game = Game()
		result = game.validateInput("D1")
		self.assertFalse(result)
Exemple #33
0
    print("Invalid file")
best = np.load(file_name + ".npy")

mf = np.vectorize(lambda x: 0.5 if x is None else float(x))
mlp = MLPClassifierOverride()
mlp.init_weights(best)
mlp.fit([[0.0] * 3 * 3 * 3, [0.0] * 3 * 3 * 3],
        [[0.1] * 3 * 3 * 3, [0.1] * 3 * 3 * 3])

message = "Do you want to be Crosses or Noughts [X/O]: "
human_is_cross = get_input(message, lambda x: x in ['x', 'o']) == 'x'

message = "Human starts or computer starts? [H/C]: "
human_move = get_input(message, lambda x: x in ['h', 'c']) == 'h'

game = Game(player1_first=human_move, player1_is_cross=human_is_cross)
while True:
    if (game.player1_move):
        game.print_boards()
        move_raw = get_input("Enter move seperated by spaces (board x y) ",
                             game.check_valid_move_string)
        move = list(map(int, move_raw.split()))
        board, x, y = move

        result = game.play(move)
    else:
        translate = mf(np.array(game.boards).flatten())
        moves = mlp.predict([translate])[0]
        moves = [z[1] for z in sorted([(x, i) for i, x in enumerate(moves)])]

        #print("Wat",moves)
Exemple #34
0
def run_game():
    """
        This function handles the game of the client/server program. The function first
        creates an object of Game which it will use to access the Game board and the
        class data members. Next the function creates sockets and makes connections and
        displays them. It then displays the current round number and then obtains the client's
        message. If the client had wanted to quit, then close sockets and end program. Otherwise,
        update client's move and check if game is over via win or draw and display the board. If
        the game is over, then send quit message to client and display output and close server.
        Otherwise get/validate input for the server's move and check if user wanted to quit.
        If the user wanted to quit server, let the client know and then close sockets and end
        program. Otherwise update the server's move on the board, send move to client and then
        check for game being over.
        :return:
        """
    player = Game()

    try:
        # learned how to create socket from: https://docs.python.org/3/howto/sockets.html
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # allow socket re-use - obtained from assignment PDF
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    except socket.error:
        print("Error creating socket! EXITING PROGRAM!!")
        sys.exit(1)

    else:
        # bind the socket
        s.bind((HOST, PORT))

        # listen for connections to server. only allowing one
        s.listen(1)

        # display server host and port
        print(f"Server listening on: {HOST} on port: {PORT}")

        while True:
            # create the connection to the client
            client_connection, client_address = s.accept()

            # verify connection details between server and client
            print(f"Connected by {client_address}")
            player.game_rules()

            # partially inspired from https://www.geeksforgeeks.org/socket-programming-python/
            # continue accepting connections while server code is running
            while True:
                # show current round number
                global ROUND
                print("\n")
                print("#" * 15 + f" ROUND: {ROUND} " + "#" * 15)

                # increment variable for next round number
                ROUND += 1

                print("\nWaiting for opponent's move...")

                try:
                    # call function to receive data from client
                    client_message = receive_data(client_connection)

                except socket.error:
                    print("Unable to receive data on this socket!")
                    sys.exit(1)

                else:

                    # if the client had chosen to quit then close sockets and end program
                    if client_message == '/q':
                        client_connection.close()
                        s.close()
                        sys.exit(0)

                    # otherwise update board to reflect opponents move and print it out
                    player.make_move(int(client_message), 'X')
                    player.show_board()

                    # check if game is over
                    player.check_game("  X  ")

                    # if the game is over then quit and close server
                    if player.game_over:
                        client_connection.close()
                        s.close()
                        sys.exit(0)

                    # otherwise prompt for and perform input validation
                    server_msg = validate_input(player)

                    # if server user had chosen to quit let client know & close sockets and end program
                    if server_msg == '/q':
                        send_data(client_connection, server_msg)
                        client_connection.close()
                        s.close()
                        sys.exit(0)

                    # update board to reflect player's move and print it out
                    player.make_move(int(server_msg), 'O')
                    player.show_board()

                    # check for a win
                    player.check_game("  O  ")

                    try:
                        # send the move over to the opponent
                        send_data(client_connection, server_msg)

                    except socket.error:
                        print("Unable to send data on this socket!")
                        sys.exit(1)

                    # if the game is over then quit and close server
                    if player.game_over:
                        client_connection.close()
                        s.close()
                        sys.exit(0)
	def test_checkNotEndGame_MovesLeftNoWin_returnsTrue(self):
		game = Game()
		result = game.checkNotEndGame(False, game.NoWin)
		self.assertTrue(result)
	def test_checkSquareIsOccupied_ItIs_ReturnsTrue(self):
		game = Game()
		game.addFirstPlayerMove("A1")
		result = game.checkSquareIsOccupied("A1")
		self.assertTrue(result)
	def test_addFirstPlayerMove_AddLegalMove_MoveHasBeenAddedToBoard(self):
		game = Game()
		game.addFirstPlayerMove("A1")
		self.assertTrue(game.checkSquareIsPlayer(game.FirstPlayer,"A1"))
	def test_askPlayerMove_FirstPlayerPassed_ReturnsFirstPlayer(self):
		game = Game()
		result = game.askPlayerMove(game.FirstPlayer)
		self.assertEqual(result, 'First player, make your move')
Exemple #39
0
 def test_check_game_we_have_run_out_of_moves(self):
     game = Game(dimensions=(6,6))
     game.move = 36
     with self.assertRaises(SystemExit) as cm:
         game.check_game_state()
     self.assertEqual(cm.exception.code, "It's a draw")
	def test_askPlayerMove_SecondPlayerPassed_ReturnsSecondPlayer(self):
		game = Game()
		result = game.askPlayerMove(game.SecondPlayer)
		self.assertEqual(result, 'Second player, make your move')
	def test_validateInput_ColumnInvalidTooLow_ReturnsFalse(self):
		game = Game()
		result = game.validateInput("A0")
		self.assertFalse(result)
	def test_nextPlayer_CurrentOneIsSecond_ReturnsFirst(self):
		game = Game()
		game.setInitialPlayer(game.SecondPlayer)
		game.nextPlayer()
		self.assertEqual(game.currentPlayer, game.FirstPlayer)
Exemple #43
0
class User:
    _ = dict()

    def __init__(self, id_, webs):
        self.id = id_
        self.ws = webs
        self.name = 'User'
        self.game = None
        self.players = None, None  # first player / second player
        self._[self.id] = self

    async def register(self, msg):
        if msg and msg.isalpha():
            self.name = msg.capitalize()
            await User.send_all(f"We have a new player {self.name}!",
                                pass_with_game=True,
                                user_to_pass=self)
            return True

    async def connect(self, msg):
        if msg == 'bot':
            self.game = Game()
            self.players = self, 0
            return True
        opponent = None
        for u in User._.values():
            if u.name.lower() == msg and not u.game:
                opponent = u
        if opponent:
            await opponent.send(
                f'You were invited to the game with {self.name}')
            self.game = opponent.game = Game()
            self.players = opponent.players = self, opponent
            return True

    async def answer(self, msg):
        if not self.game:
            ans = 'Who do you want to play with? Type their name or wait till someone invites you.\n' \
                  + await User.names_str()
            if not self.name or self.name == 'User':
                if await self.register(msg):
                    msg += '1'
                    ans += '-> ' + self.name + '\n'
                else:
                    ans = 'What is your name? Text only.'
            elif await self.connect(msg):
                ans = f'Successfully connected. Insert \'exit\' if you want leave the game.\n' \
                      f'Now make your first move (send a number from 1 to 9):'
        elif msg == 'exit':
            ans = await self.disconnect()
        else:
            ans = await self.game_answer(msg)
        return ans

    async def game_answer(self, msg):
        n = self.game.step % 2
        if self.players[n] != self:
            return 'Now we are waiting for your opponent to move!'
        waiting_player = self.players[abs(n - 1)]
        er = self.game.check_move_str(msg)
        if er:
            return er
        message = await self.game.move(int(msg) - 1)
        if waiting_player:
            await waiting_player.send(message + 'Your move:' if self.game
                                      and self.game.step % 2 != n else message)
        else:
            message += await self.game.move(
                self.game.smart_move(self.game.m, *self.game.sets[not n])
            ) + '\nYour move: '
        return message + 'Your move:' if waiting_player and self.game and self.game.step % 2 == n else message

    async def disconnect(self):
        opponent = self.players[int(not self.players.index(self))]
        if opponent:
            await User._disconnect(opponent)
            await opponent.send(f'{self.name} has escaped the game.')
        await User._disconnect(self)
        return 'You have escaped the game.'

    async def send(self, msg):
        if self.ws:
            try:
                await self.ws.send(msg)
            except:
                try:
                    opponent = self.players[int(not self.players.index(self))]
                    await User._disconnect(self)
                    if opponent:
                        await User._disconnect(opponent)
                        await opponent.ws.send(
                            f'We\'ve lost connection with {self.name}...')
                        User._.pop(self.id)
                except:
                    pass  # User._.pop(opponent.id)

    @staticmethod
    async def _disconnect(u):
        u.game = None
        u.players = None, None

    @staticmethod
    async def processing():
        while True:
            await User.send_all('ping')
            await asyncio.sleep(15)

    @staticmethod
    async def send_all(msg, pass_with_game=False, user_to_pass=None):
        try:
            for u in User._.values():
                if pass_with_game and u.game or user_to_pass and user_to_pass == u:
                    continue
                await u.send(msg)
        except:
            pass

    @staticmethod
    async def get(id_, ws=None):
        if id_ not in User._:
            User(id_, ws)
        u = User._[id_]
        if ws:
            u.ws = ws
        return u

    @staticmethod
    async def names_str():
        ans = 'Here you can see all our available for game users:\n'
        for u in User._.values():
            if u.game or not u.name or u.name == 'User':
                continue
            ans += '-> ' + u.name + ' \n'
        ans += '-> Bot \n'
        return ans
	def test_checkProblemsInput_ValidateTrueOccupiedFalse_returnsFalse(self):
		game = Game()
		result = game.checkProblemsInput(True, False)
		self.assertFalse(result)
Exemple #45
0
    (HumanPlayer(), BotPlayer(model=P2model)),
    # (BotPlayer(model=P1model), HumanPlayer())
]

games = 3

winlog = []

for match in lineup:
    P1 = match[0]
    P2 = match[1]

    print(P1.name() + ' vs ' + P2.name())

    for _ in range(games):
        game = Game(P1, P2)
        game.play(print_board=True, record_history=False)

        winlog.append([P1.name(), P2.name(), game.winner.nr])

winlog = pd.DataFrame(winlog, columns=['P1', 'P2', 'winner'])

results = winlog.groupby(
    by=['P1', 'P2', 'winner'])['winner'].count().to_frame('pc') / games
results = results.pivot_table(index=['P1', 'P2'],
                              columns='winner',
                              values='pc').reset_index()
results = results.rename(columns={0: 'Draw', 1: 'Win', 2: 'Lost'})

print(results)
	def test_checkProblemsInput_ValidateFalseOccupiedTrue_returnsTrue(self):
		game = Game()
		result = game.checkProblemsInput(False, False)
		self.assertTrue(result)
Exemple #47
0
 def setUp(self):
     self.game = Game("player 1", "player 2")
	def test_checkNotEndGame_MovesLeftWin_returnsFalse(self):
		game = Game()
		result = game.checkNotEndGame(False, game.FirstPlayerWin)
		self.assertFalse(result)
	def test_noMovesLeft_FullField_ReturnsTrue(self):
		game = Game()
		game.addFirstPlayerMove("A1")
		game.addFirstPlayerMove("A2")
		game.addFirstPlayerMove("A3")
		game.addFirstPlayerMove("B1")
		game.addFirstPlayerMove("B2")
		game.addFirstPlayerMove("B3")
		game.addFirstPlayerMove("C1")
		game.addFirstPlayerMove("C2")
		game.addFirstPlayerMove("C3")
		result = game.noMovesLeft()
		self.assertTrue(result)
Exemple #50
0
from tictactoe import Game
from agent import Agent
from graph import Graph

tests = int(input("Enter a number for number of tests: "))
num_of_iterations = int(input("Enter a number for amount of games to be played: "))
#grapher = Graph()
print("Playing %s games %s times...\n" % (num_of_iterations, tests)) 
for j in range(tests):
	print('Test number: %d\n\n' % (j+1))
	board = Game()
	board.play_agents(False, num_of_iterations)
	#grapher.y1 = board.play_agents(False, num_of_iterations)
	print("_______________________________\n")
	#play without turns
	board = Game()
	board.play_agents(True, num_of_iterations)
	#grapher.y2 = board.play_agents(False, num_of_iterations)
	print("______________________________________________________________\n")
#grapher.graph()
Exemple #51
0
from tictactoe.Game import *
import random

x_first = random.random() < .5
game = Game(X if x_first else O)


def minimax(game, i):
    if game.is_over() and not game.winner_exists():
        return 0
    if game.winner_exists():
        return 1 if game.get_winner() == O else -1
    valid_moves = game.valid_moves.copy().keys()
    best_move = next(iter(valid_moves))
    max_val = -10
    min_val = 10
    # keep history around for reminder(studying) purposes later :)
    history = []
    if i % 2 == 0:
        for m in valid_moves:
            game.make_move(m)
            next_move_val = minimax(game, i + 1)
            history.append((m, next_move_val))
            game.undo_move(m)
            if next_move_val > max_val:
                max_val = next_move_val
                best_move = m
                if next_move_val > 0:
                    break
    else:
        for m in valid_moves:
	def test_addFirstPlayerMove_IllegalMove_MoveHasBeenAddedToBoard(self):
		game = Game()
		game.addFirstPlayerMove("A1")
		result = game.addFirstPlayerMove("A1")
		self.assertEqual(result,'Square already occupied', 'Should have said the square was occupied')
Exemple #53
0
def run_game():
    """
    This function handles the game of the client/server program. The function first
    creates an object of Game which it will use to access the Game board and the
    class data members. Next the function creates sockets and makes connections and
    displays them. It then displays the current round number and validates input
    entered on the client side. If the quit command was entered the program will quit
    and let the server know to quit as well. Otherwise, the position is updated with
    the client's symbol, board is shown and the game is checked if a win occurred and will
    subsequently exit and let the server know to exit as well. Otherwise data is obtained from
    the server; checked if it needs to quit - otherwise make the move on the board for the server
    and check if a win occurred.
    :return:
    """
    player = Game()

    try:
        # learned how to create socket from: https://docs.python.org/3/howto/sockets.html
        # socket object creation
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # allow socket re-use - obtained from assignment PDF
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # handle errors creating sockets
    except socket.error:
        print("Error creating socket! EXITING PROGRAM!!")
        sys.exit(1)

    # if sockets were created successfully continue
    else:

        # handle any socket error exceptions
        try:
            # connect client to the server
            s.connect((HOST, 5500))

            # display successful connection
            print(f"Connected to:  {HOST} on port: {PORT}")
            player.game_rules()

            while True:
                # show current round number
                global ROUND
                print("\n")
                print("#" * 15 + f" ROUND: {ROUND} " + "#" * 15)

                # increment variable for next round
                ROUND += 1

                # prompt for and perform input validation
                client_message = validate_input(player)

                # call function to send data
                send_data(s, client_message)

                # if client chose to quit, shutdown sockets and end program
                if client_message == '/q':
                    s.close()
                    sys.exit(0)

                # update board to reflect player's move and display board
                player.make_move(int(client_message), 'X')
                player.show_board()

                # check if game is over
                player.check_game("  X  ")

                # if the game is over then close sockets and exit program
                if player.game_over:
                    s.close()
                    sys.exit(0)

                print("\nWaiting for opponent's move...")

                # call function to receive data
                server_reply = receive_data(s)

                # if server chose to quit, shutdown sockets and end program
                if server_reply == '/q':
                    s.close()
                    sys.exit(0)

                # update board to reflect opponent's move and display board
                player.make_move(int(server_reply), 'O')
                player.show_board()

                # check if game is over
                player.check_game("  O  ")

                # if the game is over then close sockets and exit program
                if player.game_over:
                    s.close()
                    sys.exit(0)

        # if the socket failed for any reason display error message, close socket, exit program with 1
        # create a tuple to hold the common errors. obtained this from my own Project 1 assignment.
        except (socket.herror, socket.herror, socket.timeout,
                RuntimeError) as error:
            print(
                f"ERROR: Program has failed due to a {type(error).__name__} error!"
            )
            s.close()
            sys.exit(1)
	def test_checkSquareIsOccupied_IsNot_ReturnsFalse(self):
		game = Game()
		result = game.checkSquareIsOccupied("A1")
		self.assertFalse(result)