Beispiel #1
0
    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]))})
Beispiel #2
0
    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]))})
Beispiel #3
0
    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)))
Beispiel #4
0
    def test_init(self):
        h1 = dominoes.Hand([])

        self.assertIsNotNone(h1)

        d = dominoes.Domino(1, 2)
        h2 = dominoes.Hand([d])

        self.assertIsNotNone(h2)
Beispiel #5
0
    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)
Beispiel #6
0
    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])
Beispiel #7
0
    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))
Beispiel #8
0
    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]')
Beispiel #9
0
    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)
Beispiel #10
0
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])
    ]
Beispiel #11
0
    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)
Beispiel #12
0
    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)
Beispiel #13
0
    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)
Beispiel #14
0
    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)
Beispiel #15
0
    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))
Beispiel #16
0
    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)
Beispiel #17
0
    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)
Beispiel #18
0
    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
Beispiel #19
0
    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
Beispiel #20
0
    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)
Beispiel #21
0
    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)
Beispiel #22
0
    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)
Beispiel #23
0
    def test_iter(self):
        h = dominoes.Hand([])

        self.assertIsInstance(h, collections.Iterable)
        self.assertIsNotNone(iter(h))
Beispiel #24
0
    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)))
Beispiel #25
0
    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)
Beispiel #26
0
    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)