Skip to content

Commit 56ac6c2

Browse files
committed
basic compare_hands 2
1 parent 220dfdf commit 56ac6c2

4 files changed

Lines changed: 102 additions & 53 deletions

File tree

src/poker/card.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from dataclasses import dataclass
44
from collections import Counter
55

6+
from collections import Counter
67

78
class Suit(Enum):
89
CLUBS = 'c'
@@ -76,7 +77,10 @@ def get_similar_cards(hand: Hand) -> Dict[str, List]:
7677

7778
def is_flush(hand: List[Card]) -> bool:
7879
suits = [card.suit for card in hand]
79-
return len(set(suits)) == 1
80+
81+
suit_counts = Counter(card.suit for card in hand)
82+
return any(count >= 5 for count in suit_counts.values())
83+
#return len(set(suits)) == 1
8084

8185
def is_straight(hand: List[Card]) -> Tuple[bool, int]:
8286
faces = sorted([face_values[card.face.value] for card in hand])
@@ -85,7 +89,7 @@ def is_straight(hand: List[Card]) -> Tuple[bool, int]:
8589
if len(unique_faces) < 5:
8690
return False, 0
8791

88-
for i in range(len(unique_faces) - 4):
92+
for i in range(len(unique_faces) - 5, -1, -1):
8993
if unique_faces[i:i+5] == list(range(unique_faces[i], unique_faces[i]+5)):
9094
return True, unique_faces[i+4]
9195
# specific case with ace when we have a low straight
@@ -107,6 +111,8 @@ def identify_hand(hand: Hand) -> str:
107111
flush = is_flush(hand)
108112
straight, high_card = is_straight(hand)
109113

114+
if len(hand) < 7:
115+
return "Folded"
110116
if is_royal_flush(hand):
111117
return "Royal Flush"
112118
elif straight and flush:

src/poker/compare_hands.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
1-
def compare_hands(hand1, hand2):
2-
"""
3-
Compare two poker hands and determine the winner.
1+
from poker.card import Hand, identify_hand
42

5-
Args:
6-
hand1 (list): The first poker hand.
7-
hand2 (list): The second poker hand.
8-
9-
Returns:
10-
str: A message indicating which hand wins or if it's a tie.
11-
"""
12-
# Placeholder for actual comparison logic
13-
# This should be replaced with the actual implementation that compares the hands
14-
if len(hand1) > len(hand2):
15-
return "Hand 1 wins"
16-
elif len(hand1) < len(hand2):
17-
return "Hand 2 wins"
18-
else:
19-
return "It's a tie"
3+
def compare_hands(hand1: Hand, hand2: Hand) -> str:
4+
hand1_rank = identify_hand(hand1)
5+
hand2_rank = identify_hand(hand2)
6+
return f"{hand1_rank} - {hand2_rank}"

tests/poker/test_card.py

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ def test_parse_cards():
1717
assert parse_cards(input_line) == expected
1818

1919

