""" Integration tests for Short Deck Poker implementation """ import pytest from poker.card import Card, ShortDeckRank, Suit # 使用统一的Card类 from shortdeck import ShortDeckHandEvaluator, ShortDeckHandType, ShortDeckHandRanking class TestShortDeckIntegration: """Integration tests for the complete short deck poker system""" def test_shortdeck_example_cases(self): """Test various short deck example hands""" # Test cases with expected results test_cases = [ # Royal Flush ("AsKsQsJsTs", ShortDeckHandType.ROYAL_FLUSH, "Royal Flush"), # Straight Flush (not royal) ("KsQsJsTs9s", ShortDeckHandType.STRAIGHT_FLUSH, "Straight Flush(K high)"), # Four of a Kind ("AsAhAdAcKs", ShortDeckHandType.FOUR_OF_A_KIND, "Quad(A)"), # Flush (beats Full House in Short Deck!) ("AsKsQsJs9s", ShortDeckHandType.FLUSH, "Flush(A high)"), # Full House (weaker than Flush in Short Deck) ("AsAhAdKsKh", ShortDeckHandType.FULL_HOUSE, "Full House(A over K)"), # Straight - regular ("AsKsQhJdTs", ShortDeckHandType.STRAIGHT, "Straight(A high)"), # Straight - short deck wheel (A-6-7-8-9) ("As9h8d7c6s", ShortDeckHandType.STRAIGHT, "Straight(9 high)"), # Three of a Kind ("AsAhAdKsQs", ShortDeckHandType.THREE_OF_A_KIND, "Three of a Kind(A)"), # Two Pair ("AsAhKdKsQs", ShortDeckHandType.TWO_PAIR, "Two Pair(A and K)"), # One Pair ("AsAhKdQsJs", ShortDeckHandType.ONE_PAIR, "Pair(A)"), # High Card ("AsKhQdJs9s", ShortDeckHandType.HIGH_CARD, "High Card(A)") ] for hand_str, expected_type, expected_str in test_cases: result = ShortDeckHandEvaluator.evaluate_from_input(hand_str) assert result.hand_type == expected_type, f"Failed for {hand_str}: expected {expected_type}, got {result.hand_type}" assert str(result) == expected_str, f"Failed string for {hand_str}: expected '{expected_str}', got '{str(result)}'" def test_shortdeck_seven_card_hands(self): """Test evaluation with 7 cards (like Texas Hold'em)""" # Should find the best 5-card hand from 7 cards test_cases = [ # Four of a kind + extra cards ("AsAhAdAcKs Qs 6h", ShortDeckHandType.FOUR_OF_A_KIND, "Quad(A)"), # Full house from 7 cards ("AsAhAdKsKh Qc 7d", ShortDeckHandType.FULL_HOUSE, "Full House(A over K)"), # Flush with extra cards ("AsKsQsJsTs 6h 7c", ShortDeckHandType.ROYAL_FLUSH, "Royal Flush"), ] for hand_str, expected_type, expected_str in test_cases: result = ShortDeckHandEvaluator.evaluate_from_input(hand_str) assert result.hand_type == expected_type assert str(result) == expected_str def test_shortdeck_flush_vs_full_house(self): """Test the key Short Deck rule: Flush beats Full House""" # Create flush flush_hand = "AsKsQsJs9s" # A-high flush flush_result = ShortDeckHandEvaluator.evaluate_from_input(flush_hand) # Create full house full_house_hand = "AsAhAdKsKh" # Aces full of Kings full_house_result = ShortDeckHandEvaluator.evaluate_from_input(full_house_hand) # Flush should beat Full House assert flush_result > full_house_result assert flush_result.hand_type == ShortDeckHandType.FLUSH assert full_house_result.hand_type == ShortDeckHandType.FULL_HOUSE def test_shortdeck_wheel_straight(self): """Test Short Deck wheel straight: A-6-7-8-9""" # Wheel straight wheel_hand = "As9h8d7c6s" wheel_result = ShortDeckHandEvaluator.evaluate_from_input(wheel_hand) # Regular straight regular_hand = "TsJhQdKcAs" regular_result = ShortDeckHandEvaluator.evaluate_from_input(regular_hand) assert wheel_result.hand_type == ShortDeckHandType.STRAIGHT assert regular_result.hand_type == ShortDeckHandType.STRAIGHT # A-high straight should beat 9-high wheel assert regular_result > wheel_result # Check string representations assert str(wheel_result) == "Straight(9 high)" assert str(regular_result) == "Straight(A high)" def test_no_invalid_short_deck_cards(self): """Test that cards 2, 3, 4, 5 are properly rejected""" invalid_hands = [ "2s3s4s5s6s", # Contains 2, 3, 4, 5 "AsKs2h3h4h", # Mixed valid and invalid "5sAsKsQsJs" # Contains 5 ] for invalid_hand in invalid_hands: with pytest.raises(ValueError, match="Invalid rank for short deck"): ShortDeckHandEvaluator.evaluate_from_input(invalid_hand) def test_all_short_deck_straights(self): """Test all 6 possible straights in Short Deck""" straight_tests = [ ("As9h8d7c6s", "Straight(9 high)"), # A-6-7-8-9 (wheel) ("TsJhQdKcAs", "Straight(A high)"), # T-J-Q-K-A (broadway) ("Ts9h8d7c6s", "Straight(T high)"), # 6-7-8-9-T ("JsTh9d8c7s", "Straight(J high)"), # 7-8-9-T-J ("QsJhTd9c8s", "Straight(Q high)"), # 8-9-T-J-Q ("KsQhJdTc9s", "Straight(K high)"), # 9-T-J-Q-K ] for hand_str, expected_str in straight_tests: result = ShortDeckHandEvaluator.evaluate_from_input(hand_str) assert result.hand_type == ShortDeckHandType.STRAIGHT assert str(result) == expected_str def test_shortdeck_card_count(self): """Test that Short Deck has exactly 36 cards""" # 使用Card类的ShortDeck模式 all_cards = [] for rank in ShortDeckRank: for suit in Suit: all_cards.append(Card(rank, suit)) assert len(all_cards) == 36 # 9 ranks * 4 suits # Verify no duplicates card_strings = [str(card) for card in all_cards] assert len(set(card_strings)) == 36 # Verify all ranks 6-A are present ranks_present = set(card.rank for card in all_cards) expected_ranks = set(ShortDeckRank) assert ranks_present == expected_ranks # Verify no low cards (2,3,4,5) for card in all_cards: assert card.rank.numeric_value >= 6 def test_shortdeck_hand_rankings_order(self): """Test the complete hand ranking order for Short Deck""" # Create hands of different types hands = [ ("AsKhQdJs9c", ShortDeckHandType.HIGH_CARD), # High Card ("AsAhKdQsJc", ShortDeckHandType.ONE_PAIR), # One Pair ("AsAhKdKsQc", ShortDeckHandType.TWO_PAIR), # Two Pair ("AsAhAdKsQc", ShortDeckHandType.THREE_OF_A_KIND), # Three of a Kind ("AsKhQdJsTc", ShortDeckHandType.STRAIGHT), # Straight ("AsAhAdKsKc", ShortDeckHandType.FULL_HOUSE), # Full House ("AsKsQsJs9s", ShortDeckHandType.FLUSH), # Flush (beats Full House!) ("AsAhAdAcKs", ShortDeckHandType.FOUR_OF_A_KIND), # Four of a Kind ("9s8s7s6sTs", ShortDeckHandType.STRAIGHT_FLUSH), # Straight Flush ("AsKsQsJsTs", ShortDeckHandType.ROYAL_FLUSH), # Royal Flush ] results = [] for hand_str, expected_type in hands: result = ShortDeckHandEvaluator.evaluate_from_input(hand_str) assert result.hand_type == expected_type results.append(result) # Test that they are in ascending order of strength for i in range(len(results) - 1): assert results[i] < results[i + 1], f"{results[i].hand_type} should be less than {results[i + 1].hand_type}" def test_shortdeck_main_script_functionality(self): """Test that the main script input format works correctly""" # Test various input formats that the main script should handle test_inputs = [ "AsKsQsJsTs", # 5 cards "AsKs QsJs TsAh Ad", # 7 cards with spaces "6s7s8s9sTs", # Low straight flush ] for input_str in test_inputs: # This should not raise an exception result = ShortDeckHandEvaluator.evaluate_from_input(input_str) assert result is not None assert hasattr(result, 'hand_type') assert hasattr(result, 'key_ranks') assert len(str(result)) > 0 def test_edge_cases(self): """Test various edge cases""" # All same rank except one (should be four of a kind) result1 = ShortDeckHandEvaluator.evaluate_from_input("6s6h6d6cAs") assert result1.hand_type == ShortDeckHandType.FOUR_OF_A_KIND # Almost straight but not quite result2 = ShortDeckHandEvaluator.evaluate_from_input("AsKhQdJs8c") # Missing 10 assert result2.hand_type == ShortDeckHandType.HIGH_CARD # Almost flush but not quite result3 = ShortDeckHandEvaluator.evaluate_from_input("AsKsQsJs8h") # Mixed suits, not straight assert result3.hand_type == ShortDeckHandType.HIGH_CARD