def test_comparisons(self): # where suits are compared, Spade > Heart > Club > Diamond three_c = Card(rank=Rank.THREE, suit=Suit.CLUB) three_s = Card(rank=Rank.THREE, suit=Suit.SPADE) four_s = Card(rank=Rank.FOUR, suit=Suit.SPADE) two_s = Card(rank=Rank.TWO, suit=Suit.SPADE) three_c2 = Card(rank=Rank.THREE, suit=Suit.CLUB) self.assertTrue(three_c == three_c2) self.assertFalse(three_c == three_s) self.assertFalse(three_c == four_s) self.assertTrue(three_s > three_c) self.assertFalse(three_c == three_s) self.assertTrue(three_c < four_s) self.assertTrue(three_c < three_s) self.assertTrue(three_c < two_s) # suit is more important than rank self.assertFalse(four_s <= three_c) self.assertTrue(four_s >= three_c) self.assertFalse(three_c >= four_s) self.assertTrue(three_c < three_s)
def test_small_hand_is_not_complete(): hand = Hand() hand.add(Card(rank=Rank.JACK, suit=Suit.HEART)) # 0: JH hand.add(Card(rank=Rank.QUEEN, suit=Suit.HEART)) # 1: QH md = MeldDetector(*hand.cards) assert(md.is_complete_hand == False)
def test_partial_set(self): m = Meld(Card(rank=Rank.TWO, suit=Suit.HEART), Card(rank=Rank.TWO, suit=Suit.DIAMOND)) self.assertTrue(m.all_same_rank) self.assertFalse(m.all_same_suit) self.assertFalse(m.is_run) self.assertFalse(m.is_set) self.assertFalse(m.complete)
def test_not_same_rank(self): m = Meld(Card(rank=Rank.TWO, suit=Suit.HEART), Card(rank=Rank.THREE, suit=Suit.HEART)) self.assertFalse(m.all_same_rank) self.assertTrue(m.all_same_suit) self.assertFalse(m.is_run) self.assertFalse(m.is_set) self.assertFalse(m.complete)
def test_sets_must_be_three_long_to_count(): hand = Hand() hand.add(Card(rank=Rank.JACK, suit=Suit.HEART)) # 0: JH hand.add(Card(rank=Rank.JACK, suit=Suit.DIAMOND)) # 1: JD md = MeldDetector(*hand.cards) md._detect_all_melds() assert(len(md._melds) == 0)
def test_same_suit(self): club1 = Card(rank=Rank.TWO, suit=Suit.CLUB) club2 = Card(rank=Rank.SEVEN, suit=Suit.CLUB) heart = Card(rank=Rank.FIVE, suit=Suit.HEART) self.assertTrue(club1.same_suit(club2)) self.assertTrue(club2.same_suit(club1)) self.assertFalse(club1.same_suit(heart)) self.assertFalse(heart.same_suit(club1))
def test_runs_must_be_same_suit(): hand = Hand() hand.add(Card(rank=Rank.JACK, suit=Suit.HEART)) hand.add(Card(rank=Rank.QUEEN, suit=Suit.HEART)) hand.add(Card(rank=Rank.KING, suit=Suit.CLUB)) md = MeldDetector(*hand.cards) md._detect_all_melds() assert(len(md._melds) == 0)
def test_card_sort_by_rank(self): nine = Card(rank=Rank.NINE, suit=Suit.CLUB) ten = Card(rank=Rank.TEN, suit=Suit.DIAMOND) jack = Card(rank=Rank.JACK, suit=Suit.HEART) king = Card(rank=Rank.KING, suit=Suit.SPADE) cards = [king, ten, nine, jack] cards.sort(key=lambda card: card.rank.value) expected = [nine, ten, jack, king] for i in range(0,len(cards)): self.assertTrue(cards[i].is_same_card(expected[i]))
def test_hash(self): three = Card(rank=Rank.THREE, suit=Suit.CLUB) otherthree = Card(rank=Rank.THREE, suit=Suit.CLUB) four = Card(rank=Rank.FOUR, suit=Suit.SPADE) self.assertEqual(hash(three), hash(otherthree)) self.assertNotEqual(hash(three), hash(four)) dict = {} dict[three] = "foo" self.assertEqual(dict[otherthree], "foo")
def test_sorted(self): nine = Card(rank=Rank.NINE, suit=Suit.CLUB) ten = Card(rank=Rank.TEN, suit=Suit.DIAMOND) jack = Card(rank=Rank.JACK, suit=Suit.HEART) king = Card(rank=Rank.KING, suit=Suit.SPADE) cards = [king, ten, nine, jack] ascending = sorted(cards, key=lambda card: card.rank_val()) expected = [nine, ten, jack, king] for i in range(0,len(cards)): self.assertTrue(ascending[i].is_same_card(expected[i]))
def test_full_run(self): # these cards are intentionally out of order - order is not # reliable for cards added at init time m = Meld(Card(rank=Rank.TWO, suit=Suit.HEART), Card(rank=Rank.FOUR, suit=Suit.HEART), Card(rank=Rank.THREE, suit=Suit.HEART)) self.assertTrue(m.all_same_suit) self.assertFalse(m.all_same_rank) self.assertTrue(m.is_run) self.assertFalse(m.is_set) self.assertTrue(m.complete)
def test_stack_get(self): cs = get_test_stack() two_h = Card(rank=Rank.TWO, suit=Suit.HEART) three_d = Card(rank=Rank.THREE, suit=Suit.DIAMOND) self.assertEqual(cs.size(), 12) self.assertEqual(cs.get(4), two_h) self.assertEqual(cs.size(), 12) self.assertEqual(cs.get(5), three_d) self.assertEqual(cs.size(), 12)
def test_invalid_meld_init(self): m = Meld() with self.assertRaises(InvalidMeldError): m = Meld(Card(rank=Rank.TWO, suit=Suit.HEART), Card(rank=Rank.SIX, suit=Suit.CLUB)) self.assertFalse(m.all_same_rank) self.assertFalse(m.all_same_suit) self.assertFalse(m.is_run) self.assertFalse(m.is_set) self.assertFalse(m.complete) self.assertEqual(m.size(), 0) # failed init should have emptied meld
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_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_stack_remove(self): cs = get_test_stack() two_h = Card(rank=Rank.TWO, suit=Suit.HEART) three_d = Card(rank=Rank.THREE, suit=Suit.DIAMOND) self.assertEqual(cs.size(), 12) removed_card = cs.remove(4) self.assertEqual(removed_card, two_h) self.assertEqual(cs.size(), 11) removed_card = cs.remove(4) self.assertEqual(removed_card, three_d) self.assertEqual(cs.size(), 10)
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_card_sort_by_suit(self): # expected order Spade > Heart > Club > Diamond club = Card(rank=Rank.NINE, suit=Suit.CLUB) diamond = Card(rank=Rank.TEN, suit=Suit.DIAMOND) heart = Card(rank=Rank.JACK, suit=Suit.HEART) spade = Card(rank=Rank.KING, suit=Suit.SPADE) cards = [club, heart, diamond, spade] cards.sort(key=lambda card: card.suit.value) expected = [diamond, club, heart, spade] for i in range(0,len(cards)): print("expect {} to match {}".format(cards[i], expected[i])) self.assertTrue(cards[i].is_same_card(expected[i]))
def test_invalid_set_add(self): m = Meld(Card(rank=Rank.TWO, suit=Suit.HEART), Card(rank=Rank.TWO, suit=Suit.DIAMOND)) self.assertTrue(m.all_same_rank) self.assertFalse(m.all_same_suit) self.assertFalse(m.is_run) self.assertFalse(m.is_set) self.assertFalse(m.complete) self.assertEqual(m.size(), 2) with self.assertRaises(InvalidMeldError): m.add(Card(rank=Rank.THREE, suit=Suit.CLUB)) self.assertEqual(m.size(), 2)
def test_same_score_different_sorting(self): jack = Card(rank=Rank.JACK, suit=Suit.SPADE) ten = Card(rank=Rank.TEN, suit=Suit.SPADE) king = Card(rank=Rank.KING, suit=Suit.SPADE) self.assertTrue(jack.score_val() == ten.score_val()) self.assertTrue(king.score_val() == ten.score_val()) self.assertFalse(jack == ten) self.assertFalse(jack == king) self.assertFalse(king == ten)
def test_stack_add(self): cs = CardStack() c = Card(rank=Rank.QUEEN, suit=Suit.HEART) self.assertEqual(cs.size(), 0) cs.add(c) self.assertEqual(cs.size(), 1)
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_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_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_stack_peek_sees_top(self): cs = get_test_stack() self.assertEqual(cs.size(), 12) seven_spade = cs.peek() self.assertTrue( seven_spade.is_same_card(Card(rank=Rank.SEVEN, suit=Suit.SPADE))) self.assertEqual(cs.size(), 12)
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_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_stack_remove_last(self): cs = CardStack() c = Card(rank=Rank.QUEEN, suit=Suit.HEART) self.assertEqual(cs.size(), 0) cs.add(c) self.assertEqual(cs.size(), 1) cs.remove(cs.find(c)) self.assertEqual(cs.size(), 0)
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_add_sorts(self): c2 = Card(rank=Rank.TWO, suit=Suit.CLUB) c3 = Card(rank=Rank.THREE, suit=Suit.CLUB) c4 = Card(rank=Rank.FOUR, suit=Suit.CLUB) m = Meld(c2) m.add(c4) m.add(c3) self.assertFalse(m.all_same_rank) self.assertTrue(m.all_same_suit) self.assertTrue(m.is_run) self.assertFalse(m.is_set) self.assertTrue(m.complete) # cards were implicitly re-ordered by add() self.assertEqual(m.cards[0], c2) self.assertEqual(m.cards[1], c3) self.assertEqual(m.cards[2], c4)