20-
21-
22-
2320
test_data = [
2421
("test_full_house", [
2522
Card(face=Face.KING, suit=Suit.CLUBS),
@@ -40,10 +37,11 @@ def test_parse_cards():
4037
Card(face=Face.KING, suit=Suit.SPADES),
4138
Card(face=Face.NINE, suit=Suit.DIAMONDS),
4239
Card(face=Face.THREE, suit=Suit.CLUBS),
43-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
40+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
41+
Card(face=Face.FOUR, suit=Suit.DIAMONDS)
4442
], {
4543
'combinations': [(2, 'K'), (2, '9')],
46-
'kickers': ['6', '3']
44+
'kickers': ['6', '4', '3']
4745
}),
4846

4947
("test_three_of_a_kind", [
@@ -52,36 +50,42 @@ def test_parse_cards():
5250
Card(face=Face.KING, suit=Suit.SPADES),
5351
Card(face=Face.KING, suit=Suit.DIAMONDS),
5452
Card(face=Face.THREE, suit=Suit.CLUBS),
55-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
53+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
54+
Card(face=Face.EIGHT, suit=Suit.DIAMONDS)
5655
], {
5756
'combinations': [(3, 'K')],
58-
'kickers': ['9', '6', '3']
57+
'kickers': ['9', '8', '6', '3']
5958
}),
6059

6160
("test_pair", [
6261
Card(face=Face.KING, suit=Suit.CLUBS),
6362
Card(face=Face.NINE, suit=Suit.SPADES),
6463
Card(face=Face.KING, suit=Suit.SPADES),
6564
Card(face=Face.THREE, suit=Suit.CLUBS),
66-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
65+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
66+
Card(face=Face.FOUR, suit=Suit.DIAMONDS),
67+
Card(face=Face.SEVEN, suit=Suit.HEARTS)
6768
], {
6869
'combinations': [(2, 'K')],
69-
'kickers': ['9', '6', '3']
70+
'kickers': ['9', '7', '6', '4', '3']
7071
}),
7172

7273
("test_high_card", [
7374
Card(face=Face.KING, suit=Suit.CLUBS),
7475
Card(face=Face.NINE, suit=Suit.SPADES),
7576
Card(face=Face.THREE, suit=Suit.CLUBS),
76-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
77+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
78+
Card(face=Face.ACE, suit=Suit.HEARTS),
79+
Card(face=Face.FIVE, suit=Suit.CLUBS),
80+
Card(face=Face.TEN, suit=Suit.DIAMONDS),
7781
], {
7882
'combinations': [],
79-
'kickers': ['K', '9', '6', '3']
83+
'kickers': ['T', 'K', 'A', '9', '6', '5', '3']
8084
}),
8185
]
8286

8387
@pytest.mark.parametrize("name, hand, expected", test_data)
84-
def test_get_hand_ranks(name, hand, expected):
88+
def test_get_similar_cards(name, hand, expected):
8589
assert get_similar_cards(hand) == expected
8690

8791

@@ -109,78 +113,103 @@ def test_identify_hand():
109113
Card(face=Face.THREE, suit=Suit.CLUBS),
110114
Card(face=Face.SIX, suit=Suit.DIAMONDS)
111115
], "Full House"),
112-
116+
("test_folded_2_cards", [
117+
Card(face=Face.NINE, suit=Suit.HEARTS),
118+
Card(face=Face.FIVE, suit=Suit.SPADES),
119+
], "Folded"),
113120
("test_two_pair", [
114121
Card(face=Face.KING, suit=Suit.CLUBS),
115122
Card(face=Face.NINE, suit=Suit.SPADES),
116123
Card(face=Face.KING, suit=Suit.SPADES),
117124
Card(face=Face.NINE, suit=Suit.DIAMONDS),
118125
Card(face=Face.THREE, suit=Suit.CLUBS),
119-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
126+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
127+
Card(face=Face.TWO, suit=Suit.HEARTS)
120128
], "Two Pair"),
121-
122129
("test_three_of_a_kind", [
123130
Card(face=Face.KING, suit=Suit.CLUBS),
124131
Card(face=Face.NINE, suit=Suit.SPADES),
125132
Card(face=Face.KING, suit=Suit.SPADES),
126133
Card(face=Face.KING, suit=Suit.DIAMONDS),
127134
Card(face=Face.THREE, suit=Suit.CLUBS),
128-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
135+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
136+
Card(face=Face.EIGHT, suit=Suit.HEARTS)
129137
], "Three of a Kind"),
130138

131139
("test_pair", [
132140
Card(face=Face.KING, suit=Suit.CLUBS),
133141
Card(face=Face.NINE, suit=Suit.SPADES),
134142
Card(face=Face.KING, suit=Suit.SPADES),
135143
Card(face=Face.THREE, suit=Suit.CLUBS),
136-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
144+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
145+
Card(face=Face.FIVE, suit=Suit.HEARTS),
146+
Card(face=Face.SEVEN, suit=Suit.DIAMONDS)
137147
], "Pair"),
138148

