def test_optimal_melds_chosen_from_hand_with_overlapping_melds(hand_with_overlapping_sets_and_runs): expected_melds = [ Meld(Card.from_text("2C", "2S", "2D", "2H")), Meld(Card.from_text("4D", "5D", "6D")) ] md = MeldDetector(*hand_with_overlapping_sets_and_runs.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == 2) for meld in expected_melds: assert(meld in md.optimal_hand.melds) assert(md.optimal_hand.deadwood_count == 3) assert(md.optimal_hand.deadwood_value == 28)
def test_optimal_melds_chosen_from_complex_set(hand_with_complex_sets_and_runs): expected_melds = [ Meld(Card.from_text("2D", "2S", "2H")), Meld(Card.from_text("3D", "4D", "5D")), Meld(Card.from_text("AC", "2C", "3C")) ] md = MeldDetector(*hand_with_complex_sets_and_runs.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == 3) for meld in expected_melds: assert(meld in md.optimal_hand.melds) assert(md.optimal_hand.deadwood_value == 3)
def test_optimal_melds_chosen_from_simple_hand(hand_with_simple_sets_and_runs): expected_melds = [ Meld(Card.from_text("2C", "2S", "2H")), Meld(Card.from_text("9S", "10S", "JS")), Meld(Card.from_text("4D", "5D", "6D")) ] md = MeldDetector(*hand_with_simple_sets_and_runs.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == 3) for meld in expected_melds: assert(meld in md.optimal_hand.melds) assert(md.optimal_hand.deadwood_count == 1) assert(md.optimal_hand.deadwood_value == 4)
def test_hand_with_no_overused_cards_is_valid(self): hm = HandWithMelds() (qh, qd, qc, kd) = Card.from_text("QH", "QD", "QC", "KD") hm.add([qh, qd, qc, kd]) hm.create_meld(qh, qd, qc) hm.create_meld(kd) self.assertTrue(hm.is_valid)
def test_deadwood_count_includes_cards_not_in_complete_melds(self): hm = HandWithMelds() (qh, qd, qc, kd) = Card.from_text("QH", "QD", "QC", "KD") hm.add([qh, qd, qc, kd]) hm.create_meld(qh, qd, qc) hm.create_meld(kd) self.assertEqual(hm.deadwood_count, 1)
def test_deadwood_value_sums_points_of_cards_not_in_complete_melds(self): hm = HandWithMelds() (qh, qd, qc, kd, threec) = Card.from_text("QH", "QD", "QC", "KD", "3C") hm.add([qh, qd, qc, kd, threec]) hm.create_meld(qh, qd, qc) hm.create_meld(threec) # the three and the kd are both deadwood here self.assertEqual(hm.deadwood_value, 13)
def test_is_deadwood_is_true_for_cards_not_in_any_meld(self): hm = HandWithMelds() (qh, qd, qc, kd, threec) = Card.from_text("QH", "QD", "QC", "KD", "3C") cards = [qh, qd, qc, kd, threec] hm.add(cards) hm.create_meld(qh, qd, qc) expected_deadwood = [False, False, False, True, True] for idx, card in enumerate(cards): self.assertEqual(hm.is_deadwood(card), expected_deadwood[idx])
def test_hand_with_overused_cards_is_invalid(self): hm = HandWithMelds() (qh, qd, qc, kd, jd, jh) = Card.from_text("QH", "QD", "QC", "KD", "JD", "JH") hm.add([qh, qd, qc, kd, jd, jh]) hm.create_meld(qh, qd, qc) # qd overlaps between this hm.create_meld(kd, qd, jd) # and this hm.create_meld(jd, jh) # overlap here, but incomplete self.assertFalse(hm.is_valid)
def test_hand_with_overused_cards_is_valid_if_only_one_is_complete(self): hm = HandWithMelds() (qh, qd, qc, kd, jd, jh, js) = Card.from_text("QH", "QD", "QC", "KD", "JD", "JH", "JS") hm.add([qh, qd, qc, kd, jd, jh, js]) hm.create_meld(qh, qd, qc) # qd overlaps between this hm.create_meld(kd, qd) # and this, but only the first is complete hm.create_meld(jd, jh, js) # no overlap on this one self.assertTrue(hm.is_valid)
def test_deadwood_returns_cards_not_in_complete_meld(self): # this test covers deadwood in no melds and deadwood in incomplete meld hm = HandWithMelds() (qh, qd, qc, kd, threec) = Card.from_text("QH", "QD", "QC", "KD", "3C") cards = [qh, qd, qc, kd, threec] hm.add(cards) hm.create_meld(qh, qd, qc) hm.create_meld(threec) expected_deadwood = [threec, kd] for card in expected_deadwood: self.assertTrue(card in hm.deadwood())
def test_optimal_meld_scenario_8(): h = Hand() for card in Card.from_text( "4C", "4S", "3S", "2S", "5H", "4H", "3H", "AH", "3D", "2D" ): h.add(card) ## in this scenario, there are two equally optimal outcomes optimal_expected_option1 = [ Meld(Card.from_text("4C", "4S", "4H")), Meld(Card.from_text("3H", "3S", "3D")) ] optimal_expected_option2 = [ Meld(Card.from_text("4S", "3S", "2S")), Meld(Card.from_text("5H", "4H", "3H")) ] md = MeldDetector(*h.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == len(optimal_expected_option1)) # works for either is_option_1 = True is_option_2 = True for expected_meld in optimal_expected_option1: if expected_meld not in md.optimal_hand.melds: is_option_1 = False for expected_meld in optimal_expected_option2: if expected_meld not in md.optimal_hand.melds: is_option_2 = False assert(not (is_option_1 and is_option_2)) #highlander principle assert(is_option_1 or is_option_2) # b/c the two are equiv. this is true regardless of option assert(md.optimal_hand.deadwood_value == 10) assert(md.optimal_hand.deadwood_count == 4)
def test_overlapping_set_and_run_detection(hand_with_complex_sets_and_runs): expected_melds = [ Meld(Card.from_text("2C", "2S", "2D", "2H")), Meld(Card.from_text("2S", "2D", "2H")), Meld(Card.from_text("2C", "2D", "2H")), Meld(Card.from_text("2C", "2S", "2H")), Meld(Card.from_text("2C", "2S", "2D")), Meld(Card.from_text("2D", "3D", "4D")), Meld(Card.from_text("3D", "4D", "5D")), Meld(Card.from_text("2D", "3D", "4D", "5D")), Meld(Card.from_text("3D", "3S", "3C")), Meld(Card.from_text("AC", "2C", "3C")), ] md = MeldDetector(*hand_with_complex_sets_and_runs.cards) md._detect_all_melds() assert(len(md._melds) == 10) for meld in expected_melds: assert(meld in md._melds)
def test_optimal_meld_scenario_9(): # this is a relatively simple scenario - only one card is overused h = Hand() for card in Card.from_text( "6D", "6C", "6H", "2H", "3H", "4H", "2S", "2C" ): h.add(card) optimal_expected = [ Meld(Card.from_text("6D", "6C", "6H")), Meld(Card.from_text("2H", "3H", "4H")) ] md = MeldDetector(*h.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == len(optimal_expected)) for expected_meld in optimal_expected: assert(expected_meld in md.optimal_hand.melds) assert(md.optimal_hand.deadwood_value == 4) assert(md.optimal_hand.deadwood_count == 2)
def test_optimal_meld_scenario_1(): h = Hand() for card in Card.from_text( "10S", "9S", "8S", "8H", "9C", "8C", "7C", "6C", "5C", "KD" ): h.add(card) optimal_expected = [ Meld(Card.from_text("10S", "9S", "8S")), Meld(Card.from_text("9C", "8C", "7C", "6C", "5C")) ] md = MeldDetector(*h.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == len(optimal_expected)) for expected_meld in optimal_expected: assert(expected_meld in md.optimal_hand.melds) assert(md.optimal_hand.deadwood_value == 18) assert(md.optimal_hand.deadwood_count == 2)
def test_optimal_meld_scenario_6(): h = Hand() for card in Card.from_text( "4S", "3S", "2S", "AS", "3H", "2H", "AH", "4D", "3D", "2D" ): h.add(card) optimal_expected = [ Meld(Card.from_text("4S", "3S", "2S", "AS")), Meld(Card.from_text("3H", "2H", "AH")), Meld(Card.from_text("4D", "3D", "2D")) ] md = MeldDetector(*h.cards) md.detect_optimal_melds() assert(len(md.optimal_hand.melds) == len(optimal_expected)) for expected_meld in optimal_expected: assert(expected_meld in md.optimal_hand.melds) assert(md.optimal_hand.deadwood_value == 0) assert(md.optimal_hand.deadwood_count == 0)
def hand_with_sets(): """A hand with two sets. Should find 6 sets: (QH, QC, QD) (2S, 2H, 2D, 2C) - 5 permutations of this """ hand = Hand() for card in Card.from_text( "JH", "QH", "QC", "QD", "2S", "3C", "2H", "6S", "2D", "2C" ): hand.add(card) yield hand
def hand_with_simple_sets_and_runs(): """A hand with non-overlapping sets and runs. Should find 6 melds: 2C 2S 2H (1 set) 4D 5D 6D (1 run) 9S 10S JS (1 set) 4C This hand should have 4 points of deadwood (1 deadwood card) """ hand = Hand() for card in Card.from_text( "2C", "2S", "2H", "4D", "5D", "6D", "9S", "10S", "JS", "4C" ): hand.add(card) yield hand
def hand_with_complex_sets_and_runs(): """A hand with overlapping sets and runs. Should find 10 melds: 2C 2S 2H 2D (5 permutations of set) 3D 4D 5D (3 perms of run (including 2 above): 234, 345, 2345) 3S (1 set - 333) 3C AC (1 run - A23 (2 is above)) This hand should have 0 points of deadwood (0 deadwood cards) """ hand = Hand() for card in Card.from_text( "2C", "2S", "2H", "2D", "3D", "4D", "5D", "3S", "3C", "AC" ): hand.add(card) yield hand
def hand_with_overlapping_sets_and_runs(): """A hand with obviously overlapping sets and runs. Should find 6 melds: 2C 2S 2H 2D (5 permutations of set) 4D 5D 6D (1 run) 8S 10S JS This hand should have 28 points of deadwood (3 deadwood cards) The optimal sets from this hand are: 2C 2S 2H 2D 4D 5D 6D """ hand = Hand() for card in Card.from_text( "2C", "2S", "2H", "2D", "4D", "5D", "6D", "8S", "10S", "JS" ): hand.add(card) yield hand
def test_complex_run_detection(hand_with_complex_runs): # (3H, 4H, 5H), # (4H, 5H, 6H), # (5H, 6H, 7H), # (3H, 4H, 5H, 6H), # (4H, 5H, 6H, 7H), # (3H, 4H, 5H, 6H, 7H), # (9C, 10C, JC) expected_melds = [ Meld(Card.from_text("3H", "4H", "5H")), Meld(Card.from_text("4H", "5H", "6H")), Meld(Card.from_text("5H", "6H", "7H")), Meld(Card.from_text("3H", "4H", "5H", "6H")), Meld(Card.from_text("4H", "5H", "6H", "7H")), Meld(Card.from_text("3H", "4H", "5H", "6H", "7H")), Meld(Card.from_text("9C", "10C", "JC")) ] md = MeldDetector(*hand_with_complex_runs.cards) md._detect_all_melds() assert(len(md._melds) == 7) for meld in expected_melds: assert(meld in md._melds)
def test_nonface_card_creation_from_text(self): c = Card.from_text("3C") self.assertIsInstance(c.suit, Suit) self.assertIsInstance(c.rank, Rank) self.assertIs(c.suit, Suit.CLUB) self.assertIs(c.rank, Rank.THREE)
def test_multiple_card_creation_from_text(self): cards = Card.from_text("3C","4S","QH") self.assertEqual(len(cards), 3) self.assertEqual(cards[0], Card.from_text("3C")) self.assertEqual(cards[2], Card.from_text("QH"))
def test_face_card_creation_from_text(self): c = Card.from_text("QH") self.assertIsInstance(c.suit, Suit) self.assertIsInstance(c.rank, Rank) self.assertIs(c.suit, Suit.HEART) self.assertIs(c.rank, Rank.QUEEN)
def test_stack_add_list(self): cs = CardStack() cs.add(Card.from_text("3H", "2C", "AD")) self.assertEqual(cs.size(), 3)
def test_melds_are_equal_if_same_cards(self): m1 = Meld(Card.from_text("2H", "JH", "AH")) m2 = Meld(Card.from_text("AH", "2H", "JH")) self.assertEqual(m1, m2)