def testGetPossibleHandsNoConstraints(self):
        h = HandInformation(hand_size=3, possible_cards=set(PEOPLE))

        hands = h.getPossibleHands()
        # 6C3 hands will be generated.
        self.assertEqual(len(hands), 20)

        distinct_hands = set()
        for hand in hands:
            # Ensure the hand is fully populated.
            self.assertEqual(hand.num_unknown_cards, 0)
            self.assertEqual(len(hand.known_cards), hand.hand_size)

            # Ensure all the hands are unique
            self.assertTrue(hand not in distinct_hands)
            distinct_hands.add(hand)
    def testSatisfyConstraintsCheckHands(self):
        # This test ensures that the list of possible hands match between
        # the original hand and the list of sub-hands.

        h = HandInformation(hand_size=3, possible_cards=set(range(10)))
        h.addConstraint([0, 1, 2])

        possible_hands_sol = h.getPossibleHands()

        hands = h.satisfyConstraints()
        possible_hands_test = []
        for hand in hands:
            possible_hands_test.extend(hand.getPossibleHands())

        self.assertEqual(len(possible_hands_test), len(possible_hands_sol))

        for hand in possible_hands_test:
            self.assertTrue(hand in possible_hands_sol)
    def testGetPossibleHandsWithConstraints(self):
        h = HandInformation(hand_size=3, possible_cards=set(PEOPLE))

        # Hand computed. This constraint will remove 4 possible cases.
        # (2,3,4), (2,3,5), (2,4,5), (3,4,5)
        constraint = set((PEOPLE[0], PEOPLE[1]))
        h.addConstraint(constraint)

        hands = h.getPossibleHands()
        self.assertEqual(len(hands), 16)

        distinct_hands = set()
        for hand in hands:
            # Ensure each hand satisfies the constraint
            self.assertTrue(any(c in hand.known_cards for c in constraint))

            # Ensure all hands are distinct
            self.assertTrue(hand not in distinct_hands)
            distinct_hands.add(hand)

        pass