139149
("test_high_card", [
140150
Card(face=Face.KING, suit=Suit.CLUBS),
141-
Card(face=Face.NINE, suit=Suit.SPADES),
151+
Card(face=Face.FOUR, suit=Suit.SPADES),
142152
Card(face=Face.THREE, suit=Suit.CLUBS),
143-
Card(face=Face.SIX, suit=Suit.DIAMONDS)
153+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
154+
Card(face=Face.EIGHT, suit=Suit.CLUBS),
155+
Card(face=Face.TEN, suit=Suit.DIAMONDS),
156+
Card(face=Face.SEVEN, suit=Suit.HEARTS),
144157
], "High Card"),
145158
("test_straight", [
146159
Card(face=Face.FIVE, suit=Suit.CLUBS),
147160
Card(face=Face.NINE, suit=Suit.SPADES),
148161
Card(face=Face.SIX, suit=Suit.SPADES),
149162
Card(face=Face.SEVEN, suit=Suit.DIAMONDS),
150163
Card(face=Face.EIGHT, suit=Suit.CLUBS),
151-
Card(face=Face.TEN, suit=Suit.DIAMONDS)
164+
Card(face=Face.TEN, suit=Suit.DIAMONDS),
165+
Card(face=Face.TEN, suit=Suit.HEARTS),
152166
], "Straight"),
153167
("test_flush", [
154168
Card(face=Face.FOUR, suit=Suit.CLUBS),
155169
Card(face=Face.NINE, suit=Suit.CLUBS),
156170
Card(face=Face.THREE, suit=Suit.CLUBS),
157171
Card(face=Face.SEVEN, suit=Suit.CLUBS),
158172
Card(face=Face.EIGHT, suit=Suit.CLUBS),
159-
Card(face=Face.TEN, suit=Suit.CLUBS)
173+
Card(face=Face.TEN, suit=Suit.CLUBS),
174+
Card(face=Face.TEN, suit=Suit.HEARTS),
160175
], "Flush"),
161176
("test_straight_flush", [
162177
Card(face=Face.FOUR, suit=Suit.CLUBS),
163178
Card(face=Face.NINE, suit=Suit.CLUBS),
164179
Card(face=Face.SIX, suit=Suit.CLUBS),
165180
Card(face=Face.SEVEN, suit=Suit.CLUBS),
166181
Card(face=Face.EIGHT, suit=Suit.CLUBS),
167-
Card(face=Face.TEN, suit=Suit.CLUBS)
182+
Card(face=Face.TEN, suit=Suit.CLUBS),
183+
Card(face=Face.TEN, suit=Suit.HEARTS),
168184
], "Straight Flush"),
169185
("test_royal_flush", [
170186
Card(face=Face.ACE, suit=Suit.CLUBS),
171187
Card(face=Face.JACK, suit=Suit.CLUBS),
172188
Card(face=Face.KING, suit=Suit.CLUBS),
173189
Card(face=Face.QUEEN, suit=Suit.CLUBS),
174-
Card(face=Face.TEN, suit=Suit.CLUBS)
190+
Card(face=Face.TEN, suit=Suit.CLUBS),
191+
Card(face=Face.TEN, suit=Suit.HEARTS),
192+
Card(face=Face.NINE, suit=Suit.HEARTS),
175193
], "Royal Flush"),
176194
("test_four_of_a_kind", [
177195
Card(face=Face.ACE, suit=Suit.CLUBS),
178196
Card(face=Face.ACE, suit=Suit.SPADES),
179197
Card(face=Face.ACE, suit=Suit.DIAMONDS),
180198
Card(face=Face.ACE, suit=Suit.HEARTS),
181-
Card(face=Face.TEN, suit=Suit.CLUBS)
199+
Card(face=Face.TEN, suit=Suit.CLUBS),
200+
Card(face=Face.NINE, suit=Suit.SPADES),
201+
Card(face=Face.SEVEN, suit=Suit.CLUBS),
182202
], "Four of a Kind"),
203+
("test flush and pair", [
204+
Card(face=Face.FOUR, suit=Suit.DIAMONDS),
205+
Card(face=Face.TWO, suit=Suit.DIAMONDS),
206+
Card(face=Face.KING, suit=Suit.SPADES),
207+
Card(face=Face.KING, suit=Suit.DIAMONDS),
208+
Card(face=Face.NINE, suit=Suit.DIAMONDS),
209+
Card(face=Face.THREE, suit=Suit.CLUBS),
210+
Card(face=Face.SIX, suit=Suit.DIAMONDS)
211+
], "Flush"),
183212
]
184213
@pytest.mark.parametrize("name, hand, expected", test_data_identify_hand)
185214
def test_identify_hand(name, hand, expected):
186-
assert identify_hand(hand) == expected
215+
assert identify_hand(hand) == expected

