def setUp(self): self.game = oni.Game( [oni.TIGER, oni.TIGER, oni.TIGER, oni.TIGER, oni.TIGER]) self.ai = ai.create_ai(version='unmove', game=self.game) self.ai.set_game_as_root(self.game) self.ai2 = ai.create_ai(version='copy') self.ai2.set_game_as_root(self.game)
def test_negamax(self): game = oni.Game( [oni.TIGER, oni.MONKEY, oni.CRAB, oni.BOAR, oni.MANTIS]) self.ai.set_game_as_root(game) score = self.ai.negamax(node=self.ai.root, depth=5) curr = self.ai.root # Climb down our generated search tree to verify # the correctness of negamax for i in range(5): curr = max(curr.children, key=lambda x: -x.eval) sign = -1 if i % 2 == 0 else 1 self.assertEqual(score, sign * curr.eval)
def test_set_root(self): for card in oni.ALL_CARDS: game = oni.Game([card] * 5) self.ai.set_game_as_root(game) self.ai2.set_game_as_root(game) if game.active_player.color() == 'red': start_player = ai.RED elif game.active_player.color() == 'blue': start_player = ai.BLUE else: raise Exception self.assertEqual(start_player, self.ai.active_player) self.assertEqual(card.name(), self.ai.card_data[0].name) moves = self.ai2.next_moves(self.ai2.root) for move in moves: self.assertEqual(start_player, move.player)
def test_alphabeta(self): game = oni.Game( [oni.TIGER, oni.MONKEY, oni.CRAB, oni.BOAR, oni.MANTIS]) self.ai.set_game_as_root(game) score = self.ai.alphabeta( alpha=-float('inf'), beta=float('inf'), depth=4, node=self.ai.root, ) curr = self.ai.root path = [curr] for i in range(4): children = [node for node in curr.children if node.eval != None] curr = max(children, key=lambda x: -x.eval) path.append(curr) nega_score = self.ai.negamax(node=self.ai.root, depth=4) curr = self.ai.root nega_path = [curr] for i in range(4): curr = max(curr.children, key=lambda x: -x.eval) nega_path.append(curr) self.assertEqual(score, nega_score) def equal(move1, move2): if move1 is None: return move2 is None elif move2 is None: return move1 is None else: for attr in move1.__slots__: if not getattr(move1, attr) == getattr(move2, attr): return False return True for i in range(5): if path[i].prev_move is None: self.assertTrue(nega_path[i].prev_move is None) elif nega_path[i].prev_move is None: self.assertTrue(path[i].prev_move is None) else: self.assertTrue( equal(path[i].prev_move, nega_path[i].prev_move)) move = self.ai.find_move(depth=3)
def test_mobility_eval(self): game = oni.Game( [oni.TIGER, oni.MONKEY, oni.CRAB, oni.BOAR, oni.MANTIS]) self.ai.set_game_as_root(game) eval = get_evaluator(self.ai) eval.true_mobility_factor = 2.0 # 5 moves for TIGER # 8 moves for MONKEY # 5 moves for CRAB # 5 moves for BOAR # 8 moves for MANTIS # RED: 2*13 + 5+5+8 = 44 # BLUE: 2*10 + 5+8+8 = 41 self.assertEqual(eval.mobility(), 3.0) eval.pawn_weight, eval.mobility_weight = 1, 1 self.assertEqual(eval.evaluate(RED), 3.0) self.assertEqual(eval.evaluate(BLUE), -3.0)
import onitama as oni import timeit import sys import ai game = oni.Game(start_cards=oni.ALL_CARDS[0:5]) ai_copy = ai.create_ai('copy', game) ai_unmove = ai.create_ai('unmove', game) depth = int(sys.argv[1]) def compute(): ai_copy.mock_search(depth=depth, mode=sys.argv[2]) def compute2(): ai_unmove.mock_search(depth=depth) time = timeit.timeit(stmt=compute, number=1) print('{} seconds'.format(time)) time2 = timeit.timeit(stmt=compute2, number=1) print('{} seconds'.format(time2)) nodes = 0 nodes2 = 0 for i in range(depth+1): nodes += len(ai_copy.get_nodes(i)) nodes2 += len(ai_unmove.get_nodes(i)) print('{} nodes'.format(nodes)) print('{} kilonodes/s'.format(nodes/time/1000))
def new_game(self): cards = random.sample(oni.ALL_CARDS, 5) game = oni.Game(cards) self.set_game(game=game, user=oni.Player.RED)