def test_random_possible_hands(self): d1 = dominoes.Domino(0, 0) d2 = dominoes.Domino(1, 2) d3 = dominoes.Domino(3, 4) d4 = dominoes.Domino(5, 6) g = dominoes.Game.new() g.hands = [ dominoes.Hand([d1, d1]), dominoes.Hand([d2, d3]), dominoes.Hand([d1, d1]), dominoes.Hand([d4]) ] g.make_move(d1, True) g.make_move(d1, True) # there is a small chance that this assertion will fail, if any of # the 3 possible hands does not get generated in the 100 attempts. self.assertEqual( { tuple(frozenset(h) for h in g.random_possible_hands()) for _ in range(100) }, {(frozenset([d1]), frozenset([d3, d4]), frozenset( [d1]), frozenset([d2])), (frozenset([d1]), frozenset([d2, d4]), frozenset( [d1]), frozenset([d3])), (frozenset([d1]), frozenset([d2, d3]), frozenset( [d1]), frozenset([d4]))})
def test_all_possible_hands(self): d1 = dominoes.Domino(0, 0) d2 = dominoes.Domino(1, 2) d3 = dominoes.Domino(3, 4) d4 = dominoes.Domino(5, 6) g = dominoes.Game.new() g.hands = [ dominoes.Hand([d1, d1]), dominoes.Hand([d2, d3]), dominoes.Hand([d1, d1]), dominoes.Hand([d4]) ] g.make_move(d1, True) g.make_move(d1, True) self.assertEqual( { tuple(frozenset(h) for h in phs) for phs in g.all_possible_hands() }, {(frozenset([d1]), frozenset([d3, d4]), frozenset( [d1]), frozenset([d2])), (frozenset([d1]), frozenset([d2, d4]), frozenset( [d1]), frozenset([d3])), (frozenset([d1]), frozenset([d2, d3]), frozenset( [d1]), frozenset([d4]))})
def test_omniscient(self): # game cannot have ended after 6 fixed moves. self._test_player_interface(dominoes.players.omniscient(), 6) self.assertEqual( dominoes.players.omniscient(name='test').__name__, 'test') self.assertEqual(dominoes.players.omniscient().__name__, 'omniscient') cp1 = dominoes.players.counter() op1 = dominoes.players.omniscient(start_move=1, player=cp1) g1 = dominoes.Game.new() op1(g1) self.assertEqual(cp1.count, 0) # due to passes, the amount of total moves will be greater # than or equal to 6 after playing 6 fixed moves. therefore, # the following will not test the boundary condition every time. # this test suite gets run often enough that the danger is negligible. cp2 = dominoes.players.counter() op2 = dominoes.players.omniscient(start_move=6, player=cp2) while True: g2 = dominoes.Game.new() for _ in range(6): g2.make_move(*g2.valid_moves[0]) # the omniscient player is smart enough not # to run when there is only one valid move. if len(g2.valid_moves) > 1: break op2(g2) self.assertNotEqual(cp2.count, 0) d1 = dominoes.Domino(7, 0) d2 = dominoes.Domino(0, 0) d3 = dominoes.Domino(0, 1) d4 = dominoes.Domino(0, 8) d5 = dominoes.Domino(1, 9) h1 = dominoes.Hand([d1, d2]) h2 = dominoes.Hand([d3, d2]) h3 = dominoes.Hand([d3, d4, d5]) h4 = dominoes.Hand([d2]) g3 = dominoes.Game.new(starting_player=0) g3.hands = [h1, h2, h3, h4] g3.make_move(d1, True) op3 = dominoes.players.omniscient() self.assertEqual(g3.valid_moves, ((d3, False), (d2, False))) op3(g3) self.assertEqual(g3.valid_moves, ((d2, False), (d3, False)))
def test_init(self): h1 = dominoes.Hand([]) self.assertIsNotNone(h1) d = dominoes.Domino(1, 2) h2 = dominoes.Hand([d]) self.assertIsNotNone(h2)
def test_len(self): h1 = dominoes.Hand([]) self.assertEqual(len(h1), 0) d = dominoes.Domino(1, 2) h2 = dominoes.Hand([d]) self.assertEqual(len(h2), 1)
def test_remaining_points(self): h1 = [] self.assertEqual(dominoes.game._remaining_points(h1), []) d1 = dominoes.Domino(0, 1) d2 = dominoes.Domino(1, 3) d3 = dominoes.Domino(3, 6) h2 = [dominoes.Hand([]), dominoes.Hand([d1]), dominoes.Hand([d2, d3])] self.assertEqual(dominoes.game._remaining_points(h2), [0, 1, 13])
def test_contains_value(self): self.assertFalse(dominoes.hand.contains_value(dominoes.Hand([]), 0)) d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(3, 3) h = dominoes.Hand([d1, d2]) self.assertFalse(dominoes.hand.contains_value(h, 0)) self.assertTrue(dominoes.hand.contains_value(h, 1)) self.assertTrue(dominoes.hand.contains_value(h, 2)) self.assertTrue(dominoes.hand.contains_value(h, 3))
def test_repr(self): h1 = dominoes.Hand([]) self.assertEqual(repr(h1), '') d1 = dominoes.Domino(1, 2) h2 = dominoes.Hand([d1]) self.assertEqual(repr(h2), '[1|2]') d2 = dominoes.Domino(1, 3) h3 = dominoes.Hand([d1, d2]) self.assertEqual(repr(h3), '[1|2][1|3]')
def test_eq(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) h1 = dominoes.Hand([]) h2 = dominoes.Hand([]) h3 = dominoes.Hand([d1]) h4 = dominoes.Hand([d1]) h5 = dominoes.Hand([d2]) h6 = dominoes.Hand([d1, d2]) h7 = dominoes.Hand([d1, d2]) h8 = dominoes.Hand([d2, d1]) self.assertEqual(h1, h2) self.assertEqual(h3, h4) self.assertEqual(h6, h7) self.assertNotEqual(h1, h3) self.assertNotEqual(h3, h5) self.assertNotEqual(h5, h6) self.assertNotEqual(h6, h8) class PseudoHand: def __init__(self, _dominoes): self._dominoes = _dominoes ph1 = PseudoHand([]) ph2 = PseudoHand([d1]) ph3 = PseudoHand([d1, d2]) self.assertNotEqual(h1, ph1) self.assertNotEqual(h3, ph2) self.assertNotEqual(h6, ph3)
def _randomized_hands(): ''' :return: 4 hands, obtained by shuffling the 28 dominoes used in this variation of the game, and distributing them evenly ''' all_dominoes = [ dominoes.Domino(i, j) for i in range(7) for j in range(i, 7) ] random.shuffle(all_dominoes) return [ dominoes.Hand(all_dominoes[0:7]), dominoes.Hand(all_dominoes[7:14]), dominoes.Hand(all_dominoes[14:21]), dominoes.Hand(all_dominoes[21:28]) ]
def test_update_valid_moves(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(2, 3) p = 3 g = dominoes.Game.new(starting_player=p) g.board.add(d1, True) h = dominoes.Hand([d1, d2]) g.hands[p] = h g._update_valid_moves() # left end of board != right end of board self.assertEqual(len(g.valid_moves), 3) self.assertTrue((d1, True) in g.valid_moves) self.assertTrue((d1, False) in g.valid_moves) self.assertTrue((d2, False) in g.valid_moves) g.board.add(d1, True) g._update_valid_moves() # left end of board == right end of board self.assertEqual(len(g.valid_moves), 2) self.assertTrue((d1, True) in g.valid_moves) self.assertTrue((d2, True) in g.valid_moves)
def test_domino_hand(self): d1 = dominoes.Domino(1, 1) d2 = dominoes.Domino(1, 2) d3 = dominoes.Domino(1, 3) d4 = dominoes.Domino(1, 4) d5 = dominoes.Domino(1, 5) h1 = dominoes.Hand([d1, d2]) h2 = dominoes.Hand([d3, d4]) hands = [h1, h2] self.assertEqual(dominoes.game._domino_hand(d1, hands), 0) self.assertEqual(dominoes.game._domino_hand(d4, hands), 1) self.assertRaises(dominoes.NoSuchDominoException, dominoes.game._domino_hand, d5, hands)
def test_getitem(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) h = dominoes.Hand([d1, d2]) self.assertEqual(h[0], d1) self.assertEqual(h[1], d2)
def test_contains(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) h = dominoes.Hand([d1]) self.assertTrue(d1 in h) self.assertFalse(d2 in h)
def test_validate_hands(self): d1 = dominoes.Domino(0, 0) d2 = dominoes.Domino(1, 2) d3 = dominoes.Domino(3, 4) d4 = dominoes.Domino(5, 6) hs = [ dominoes.Hand([d1, d2]), dominoes.Hand([d3]), dominoes.Hand([d4]), dominoes.Hand([]) ] self.assertTrue(dominoes.game._validate_hands(hs, [set()] * 4)) self.assertTrue(dominoes.game._validate_hands(hs, [{3}, {5}, {7}, {1}])) self.assertFalse(dominoes.game._validate_hands(hs, [{0}] + [set()] * 3))
def test_draw(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) d3 = dominoes.Domino(1, 4) d4 = dominoes.Domino(1, 5) h = dominoes.Hand([]) self.assertEqual(len(h), 0) self.assertFalse(d1 in h) self.assertFalse(d2 in h) self.assertFalse(d3 in h) self.assertFalse(d4 in h) self.assertIsNone(h.draw(d1)) self.assertEqual(len(h), 1) self.assertEqual(h[0], d1) self.assertTrue(d1 in h) self.assertFalse(d2 in h) self.assertFalse(d3 in h) self.assertFalse(d4 in h) self.assertIsNone(h.draw(d2, 0)) self.assertEqual(len(h), 2) self.assertEqual(h[0], d2) self.assertEqual(h[1], d1) self.assertTrue(d1 in h) self.assertTrue(d2 in h) self.assertFalse(d3 in h) self.assertFalse(d4 in h) self.assertIsNone(h.draw(d3, 1)) self.assertEqual(len(h), 3) self.assertEqual(h[0], d2) self.assertEqual(h[1], d3) self.assertEqual(h[2], d1) self.assertTrue(d1 in h) self.assertTrue(d2 in h) self.assertTrue(d3 in h) self.assertFalse(d4 in h) self.assertIsNone(h.draw(d4)) self.assertEqual(len(h), 4) self.assertEqual(h[0], d2) self.assertEqual(h[1], d3) self.assertEqual(h[2], d1) self.assertEqual(h[3], d4) self.assertTrue(d1 in h) self.assertTrue(d2 in h) self.assertTrue(d3 in h) self.assertTrue(d4 in h)
def test_missing_values(self): g = dominoes.Game.new() self.assertEqual(g.missing_values(), [set()] * 4) d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(3, 4) d3 = dominoes.Domino(5, 6) d4 = dominoes.Domino(7, 8) h1 = dominoes.Hand([d1, d1]) h2 = dominoes.Hand([d2]) h3 = dominoes.Hand([d3]) h4 = dominoes.Hand([d4]) g.hands = [h1, h2, h3, h4] g.make_move(d1, True) self.assertEqual(g.missing_values(), [set()] + [{1, 2}] * 3)
def all_possible_hands(self): ''' Yields all possible hands for all players, given the information known by the player whose turn it is. This information includes the current player's hand, the sizes of the other players' hands, and the moves played by every player, including the passes. :yields: a list of possible Hand objects, corresponding to each player ''' # compute values that must be missing from # each hand, to rule out impossible hands missing = self.missing_values() # get the dominoes that are in all of the other hands. note that, even # though we are 'looking' at the other hands to get these dominoes, we # are not 'cheating' because these dominoes could also be computed by # subtracting the dominoes that have been played (which are public # knowledge) and the dominoes in the current player's hand from the # initial set of dominoes other_dominoes = { d for p, h in enumerate(self.hands) for d in h if p != self.turn } # get the lengths of all the other hands, so # that we know how many dominoes to place in each other_hand_lengths = [ len(h) for p, h in enumerate(self.hands) if p != self.turn ] # iterate over all possible hands that the other players might have for possible_hands in _all_possible_partitionings( other_dominoes, other_hand_lengths): # given possible hands for all players, this is a generator for # tuples containing the dominoes that are in the other players' hands possible_hands = (h for h in possible_hands) # build a list containing possible hands for all players. since we # know the current player's hand, we just use a shallow copy of it hands = [] for player, hand in enumerate(self.hands): if player != self.turn: hand = next(possible_hands) hands.append(dominoes.Hand(hand)) # only yield the hands if they are possible, according # to the values we know to be missing from each hand if _validate_hands(hands, missing): yield hands
def random_possible_hands(self): ''' Returns random possible hands for all players, given the information known by the player whose turn it is. This information includes the current player's hand, the sizes of the other players' hands, and the moves played by every player, including the passes. :return: a list of possible Hand objects, corresponding to each player ''' # compute values that must be missing from # each hand, to rule out impossible hands missing = self.missing_values() # get the dominoes that are in all of the other hands. note that, even # though we are 'looking' at the other hands to get these dominoes, we # are not 'cheating' because these dominoes could also be computed by # subtracting the dominoes that have been played (which are public # knowledge) and the dominoes in the current player's hand from the # initial set of dominoes other_dominoes = [ d for p, h in enumerate(self.hands) for d in h if p != self.turn ] while True: # generator for a shuffled shallow copy of other_dominoes shuffled_dominoes = ( d for d in random.sample(other_dominoes, len(other_dominoes))) # generate random hands by partitioning the shuffled dominoes according # to how many dominoes need to be in each of the other hands. since we # know the current player's hand, we just use a shallow copy of it hands = [] for player, hand in enumerate(self.hands): if player != self.turn: hand = [next(shuffled_dominoes) for _ in hand] hands.append(dominoes.Hand(hand)) # only return the hands if they are possible, according to the values we # know to be missing from each hand. if the hands are not possible, try # generating random hands again if _validate_hands(hands, missing): return hands
def test_play(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) d3 = dominoes.Domino(1, 4) h = dominoes.Hand([d1, d2, d3]) self.assertEqual(len(h), 3) self.assertTrue(d1 in h) self.assertTrue(d2 in h) self.assertTrue(d3 in h) self.assertEqual(h.play(d3), 2) self.assertEqual(len(h), 2) self.assertTrue(d1 in h) self.assertTrue(d2 in h) self.assertFalse(d3 in h) self.assertRaises(dominoes.NoSuchDominoException, h.play, d3) self.assertEqual(len(h), 2) self.assertTrue(d1 in h) self.assertTrue(d2 in h) self.assertFalse(d3 in h) self.assertEqual(h.play(d1), 0) self.assertEqual(len(h), 1) self.assertFalse(d1 in h) self.assertTrue(d2 in h) self.assertFalse(d3 in h) self.assertEqual(h.play(d2), 0) self.assertEqual(len(h), 0) self.assertFalse(d1 in h) self.assertFalse(d2 in h) self.assertFalse(d3 in h)
def __deepcopy__(self, _): if isinstance(self.board, dominoes.SkinnyBoard): if self.board: # SkinnyBoard attributes are ints; no need to deepcopy board = dominoes.SkinnyBoard(self.board.left_end(), self.board.right_end(), len(self.board)) else: # board is empty board = dominoes.SkinnyBoard() else: # TODO: optimize for Board class board = copy.deepcopy(self.board) # only need to copy the Hand, because the Domino objects are # immutable. note that using copy.copy does not work because # the container of the Domino objects within the Hand also # needs to be copied, which the Hand initializer takes care of. hands = [dominoes.Hand(hand) for hand in self.hands] # list of tuples of Domino and bool; shallow copy is sufficient moves = list(self.moves) # tuple of immutable Domino objects; no need to deepcopy valid_moves = self.valid_moves # None or namedtuple of ints and bools; no need to deepcopy result = self.result # just an int; no need to deepcopy turn = self.turn # just an int; no need to deepcopy starting_player = self.starting_player return type(self)(board, hands, moves, turn, valid_moves, starting_player, result)
def test_make_move(self): g1 = dominoes.Game.new() d1 = dominoes.Domino(7, 7) g1.board.add(d1, True) d2 = dominoes.Domino(7, 6) p1 = g1.turn len_hand1 = len(g1.hands[p1]) g1.hands[p1].draw(d2) # make a move on the left end of the board g1.make_move(d2, True) self.assertEqual(g1.board.left_end(), d2.second) self.assertEqual(g1.board.right_end(), d1.second) self.assertEqual(len(g1.board), 2) self.assertEqual(len(g1.hands[p1]), len_hand1) self.assertFalse(d2 in g1.hands[p1]) self.assertEqual(g1.moves[0], (d2, True)) for m in g1.moves[1:]: self.assertIsNone(m) self.assertTrue(bool(g1.valid_moves)) self.assertIsNone(g1.result) d3 = dominoes.Domino(7, 5) p2 = g1.turn len_hand2 = len(g1.hands[p2]) len_moves1 = len(g1.moves) g1.hands[p2].draw(d3) # make a move on the right end of the board g1.make_move(d3, False) str1 = str(g1) repr1 = repr(g1) self.assertEqual(g1.board.left_end(), d2.second) self.assertEqual(g1.board.right_end(), d3.second) self.assertEqual(len(g1.board), 3) self.assertEqual(len(g1.hands[p2]), len_hand2) self.assertFalse(d3 in g1.hands[p2]) self.assertEqual(g1.moves[0], (d2, True)) for m in g1.moves[1:len_moves1]: self.assertIsNone(m) self.assertEqual(g1.moves[len_moves1], (d3, False)) for m in g1.moves[len_moves1 + 1:]: self.assertIsNone(m) self.assertTrue(bool(g1.valid_moves)) self.assertIsNone(g1.result) self.assertTrue('Board: {}'.format(g1.board) in str1) self.assertTrue("Player 0's hand: {}".format(g1.hands[0]) in str1) self.assertTrue("Player 1's hand: {}".format(g1.hands[1]) in str1) self.assertTrue("Player 2's hand: {}".format(g1.hands[2]) in str1) self.assertTrue("Player 3's hand: {}".format(g1.hands[3]) in str1) self.assertTrue("Player {}'s turn".format(g1.turn) in str1) self.assertFalse('Player {} won'.format(p2) in str1) self.assertFalse('Player {} stuck'.format(p2) in str1) self.assertEqual(str1, repr1) d4 = dominoes.Domino(7, 7) p3 = g1.turn len_hand3 = len(g1.hands[p3]) before = copy.deepcopy(g1) # try to play a domino that is not in the player's hand self.assertRaises(dominoes.NoSuchDominoException, g1.make_move, d4, True) self.assertEqual(before, g1) self.assertEqual(g1.board.left_end(), d2.second) self.assertEqual(g1.board.right_end(), d3.second) self.assertEqual(len(g1.board), 3) self.assertEqual(len(g1.hands[p3]), len_hand3) self.assertFalse(d4 in g1.hands[p3]) self.assertEqual(g1.turn, p3) self.assertEqual(g1.moves[0], (d2, True)) for m in g1.moves[1:len_moves1]: self.assertIsNone(m) self.assertEqual(g1.moves[len_moves1], (d3, False)) for m in g1.moves[len_moves1 + 1:]: self.assertIsNone(m) self.assertTrue(bool(g1.valid_moves)) self.assertIsNone(g1.result) g1.hands[p3].draw(d4) before = copy.deepcopy(g1) # try to play a domino that does not match the board self.assertRaises(dominoes.EndsMismatchException, g1.make_move, d4, True) self.assertEqual(before, g1) self.assertEqual(g1.board.left_end(), d2.second) self.assertEqual(g1.board.right_end(), d3.second) self.assertEqual(len(g1.board), 3) self.assertEqual(len(g1.hands[p3]), len_hand3 + 1) self.assertTrue(d4 in g1.hands[p3]) self.assertEqual(g1.turn, p3) self.assertEqual(g1.moves[0], (d2, True)) for m in g1.moves[1:len_moves1]: self.assertIsNone(m) self.assertEqual(g1.moves[len_moves1], (d3, False)) for m in g1.moves[len_moves1 + 1:]: self.assertIsNone(m) self.assertTrue(bool(g1.valid_moves)) self.assertIsNone(g1.result) # play a domino that forces a pass d5 = dominoes.Domino(1, 1) d6 = dominoes.Domino(2, 2) d7 = dominoes.Domino(3, 3) d8 = dominoes.Domino(4, 4) d9 = dominoes.Domino(1, 2) h1 = dominoes.Hand([d5, d6]) h2 = dominoes.Hand([d7]) h3 = dominoes.Hand([d8]) h4 = dominoes.Hand([d9]) g2 = dominoes.Game.new() g2.hands = [h1, h2, h3, h4] g2.make_move(d5, True) self.assertEqual(g2.board.left_end(), d5.first) self.assertEqual(g2.board.right_end(), d5.second) self.assertEqual(len(g2.board), 1) self.assertEqual(len(g2.hands[0]), 1) self.assertFalse(d5 in g2.hands[0]) self.assertEqual(g2.moves, [(d5, True), None, None]) self.assertEqual(g2.turn, 3) self.assertTrue(bool(g2.valid_moves)) self.assertIsNone(g2.result)
def test_iter(self): h = dominoes.Hand([]) self.assertIsInstance(h, collections.Iterable) self.assertIsNotNone(iter(h))
def test_probabilistic_alphabeta(self): # test player interface self._test_player_interface(dominoes.players.probabilistic_alphabeta(), 15) # test name self.assertEqual( dominoes.players.probabilistic_alphabeta(name='test').__name__, 'test') self.assertEqual(dominoes.players.probabilistic_alphabeta().__name__, 'probabilistic_alphabeta') # test that start move can prevent running of player cp1 = dominoes.players.counter() pap1 = dominoes.players.probabilistic_alphabeta(start_move=1, player=cp1) g1 = dominoes.Game.new() pap1(g1) self.assertEqual(cp1.count, 0) # test that player can still run even with a start move. # due to passes, the amount of total moves will be greater # than or equal to 15 after playing 15 fixed moves. therefore, # the following will not test the boundary condition every time. # this test suite gets run often enough that the danger is negligible. cp2 = dominoes.players.counter() pap2 = dominoes.players.probabilistic_alphabeta(start_move=15, player=cp2) while True: g2 = _new_game_with_fixed_moves(15) # the probabilistic_alphabeta player is smart enough # not to run when there is only one valid move. if len(g2.valid_moves) > 1: break pap2(g2) self.assertNotEqual(cp2.count, 0) # testing that a small sample size greatly limits the amount of work done g3 = _new_game_with_fixed_moves(10) pap3 = dominoes.players.probabilistic_alphabeta(sample_size=1) start = time.time() pap3(g3) elapsed = time.time() - start self.assertTrue(elapsed < 1) # test for correct results on a simple example d1 = dominoes.Domino(2, 0) d2 = dominoes.Domino(3, 0) d3 = dominoes.Domino(4, 0) d4 = dominoes.Domino(5, 0) d5 = dominoes.Domino(5, 1) d6 = dominoes.Domino(6, 0) h1 = dominoes.Hand([d1, d2]) h2 = dominoes.Hand([d3, d4]) h3 = dominoes.Hand([d5]) h4 = dominoes.Hand([d6]) g4 = dominoes.Game.new(starting_player=0) g4.hands = [h1, h2, h3, h4] g4.make_move(d1, True) pap4 = dominoes.players.probabilistic_alphabeta() self.assertEqual(g4.valid_moves, ((d3, False), (d4, False))) pap4(g4) self.assertEqual(g4.valid_moves, ((d4, False), (d3, False)))
def test_alphabeta(self): g1 = dominoes.Game.new() g1.result = dominoes.Result(0, True, 10) self.assertEqual(([], 10), dominoes.search.alphabeta(g1)) g2 = dominoes.Game.new() g2.result = dominoes.Result(1, True, -10) self.assertEqual(([], -10), dominoes.search.alphabeta(g2)) d1 = dominoes.Domino(7, 0) d2 = dominoes.Domino(0, 0) d3 = dominoes.Domino(0, 1) d4 = dominoes.Domino(0, 2) d5 = dominoes.Domino(0, 3) d6 = dominoes.Domino(0, 4) d7 = dominoes.Domino(0, 5) d8 = dominoes.Domino(0, 6) d9 = dominoes.Domino(0, 8) d10 = dominoes.Domino(1, 9) d11 = dominoes.Domino(2, 10) d12 = dominoes.Domino(3, 11) d13 = dominoes.Domino(4, 12) d14 = dominoes.Domino(5, 13) d15 = dominoes.Domino(6, 14) h1 = dominoes.Hand([d1, d2]) h2 = [d2, d3, d4, d5, d6, d7, d8] random.shuffle(h2) h2 = dominoes.Hand(h2) h3 = [d9, d10, d11, d12, d13, d14, d15] random.shuffle(h3) h3 = dominoes.Hand(h3) h4 = dominoes.Hand([d2]) g3 = dominoes.Game.new(starting_player=0) g3.hands = [h1, h2, h3, h4] g3.make_move(d1, True) self.assertEqual(([(d2, False), (d9, False)], -111), dominoes.search.alphabeta(g3)) h5 = dominoes.Hand([d2]) h6 = dominoes.Hand([d1, d2]) h7 = [d2, d3, d4, d5, d6, d7, d8] random.shuffle(h7) h7 = dominoes.Hand(h7) h8 = [d9, d10, d11, d12, d13, d14, d15] random.shuffle(h8) h8 = dominoes.Hand(h8) g4 = dominoes.Game.new(starting_player=1) g4.hands = [h5, h6, h7, h8] g4.make_move(d1, True) self.assertEqual(([(d2, False), (d9, False)], 111), dominoes.search.alphabeta(g4)) h9 = dominoes.Hand([d1, d2]) h10 = dominoes.Hand([d2, d3]) h11 = dominoes.Hand([d9, d10, d3]) h12 = dominoes.Hand([d2]) g5 = dominoes.Game.new(starting_player=0) g5.hands = [h9, h10, h11, h12] g5.make_move(d1, True) cp1 = dominoes.players.counter() self.assertEqual(([(d2, False), (d9, False)], -12), dominoes.search.alphabeta(g5, player=cp1)) self.assertEqual(cp1.count, 4) h13 = dominoes.Hand([d2]) h14 = dominoes.Hand([d1, d2]) h15 = dominoes.Hand([d2, d3]) h16 = dominoes.Hand([d9, d10, d3]) g6 = dominoes.Game.new(starting_player=1) g6.hands = [h13, h14, h15, h16] g6.make_move(d1, True) cp2 = dominoes.players.counter() self.assertEqual(([(d2, False), (d9, False)], 12), dominoes.search.alphabeta(g6, player=cp2)) self.assertEqual(cp2.count, 4) h17 = dominoes.Hand([d1, d2]) h18 = dominoes.Hand([d2, d3]) h19 = dominoes.Hand([d9, d3, d10]) h20 = dominoes.Hand([d2]) g7 = dominoes.Game.new(starting_player=0) g7.hands = [h17, h18, h19, h20] g7.make_move(d1, True) def d10_before_d3(game): if game.valid_moves == ((d3, False), (d10, False)): game.valid_moves = ((d10, False), (d3, False)) cp3 = dominoes.players.counter(d10_before_d3) self.assertEqual(([(d2, False), (d9, False)], -12), dominoes.search.alphabeta(g7, player=cp3)) self.assertEqual(cp3.count, 4) h21 = dominoes.Hand([d2]) h22 = dominoes.Hand([d1, d2]) h23 = dominoes.Hand([d2, d3]) h24 = dominoes.Hand([d9, d3, d10]) g8 = dominoes.Game.new(starting_player=1) g8.hands = [h21, h22, h23, h24] g8.make_move(d1, True) cp4 = dominoes.players.counter(d10_before_d3) self.assertEqual(([(d2, False), (d9, False)], 12), dominoes.search.alphabeta(g8, player=cp4)) self.assertEqual(cp4.count, 4)
def test_make_move_endgame(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(2, 3) d3 = dominoes.Domino(3, 4) d4 = dominoes.Domino(4, 5) h1 = dominoes.Hand([d1]) h2 = dominoes.Hand([d2]) h3 = dominoes.Hand([d3]) h4 = dominoes.Hand([d4]) g1 = dominoes.Game.new() g1.hands = [h1, h2, h3, h4] g1.make_move(d1, True) str1 = str(g1) repr1 = repr(g1) self.assertEqual(g1.board.left_end(), d1.first) self.assertEqual(g1.board.right_end(), d1.second) self.assertEqual(len(g1.board), 1) self.assertEqual(len(g1.hands[0]), 0) self.assertEqual(len(g1.hands[1]), 1) self.assertEqual(len(g1.hands[2]), 1) self.assertEqual(len(g1.hands[3]), 1) self.assertEqual(g1.moves, [(d1, True)]) self.assertFalse(bool(g1.valid_moves)) self.assertEqual(g1.result, dominoes.Result(0, True, 21)) self.assertEqual(g1.turn, 0) self.assertTrue('Board: {}'.format(g1.board) in str1) self.assertTrue("Player 0's hand: {}".format(g1.hands[0]) in str1) self.assertTrue("Player 1's hand: {}".format(g1.hands[1]) in str1) self.assertTrue("Player 2's hand: {}".format(g1.hands[2]) in str1) self.assertTrue("Player 3's hand: {}".format(g1.hands[3]) in str1) self.assertFalse("Player 0's turn" in str1) self.assertTrue('Player 0 won and scored 21 points!' in str1) self.assertEqual(str1, repr1) d5 = dominoes.Domino(7, 7) d6 = dominoes.Domino(1, 1) d7 = dominoes.Domino(2, 2) d8 = dominoes.Domino(3, 3) d9 = dominoes.Domino(4, 4) h5 = dominoes.Hand([d5, d6]) h6 = dominoes.Hand([d7]) h7 = dominoes.Hand([d8]) h8 = dominoes.Hand([d9]) g2 = dominoes.Game.new() g2.hands = [h5, h6, h7, h8] g2.make_move(d5, True) str2 = str(g2) repr2 = repr(g2) self.assertEqual(g2.board.left_end(), d5.first) self.assertEqual(g2.board.right_end(), d5.second) self.assertEqual(len(g2.board), 1) self.assertEqual(len(g2.hands[0]), 1) self.assertEqual(len(g2.hands[1]), 1) self.assertEqual(len(g2.hands[2]), 1) self.assertEqual(len(g2.hands[3]), 1) self.assertEqual(g2.moves, [(d5, True)]) self.assertFalse(bool(g2.valid_moves)) self.assertEqual(g2.result, dominoes.Result(0, False, 20)) self.assertEqual(g2.turn, 0) self.assertTrue('Board: {}'.format(g2.board) in str2) self.assertTrue("Player 0's hand: {}".format(g2.hands[0]) in str2) self.assertTrue("Player 1's hand: {}".format(g2.hands[1]) in str2) self.assertTrue("Player 2's hand: {}".format(g2.hands[2]) in str2) self.assertTrue("Player 3's hand: {}".format(g2.hands[3]) in str2) self.assertFalse("Player 0's turn" in str2) self.assertTrue( 'Player 0 stuck the game and scored 20 points!' in str2) self.assertEqual(str2, repr2) h9 = dominoes.Hand([d5, d6]) h10 = dominoes.Hand([d7]) h11 = dominoes.Hand([d9]) h12 = dominoes.Hand([d8]) g3 = dominoes.Game.new() g3.hands = [h9, h10, h11, h12] g3.make_move(d5, True) str3 = str(g3) repr3 = repr(g3) self.assertEqual(g3.board.left_end(), d5.first) self.assertEqual(g3.board.right_end(), d5.second) self.assertEqual(len(g3.board), 1) self.assertEqual(len(g3.hands[0]), 1) self.assertEqual(len(g3.hands[1]), 1) self.assertEqual(len(g3.hands[2]), 1) self.assertEqual(len(g3.hands[3]), 1) self.assertEqual(g3.moves, [(d5, True)]) self.assertFalse(bool(g3.valid_moves)) self.assertEqual(g3.result, dominoes.Result(0, False, 0)) self.assertEqual(g3.turn, 0) self.assertTrue('Board: {}'.format(g3.board) in str3) self.assertTrue("Player 0's hand: {}".format(g3.hands[0]) in str3) self.assertTrue("Player 1's hand: {}".format(g3.hands[1]) in str3) self.assertTrue("Player 2's hand: {}".format(g3.hands[2]) in str3) self.assertTrue("Player 3's hand: {}".format(g3.hands[3]) in str3) self.assertFalse("Player 0's turn" in str3) self.assertTrue('Player 0 stuck the game and tied (0 points)!' in str3) self.assertEqual(str3, repr3) h13 = dominoes.Hand([d5, d7]) h14 = dominoes.Hand([d6]) h15 = dominoes.Hand([d9]) h16 = dominoes.Hand([d8]) g4 = dominoes.Game.new() g4.hands = [h13, h14, h15, h16] g4.make_move(d5, True) str4 = str(g4) repr4 = repr(g4) self.assertEqual(g4.board.left_end(), d5.first) self.assertEqual(g4.board.right_end(), d5.second) self.assertEqual(len(g4.board), 1) self.assertEqual(len(g4.hands[0]), 1) self.assertEqual(len(g4.hands[1]), 1) self.assertEqual(len(g4.hands[2]), 1) self.assertEqual(len(g4.hands[3]), 1) self.assertEqual(g4.moves, [(d5, True)]) self.assertFalse(bool(g4.valid_moves)) self.assertEqual(g4.result, dominoes.Result(0, False, -20)) self.assertEqual(g4.turn, 0) self.assertTrue('Board: {}'.format(g4.board) in str4) self.assertTrue("Player 0's hand: {}".format(g4.hands[0]) in str4) self.assertTrue("Player 1's hand: {}".format(g4.hands[1]) in str4) self.assertTrue("Player 2's hand: {}".format(g4.hands[2]) in str4) self.assertTrue("Player 3's hand: {}".format(g4.hands[3]) in str4) self.assertFalse("Player 0's turn" in str4) self.assertTrue( 'Player 0 stuck the game and scored 20 points for the opposing team!' in str4) self.assertEqual(str4, repr4) before = copy.deepcopy(g4) self.assertRaises(dominoes.GameOverException, g4.make_move, d7, True) self.assertEqual(before, g4) self.assertEqual(g4.board.left_end(), d5.first) self.assertEqual(g4.board.right_end(), d5.second) self.assertEqual(len(g4.board), 1) self.assertEqual(len(g4.hands[0]), 1) self.assertEqual(len(g4.hands[1]), 1) self.assertEqual(len(g4.hands[2]), 1) self.assertEqual(len(g4.hands[3]), 1) self.assertEqual(g4.moves, [(d5, True)]) self.assertFalse(bool(g4.valid_moves)) self.assertEqual(g4.result, dominoes.Result(0, False, -20)) self.assertEqual(g4.turn, 0) d10 = dominoes.Domino(1, 2) d11 = dominoes.Domino(2, 3) d12 = dominoes.Domino(3, 4) d13 = dominoes.Domino(4, 5) h17 = dominoes.Hand([d10]) h18 = dominoes.Hand([d11]) h19 = dominoes.Hand([d12]) h20 = dominoes.Hand([d13]) g5 = dominoes.Game.new(starting_player=1) g5.hands = [h17, h18, h19, h20] g5.make_move(d11, True) str5 = str(g5) repr5 = repr(g5) self.assertEqual(g5.board.left_end(), d11.first) self.assertEqual(g5.board.right_end(), d11.second) self.assertEqual(len(g5.board), 1) self.assertEqual(len(g5.hands[0]), 1) self.assertEqual(len(g5.hands[1]), 0) self.assertEqual(len(g5.hands[2]), 1) self.assertEqual(len(g5.hands[3]), 1) self.assertEqual(g5.moves, [(d11, True)]) self.assertFalse(bool(g5.valid_moves)) self.assertEqual(g5.result, dominoes.Result(1, True, -19)) self.assertEqual(g5.turn, 1) self.assertTrue('Board: {}'.format(g5.board) in str5) self.assertTrue("Player 0's hand: {}".format(g5.hands[0]) in str5) self.assertTrue("Player 1's hand: {}".format(g5.hands[1]) in str5) self.assertTrue("Player 2's hand: {}".format(g5.hands[2]) in str5) self.assertTrue("Player 3's hand: {}".format(g5.hands[3]) in str5) self.assertFalse("Player 1's turn" in str5) self.assertTrue('Player 1 won and scored 19 points!' in str5) self.assertEqual(str5, repr5)