tests/poker/test_compare_hands.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
def test_compare_hands():
2-
from poker.compare_hands import compare_hands
3-
from poker.card import Card, Face, Suit
1+
from poker.compare_hands import compare_hands
2+
from poker.card import Card, Face, Suit
43

4+
def test_compare_hands():
55
# GIVEN
6-
hand1 = [
6+
hand1 = [ #Kc 9s Ks Kd 9d 3c 6d Full House
77
Card(face=Face.KING, suit=Suit.CLUBS),
88
Card(face=Face.NINE, suit=Suit.SPADES),
99
Card(face=Face.KING, suit=Suit.SPADES),
@@ -13,16 +13,43 @@ def test_compare_hands():
1313
Card(face=Face.SIX, suit=Suit.DIAMONDS)
1414
]
1515

16-
hand2 = [
17-
Card(face=Face.KING, suit=Suit.CLUBS),
18-
Card(face=Face.NINE, suit=Suit.SPADES),
16+
hand2 = [ #9c Ah Ks Kd 9d 3c 6d
17+
Card(face=Face.NINE, suit=Suit.CLUBS),
18+
Card(face=Face.ACE, suit=Suit.HEARTS),
1919
Card(face=Face.KING, suit=Suit.SPADES),
20+
Card(face=Face.KING, suit=Suit.DIAMONDS),
21+
Card(face=Face.NINE, suit=Suit.DIAMONDS),
22+
Card(face=Face.SIX, suit=Suit.DIAMONDS),
23+
Card(face=Face.THREE, suit=Suit.CLUBS)
24+
25+
]
26+
27+
# WHEN
28+
result = compare_hands(hand1, hand2)
29+
30+
# THEN
31+
assert result == "Full House - Two Pair"
32+
33+
def test_compare_hands_2():
34+
# GIVEN
35+
hand1 = [ #4d 2d Ks Kd 9d 3c 6d Flush
36+
Card(face=Face.FOUR, suit=Suit.DIAMONDS),
37+
Card(face=Face.TWO, suit=Suit.DIAMONDS),
38+
Card(face=Face.KING, suit=Suit.SPADES),
39+
Card(face=Face.KING, suit=Suit.DIAMONDS),
40+
Card(face=Face.NINE, suit=Suit.DIAMONDS),
2041
Card(face=Face.THREE, suit=Suit.CLUBS),
2142
Card(face=Face.SIX, suit=Suit.DIAMONDS)
2243
]
2344

45+
hand2 = [ #9c 5s
46+
Card(face=Face.NINE, suit=Suit.HEARTS),
47+
Card(face=Face.FIVE, suit=Suit.SPADES),
48+
49+
]
50+
2451
# WHEN
2552
result = compare_hands(hand1, hand2)
2653

2754
# THEN
28-
assert result == "Hand 1 wins" # Adjust based on actual implementation logic
55+
assert result == "Flush - Folded"

0 commit comments

Comments
 (0)