def test_col_win(self): connect_four = ConnectFour() connect_four.board = [ [1, 2, 1, 0, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], ] self.assertFalse(connect_four.col_win(PLAYER_1, 5, 0)) connect_four.board = [ [1, 2, 1, 1, 1, 1, 1], [1, 1, 2, 1, 2, 1, 1], [1, 2, 1, 2, 1, 2, 1], [1, 1, 2, 1, 2, 1, 1], [2, 1, 1, 1, 1, 1, 1], [2, 1, 2, 1, 2, 1, 1], ] self.assertTrue(connect_four.col_win(PLAYER_1, 0, 0)) self.assertTrue(connect_four.col_win(PLAYER_1, 1, 0)) self.assertTrue(connect_four.col_win(PLAYER_1, 2, 0)) self.assertTrue(connect_four.col_win(PLAYER_1, 3, 0)) self.assertTrue(connect_four.col_win(PLAYER_1, 0, 6)) self.assertTrue(connect_four.col_win(PLAYER_1, 1, 6)) self.assertTrue(connect_four.col_win(PLAYER_1, 2, 6)) self.assertTrue(connect_four.col_win(PLAYER_1, 3, 6)) self.assertTrue(connect_four.col_win(PLAYER_1, 4, 6)) self.assertTrue(connect_four.col_win(PLAYER_1, 5, 6))
def test_row_win(self): connect_four = ConnectFour() connect_four.board = [ [1, 2, 1, 0, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], ] #self.assertFalse(connect_four.row_win(PLAYER_1, 5, 0)) connect_four.board = [ [1, 2, 1, 1, 1, 1, 2], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 1, 1, 1, 1, 1, 1], [2, 1, 2, 1, 2, 1, 2], ] self.assertTrue(connect_four.row_win(PLAYER_1, 0, 3)) self.assertTrue(connect_four.row_win(PLAYER_1, 0, 2)) self.assertTrue(connect_four.row_win(PLAYER_1, 0, 4)) self.assertTrue(connect_four.row_win(PLAYER_1, 0, 5)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 0)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 1)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 2)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 3)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 4)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 5)) self.assertTrue(connect_four.row_win(PLAYER_1, 4, 6))
def test_game_draw(self): connect_four = ConnectFour() connect_four.board = [ [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], ] self.assertTrue(connect_four.is_game_draw()) self.assertEqual(connect_four.check_game_status(PLAYER_1, 1, 1), GAME_STATUS_DRAW)
def test_game_incomplete(self): connect_four = ConnectFour() connect_four.board = [ [1, 2, 1, 0, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], ] self.assertFalse(connect_four.is_game_draw()) self.assertEqual(connect_four.check_game_status(PLAYER_1, 1, 1), GAME_INCOMPLETE)
def activate(self, inputs): game = ConnectFour._createFromState(inputs) possibles = game.possibleMoves() return [ random.random() if index in possibles else 0.0 for index in range(0, 7) ]
def simulateGame(player, opponent): # Returns fitness delta game = ConnectFour() illegal_moves = 0 random_moves_left = 3 while not game.isFinished(): # TODO track stats? if game.isOurTurn(): try: pickAndMakeMove(game, player) except IndexError: illegal_moves += 1 if illegal_moves >= NUMBER_ILLEGAL_MOVES_ALLOWED: # Penalise player return -NUMBER_TO_SAMPLE else: continue if game.isFinished(): break if random_moves_left > 0: pickAndMakeMove(game, agents.RandomAgent()) random_moves_left -= 1 else: try: pickAndMakeMove(game, opponent) except IndexError: pickAndMakeMove(game, agents.RandomAgent()) else: # Not our turn if random_moves_left > 0: pickAndMakeMove(game, agents.RandomAgent()) random_moves_left -= 1 else: try: pickAndMakeMove(game, opponent) except IndexError: pickAndMakeMove(game, agents.RandomAgent()) if game.isFinished(): break try: pickAndMakeMove(game, player) except IndexError: illegal_moves += 1 if illegal_moves >= NUMBER_ILLEGAL_MOVES_ALLOWED: # Penalise player return -NUMBER_TO_SAMPLE else: continue # Game is finished (or illegal move made) # TODO debug prints, or stats return game.score()
def player_vs_player_statistics(n=100): """Run n games with player vs itself.""" wins = [0, 0] draws = 0 for i in range(n): winner = ConnectFour.play(players.MinimaxPlayer, players.MinimaxPlayer, verbose=False, difficulty=6) if winner == -1: draws += 1 else: wins[winner] += 1 logger.info(f'Negamax wins={wins[0]} random player wins={wins[1]} draws={draws}')
def monte_carlo_vs_random_statistics(n=100): wins = [0, 0] draws = 0 for i in range(n): print(f'Game #{i}') winner = ConnectFour.play(players.MonteCarloPlayer, players.RandomPlayer, verbose=False) if winner == -1: draws += 1 else: wins[winner] += 1 print(f"MonteCarlo won {wins[0]} times while Random won {wins[1]} times")
def activate(self, inputs): game = ConnectFour._createFromState(inputs) winners = game._almostWinners() possibles = game.possibleMoves() moves = [ random.random() if index in possibles and winners[index] is None else 0.0 for index in range(0, 9) ] if moves.count(0.0) == 9: return [ random.random() if index in possibles else 0.0 for index in range(0, 9) ] return moves
def monte_carlo_vs_negamax_statistics(n=100, difficulty=5, games=500): filename = Path(f'monte_carlo_minimax_diff{difficulty}_games{games}') if filename.exists(): with filename.open('r') as f: wins = json.load(f) else: wins = [0, 0] for i in range(n): # print(f'Game #{i}') winner = ConnectFour.play(players.MonteCarloPlayer, players.MinimaxPlayer, verbose=False, difficulty=difficulty, games=games) wins[winner] += 1 with filename.open('w') as f: json.dump(wins, f) print(f"MonteCarlo won {wins[0]} times while Minimax won {wins[1]} times")
from __future__ import print_function import pickle # pip install cloudpickle import os import sys from game import ConnectFour import agents from utilities import pickMove, pickAndMakeMove game = ConnectFour() if len(sys.argv) >= 2: print("Using opponent from {}".format(sys.argv[1])) with open(sys.argv[1], 'rb') as output: opponent = pickle.load(output) else: print("Using random agent") opponent = agents.RandomAgent() while not game.isFinished(): if game.isOurTurn(): print(game) possibles = game.possibleMoves() column = input("Which column {}? ".format(possibles)) try: game.playMove(int(column)) except Exception as e: print("error occurred", e) else: try: pickAndMakeMove(game, opponent)
def test_horizontal_win_down(self): connect_four = ConnectFour() connect_four.board = [ [1, 2, 1, 0, 1, 2, 1], [1, 2, 1, 0, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 0, 1, 2, 1], [1, 2, 1, 0, 1, 2, 1], ] self.assertFalse(connect_four.horizontal_win_down(PLAYER_1, 5, 0)) connect_four.board = [ [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], ] self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 0, 0)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 1, 1)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 2, 2)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 3, 3)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 4, 4)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 5, 5)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 0, 1)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 1, 2)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 2, 3)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 3, 4)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 4, 5)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 5, 6)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 0, 2)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 1, 3)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 2, 4)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 3, 5)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 4, 6)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 0, 3)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 1, 4)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 2, 5)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 3, 6)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 1, 0)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 2, 1)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 3, 2)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 4, 3)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_2, 5, 4)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 2, 0)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 3, 1)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 4, 2)) self.assertTrue(connect_four.horizontal_win_down(PLAYER_1, 5, 3))
parser = argparse.ArgumentParser(description='Play connect four.') parser.add_argument('--player1', type=str, dest='player1', default='computer', help='one of: computer, human, random.') parser.add_argument('--player2', type=str, dest='player2', default='human', help='one of: computer, human, random.') parser.add_argument('--difficulty', dest='difficulty', type=int, default=5, help='the computer player difficulty, notice that difficulty 6 and above takes a lot of time ' 'to evaluate.') parser.add_argument('--games', dest='games', type=int, default=500, help='the amount of games per turn that the monte_carlo agents will play.') args = parser.parse_args() return args if __name__ == '__main__': args = parse_cli_arguments() p1 = players.PLAYERS[args.player1] p2 = players.PLAYERS[args.player2] ConnectFour.play(p1, p2, difficulty=args.difficulty, number_of_games=args.games) # player_vs_random_statistics(n=10000)
def activate(self, inputs): game = ConnectFour._createFromState(inputs) winners = game._almostWinners()
def __init__(self): self.__window = Tk() self.__window.title('Connect-Four!') self.__window.config(background='black') self.__buttonColumn1 = Button(self.__window, text='1', width=8, command=lambda: self.__column(0)).grid( row=0, column=1, sticky=E) self.__buttonColumn2 = Button(self.__window, text='2', width=8, command=lambda: self.__column(1)).grid( row=0, column=2, sticky=E) self.__buttonColumn3 = Button(self.__window, text='3', width=8, command=lambda: self.__column(2)).grid( row=0, column=3, sticky=E) self.__buttonColumn4 = Button(self.__window, text='4', width=8, command=lambda: self.__column(3)).grid( row=0, column=4, sticky=E) self.__buttonColumn5 = Button(self.__window, text='5', width=8, command=lambda: self.__column(4)).grid( row=0, column=5, sticky=E) self.__buttonColumn6 = Button(self.__window, text='6', width=8, command=lambda: self.__column(5)).grid( row=0, column=6, sticky=E) self.__buttonColumn7 = Button(self.__window, text='7', width=8, command=lambda: self.__column(6)).grid( row=0, column=7, sticky=E) self.__buttonHelp = Button(self.__window, text='Help', width=10, command=self.__help).grid(row=0, column=12, sticky=E) for i in range(0, 6): for j in range(0, 7): self.__output = Text(self.__window, width=8, height=4, wrap=WORD, background='white') self.__output.grid(row=i + 1, column=j + 1, columnspan=1, sticky=W) self.__outputConsole = Text(self.__window, width=20, height=25, wrap=WORD, background='white') self.__outputConsole.grid(row=1, column=12, rowspan=7, sticky=W) ConnectFour.__init__(self, '1')