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_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 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_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_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_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_hash(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(2, 1) d3 = dominoes.Domino(1, 3) d_set = {d1} self.assertTrue(d1 in d_set) self.assertTrue(d2 in d_set) self.assertFalse(d3 in d_set)
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_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 __str__(self): if not self: return '' elif self._length == 1: return str(dominoes.Domino(self._left, self._right)) else: left_domino = dominoes.Domino(self._left, '?') right_domino = dominoes.Domino('?', self._right) middle_dominoes = [dominoes.Domino('?', '?')] * (self._length - 2) all_dominoes = [left_domino] + middle_dominoes + [right_domino] return ''.join(str(d) for d in all_dominoes)
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_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_reverse(self): self._test_player_interface(dominoes.players.reverse) g = dominoes.Game.new() d1 = dominoes.Domino(1, 1) d2 = dominoes.Domino(2, 2) d3 = dominoes.Domino(3, 3) vms = [((d1, True), ), ((d1, True), (d2, False)), ((d1, True), (d2, False), (d3, False))] rvms = [((d1, True), ), ((d2, False), (d1, True)), ((d3, False), (d2, False), (d1, True))] for vm, rvm in zip(vms, rvms): g.valid_moves = vm dominoes.players.reverse(g) self.assertEqual(g.valid_moves, rvm)
def __init__(self, target_score=200, starting_domino=None): if starting_domino is None: starting_domino = dominoes.Domino(6, 6) self.games = [dominoes.Game.new(starting_domino=starting_domino)] self.scores = [0, 0] self.target_score = target_score
def test_identity(self): self._test_player_interface(dominoes.players.identity) g = dominoes.Game.new() d1 = dominoes.Domino(1, 1) d2 = dominoes.Domino(2, 2) d3 = dominoes.Domino(3, 3) valid_moves_before = [((d1, True), ), ((d1, True), (d2, False)), ((d1, True), (d2, False), (d3, False))] valid_moves_after = [((d1, True), ), ((d1, True), (d2, False)), ((d1, True), (d2, False), (d3, False))] for vmb, vma in zip(valid_moves_before, valid_moves_after): g.valid_moves = vmb dominoes.players.identity(g) self.assertEqual(g.valid_moves, vma)
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_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_init(self): h1 = dominoes.Hand([]) self.assertIsNotNone(h1) d = dominoes.Domino(1, 2) h2 = dominoes.Hand([d]) self.assertIsNotNone(h2)
def test_skinny_board(self): d = dominoes.Domino(1, 2) g = dominoes.Game.new(starting_domino=d) g.skinny_board() ends = [g.board.left_end(), g.board.right_end()] self.assertTrue(d.first in ends) self.assertTrue(d.second in ends) self.assertEqual(len(g.board), 1)
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 test_immutability(self): d = dominoes.Domino(1, 2) def set_first(value): d.first = value def set_second(value): d.second = value self.assertRaises(AttributeError, set_first, 3) self.assertRaises(AttributeError, set_second, 3)
def test_bota_gorda(self): self._test_player_interface(dominoes.players.bota_gorda) g = dominoes.Game.new() d1 = dominoes.Domino(1, 1) d2 = dominoes.Domino(2, 0) d3 = dominoes.Domino(1, 0) valid_moves_before = [((d1, True), ), ((d1, True), (d1, False)), ((d1, True), (d2, True)), ((d1, True), (d3, True)), ((d3, True), (d1, True))] valid_moves_after = [((d1, True), ), ((d1, True), (d1, False)), ((d1, True), (d2, True)), ((d1, True), (d3, True)), ((d1, True), (d3, True))] for vmb, vma in zip(valid_moves_before, valid_moves_after): g.valid_moves = vmb dominoes.players.bota_gorda(g) self.assertEqual(g.valid_moves, vma)
def test_add_right(self): b = dominoes.Board() d1 = dominoes.Domino(2, 1) d2 = dominoes.Domino(3, 1) d3 = dominoes.Domino(3, 2) d4 = dominoes.Domino(4, 4) b.add(d1, False) self.assertEqual(len(b), 1) self.assertEqual(b.left_end(), 2) self.assertEqual(b.right_end(), 1) self.assertEqual(str(b), '[2|1]') self.assertEqual(repr(b), '[2|1]') b.add(d2, False) self.assertEqual(len(b), 2) self.assertEqual(b.left_end(), 2) self.assertEqual(b.right_end(), 3) self.assertEqual(str(b), '[2|1][1|3]') self.assertEqual(repr(b), '[2|1][1|3]') b.add(d3, False) self.assertEqual(len(b), 3) self.assertEqual(b.left_end(), 2) self.assertEqual(b.right_end(), 2) self.assertEqual(str(b), '[2|1][1|3][3|2]') self.assertEqual(repr(b), '[2|1][1|3][3|2]') self.assertRaises(dominoes.EndsMismatchException, b.add, d4, False) self.assertEqual(len(b), 3) self.assertEqual(b.left_end(), 2) self.assertEqual(b.right_end(), 2) self.assertEqual(str(b), '[2|1][1|3][3|2]') self.assertEqual(repr(b), '[2|1][1|3][3|2]')
def test_add_left(self): b = dominoes.SkinnyBoard() d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) d3 = dominoes.Domino(2, 3) d4 = dominoes.Domino(4, 4) b.add(d1, True) self.assertEqual(len(b), 1) self.assertEqual(b.left_end(), 1) self.assertEqual(b.right_end(), 2) self.assertEqual(str(b), '[1|2]') self.assertEqual(repr(b), '[1|2]') b.add(d2, True) self.assertEqual(len(b), 2) self.assertEqual(b.left_end(), 3) self.assertEqual(b.right_end(), 2) self.assertEqual(str(b), '[3|?][?|2]') self.assertEqual(repr(b), '[3|?][?|2]') b.add(d3, True) self.assertEqual(len(b), 3) self.assertEqual(b.left_end(), 2) self.assertEqual(b.right_end(), 2) self.assertEqual(str(b), '[2|?][?|?][?|2]') self.assertEqual(repr(b), '[2|?][?|?][?|2]') self.assertRaises(dominoes.EndsMismatchException, b.add, d4, True) self.assertEqual(len(b), 3) self.assertEqual(b.left_end(), 2) self.assertEqual(b.right_end(), 2) self.assertEqual(str(b), '[2|?][?|?][?|2]') self.assertEqual(repr(b), '[2|?][?|?][?|2]')
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 test_eq(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 3) d3 = dominoes.Domino(2, 3) b1 = dominoes.Board() b2 = dominoes.Board() PseudoBoard = collections.namedtuple('PseudoBoard', ['board']) pb = PseudoBoard(collections.deque()) self.assertEqual(b1, b2) self.assertNotEqual(b1, pb) b1.add(d1, True) self.assertNotEqual(b1, b2) b2.add(d1, True) self.assertEqual(b1, b2) b1.add(d2, True) self.assertNotEqual(b1, b2) b2.add(d2, True) self.assertEqual(b1, b2) b1.add(d3, False) self.assertNotEqual(b1, b2) b2.add(d3, False) self.assertEqual(b1, b2)
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_eq(self): d1 = dominoes.Domino(1, 2) d2 = dominoes.Domino(1, 2) d3 = dominoes.Domino(2, 1) # order of values does not matter self.assertEqual(d1, d2) self.assertEqual(d1, d3) d4 = dominoes.Domino(1, 1) d5 = dominoes.Domino(1, 1) # it's OK if both values are the same self.assertEqual(d4, d5) # both values must be the same self.assertNotEqual(d1, d4) PseudoDomino = collections.namedtuple('PseudoDomino', ['first', 'second']) pd = PseudoDomino(1, 2) # needs to be a real Domino instance self.assertNotEqual(d1, pd)