def test_policy_with_heuristic(self): board_size = (3, 3) def heuristic(board_state, max_score, min_score, is_max): return -min_score players = { "p1": dnbpy.Level3MinimaxPolicy(board_size, 3, random_state=0, heuristic=heuristic), "p2": dnbpy.Level2HeuristicPolicy(board_size, random_state=0) } game = dnbpy.Game(board_size, ["p1", "p2"]) while not game.is_finished(): current_player = game.get_current_player() opp_player = "p2" if current_player == "p1" else "p1" edge = players[current_player].select_edge( game.get_board_state(), game.get_score(current_player), game.get_score(opp_player)) game.select_edge(edge, current_player) self.assertEqual(5, game.get_score("p1")) self.assertEqual(4, game.get_score("p2"))
def test_random_vs_level2(self): board_size = (2, 2) players = { 0: dnbpy.RandomPolicy(random_state=0), 1: dnbpy.Level2HeuristicPolicy(board_size, random_state=0) } result = dnbpy.duel(board_size, players) self.assertEqual({'lost': 3, 'won': 19, 'tied': 2}, result[1]) board_size = (3, 3) players = { 0: dnbpy.RandomPolicy(random_state=0), 1: dnbpy.Level2HeuristicPolicy(board_size, random_state=0) } result = dnbpy.duel(board_size, players) self.assertEqual({'lost': 0, 'won': 48, 'tied': 0}, result[1])
def test_level2_vs_level3_variable_depth(self): board_size = (3, 3) players = { 0: dnbpy.Level2HeuristicPolicy(board_size, random_state=0), 1: dnbpy.Level3MinimaxPolicy(board_size, random_state=0) } result = dnbpy.duel(board_size, players) self.assertEqual({'tied': 0, 'lost': 7, 'won': 41}, result[1])
def test_level2_vs_level3update_alpha(self): board_size = (3, 3) players = { 0: dnbpy.Level2HeuristicPolicy(board_size, random_state=0), 1: dnbpy.Level3MinimaxPolicy(board_size, 3, random_state=0, update_alpha=True) } result = dnbpy.duel(board_size, players) self.assertEqual({'tied': 0, 'lost': 13, 'won': 35}, result[1])
def test_select_edge(self): policy = dnbpy.Level2HeuristicPolicy(board_size=(3, 3)) """ *---------*---------*---------* | | | $L2 | 5 6 | | *---------*---------* 9 * | 10 11 12 | | *---------* 15 * 16 * | 17 18 19 | | * 21 * 22 *---------* """ board_state = [ 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1 ] edge = policy.select_edge(board_state) self.assertEqual(5, edge) """ *---------*---------*---------* | | | | $L2 | $L2 | 6 | | | *---------*---------* 9 * | 10 11 12 | | *---------* 15 * 16 * | 17 18 19 | | * 21 * 22 *---------* """ board_state = [ 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1 ] edge = policy.select_edge(board_state) self.assertTrue(edge not in [6, 9, 10, 11, 16, 19])
def test_policy_with_no_depth(self): board_size = (3, 3) players = { "p1": dnbpy.Level3MinimaxPolicy(board_size, random_state=0), "p2": dnbpy.Level2HeuristicPolicy(board_size, random_state=0) } game = dnbpy.Game(board_size, ["p1", "p2"]) while not game.is_finished(): current_player = game.get_current_player() opp_player = "p2" if current_player == "p1" else "p1" edge = players[current_player].select_edge( game.get_board_state(), game.get_score(current_player), game.get_score(opp_player)) game.select_edge(edge, current_player) self.assertEqual(7, game.get_score("p1")) self.assertEqual(2, game.get_score("p2"))
def play(): print("DNBPy - Play") num_players = int(input("How many players?: ")) if num_players < 2: print("Error: there must be at least two players") sys.exit(0) players = [] for n in range(num_players): player = input("player {} name: ".format(n + 1)) players.append(player) if len(set(players)) == 1: print("Error: player names must be unique") sys.exit(0) board_rows = int(input("Number of board rows: ")) if board_rows < 1: print("Error: there must be at least one row") sys.exit(0) board_cols = int(input("Number of board columns: ")) if board_cols < 1: print("Error: there must be at least one column") sys.exit(0) minimax_depth = None if "$L3" in players: val = input("Minimax depth (leave empty for variable depth): ") if len(val.strip()) > 0: minimax_depth = int(val) if minimax_depth < 1: print("Error: minimax depth must be greater than 0") sys.exit(0) num_playouts = 100 if "$mcts" in players: num_playouts = int(input("Number of playouts: ")) if num_playouts < 1: print("Error: number of playouts must be greater than 0") sys.exit(0) print("preparing game...") board_size = (board_rows, board_cols) game = dnbpy.Game(board_size, players) print(game) computer_players = { "$random": dnbpy.RandomPolicy(), "$L1": dnbpy.Level1HeuristicPolicy(board_size=board_size), "$L2": dnbpy.Level2HeuristicPolicy(board_size=board_size), "$L3": dnbpy.Level3MinimaxPolicy(board_size=board_size, depth=minimax_depth, update_alpha=True), "$mcts": dnbpy.MCTSPolicy(board_size=board_size, num_playouts=num_playouts) } while not game.is_finished(): current_player = game.get_current_player() if current_player in computer_players: # get the first player that isn't the current player opp_player = [p for p in players if p != current_player][0] move = computer_players[current_player].select_edge( game.get_board_state(), game.get_score(current_player), game.get_score(opp_player)) game.select_edge(move, current_player) print("player %s selects edge %s" % (current_player, move)) else: try: move = int( input("{} select your move: ".format(current_player))) game.select_edge(move, current_player) except Exception: print("illegal move selection.. select again") print(game)