Пример #1
0
    def play_against(self,
                     opponent: Player,
                     game: Connect4Game = Connect4Game()):
        """
        Make the agent play against another player on the given game or a new game.
        If both player have the same game turn id, self will change its game turn id
        Returns the winner
        :param opponent: another player
        :param game: The current game, if nothing specified then a new game
        :return: the winner (0 for draw, 1 for player 1, 2 for player 2
        """
        if self.player_turn_id == opponent.player_turn_id:
            self.player_turn_id = 3 - self.player_turn_id
        yellow_goes_first = game.get_turn() == 1
        winner = game.get_win()
        while winner is None:
            if game.get_turn() == self.player_turn_id:
                game.place(self.choose_action(game))
            else:
                game.place(opponent.choose_action(game))
            winner = game.get_win()

        if winner != 0 and not yellow_goes_first:
            winner = 3 - winner
        return winner
 def choose_action(self, game: Connect4Game):
     board = game.transform_board()[0]
     # Get the prediction
     prediction = self.forward_pass(board)
     # Remove full column
     prediction = [
         0 if game.board[i][-1] != 0 else prediction[0][i]
         for i in range(len(game.board))
     ]
     return np.argmax(prediction)
Пример #3
0
	async def play(self, ctx, *, player2: discord.Member):
		"""
		Play connect4 with another player
		"""
		player1 = ctx.message.author

		game = Connect4Game(
			player1.display_name,
			player2.display_name
		)

		message = await ctx.send(str(game))

		for digit in self.DIGITS:
			await message.add_reaction(digit)

		def check(reaction, user):
			return (
				user == (player1, player2)[game.whomst_turn()-1]
				and str(reaction) in self.VALID_REACTIONS
				and reaction.message.id == message.id
			)

		while game.whomst_won() == game.NO_WINNER:
			try:
				reaction, user = await self.bot.wait_for(
					'reaction_add',
					check=check,
					timeout=self.GAME_TIMEOUT_THRESHOLD
				)
			except asyncio.TimeoutError:
				game.forfeit()
				break

			await asyncio.sleep(0.2)
			try:
				await message.remove_reaction(reaction, user)
			except discord.errors.Forbidden:
				pass

			if str(reaction) == self.CANCEL_GAME_EMOJI:
				game.forfeit()
				break

			try:
				# convert the reaction to a 0-indexed int and move in that column
				game.move(self.DIGITS.index(str(reaction)))
			except ValueError:
				pass # the column may be full

			await message.edit(content=str(game))

		await self.end_game(game, message)
Пример #4
0
def get_random_hypothetical_game_history():
    """
    Constructs a game by making an agent play against himself (since he is random, his turn id
    doesn't matter)
    :return:
    """
    game = Connect4Game()
    player = RandomPlayer.RandomPlayer(3 - game.get_turn())
    while game.get_win() is None:
        placement = player.choose_action(game)
        if placement is not None:
            game.place(placement)
    return game.history
 def compute_fitness(self):
     """
     The fitness of one player is computed by making him play 10 times against a MinMaxPlayer
     :return:
     """
     player_score = 1  # Since this will be used for probabilities, no one should have a score of 0
     for i in range(10):
         game = Connect4Game()
         opponent = MinMaxPlayer(player_turn_id=3 - game.get_turn())
         winner = self.play_against(opponent, game)
         if winner == 0:  # Tie
             player_score += 50
         elif winner == self.player_turn_id:  # Won
             player_score += 100
     return player_score
Пример #6
0
def get_minmax_game_history(difficulty=2):
    """
    Constructs a game by making a minmax agent play against another minmax agent
    :param difficulty:
    :return:
    """
    game = Connect4Game()
    player_a = MinMaxPlayer.MinMaxPlayer(3 - game.get_turn())
    player_b = MinMaxPlayer.MinMaxPlayer(3 - player_a.player_turn_id)
    while game.get_win() is None:
        placement = player_a.choose_action(game, difficulty)
        game.place(placement)
        if game.get_win() is not None:
            break

        placement = player_b.choose_action(game, difficulty)
        game.place(placement)
    return game.history
Пример #7
0
def compute_fitness(player: Player.Player):
    """
    Compute the fitness of the agent. This is done by playing 10 times against a minmax player
    followed by 10 other games against a random player to differentiate agents with low but
    better than random reasoning
    :return: the score
    """
    game = Connect4Game()
    score = 1
    for _ in range(10):
        adversary = MinMaxPlayer.MinMaxPlayer(random.randint(1, 2))
        winner = player.play_against(adversary, game)
        if winner == player.player_turn_id:
            score += 1
    for _ in range(10):
        adversary = RandomPlayer.RandomPlayer(random.randint(1, 2))
        winner = player.play_against(adversary, game)
        if winner == player.player_turn_id:
            score += 1
    return score
 def choose_action(self, game: Connect4Game) -> int:
     best_substring = ""
     letter = None
     for gh_i in range(len(game.history)):
         for chromo in self.chromosomes:
             if chromo[-1] != str(game.get_turn()):
                 continue
             substring = game.history[gh_i:-2]
             index = chromo.rfind(substring)  # Search from the end
             # If we found the substring and is longer than the previous best
             # and that it is not the game outcome
             if index != -1 and len(substring) > len(best_substring):
                 best_substring = substring
                 letter = chromo[index + len(best_substring)].lower()
     # If nothing was found
     if letter is None or game.history.count(
             letter.lower()) + game.history.count(letter.upper()) >= 6:
         action = random.randint(0, 6)
     else:
         action = ord(letter) - ord("a")
     return action
        scores = scores + scores_2
        return scores / sum(scores)  # makes the total equals to 1


if __name__ == '__main__':
    MinMaxPlayer.MinMaxPlayer.difficulty = 2
    gen = Generation(20, 100, 1)
    best_player = None
    max_fitness = 0
    for player in gen.players:
        fitness = compute_fitness(player)
        if fitness > max_fitness:
            max_fitness = fitness
            best_player = player
    player = best_player
    game = Connect4Game()
    game.reset_game()
    view = Connect4Viewer(game=game)
    view.initialize()
    running = True
    while running:
        for i, event in enumerate(pygame.event.get()):
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                if game.get_win() is None:
                    placement = game.place(pygame.mouse.get_pos()[0] // SQUARE_SIZE)
                    if placement is None:  # Still player's turn if placement fails
                        continue
                    if game.get_win() is not None:
                        game.reset_game()
        else:
            action = ord(letter) - ord("a")
        return action


if __name__ == '__main__':
    # for h in [CombinatorialPlayer.get_random_hypothetical_game_history() for _ in range(10)]:
    #     print(h)
    #     board = Connect4Game.from_history(h)
    #     for col in board.board:
    #         print(col)
    #     print(board.get_win(), board.history)
    #
    # player = [CombinatorialPlayer(5), CombinatorialPlayer(5)]
    # board = Connect4Game.from_history("dAgDeAfFeBaDdCeBeAaAcDbFb")
    # player[0].choose_action(board)
    # new_player = CombinatorialPlayer.reproduce(player)
    # for p in player:
    #     print(p.chromosomes)
    # print(new_player.chromosomes)

    player_a = CombinatorialPlayer(24)
    player_b = CombinatorialPlayer(24)

    player_c = CombinatorialPlayer.reproduce((player_a, player_b))[0]
    history = "BfFaEdBeAgGaDbFgDdEcFaCaGcFcBcBaGgBdDfCeEe"
    board = Connect4Game.from_history(history)
    player_a.choose_action(board)
    player_b.choose_action(board)
    player_c.choose_action(board)