diff --git a/model/data.py b/model/data.py index cecf3ed..48b8dd7 100644 --- a/model/data.py +++ b/model/data.py @@ -50,7 +50,7 @@ class Card: return (self.score() == other.score()) def __str__(self) -> str: - return f"{self.color.value} {self.value.name} {self.color.value}" + return f"{self.value.value} {self.color.value}" def score(self) -> int: return int(self.value.value) @@ -68,11 +68,15 @@ class Hand: def __getitem__(self, item): return self.cards[item] + def __repr__(self): + return "|".join([str(c) for c in self.cards]) + def give(self, other: Card): self.cards.append(other) def value(self): counter = Counter([c.value for c in self.cards]) + print("Counter:", counter) has_pair = False has_double_pair = False @@ -90,8 +94,9 @@ class Hand: for element, count in counter.items(): element_cards = [c for c in self.cards if c.value == element] - card = element_cards[0] # Note we take a random color + card = element_cards[0] # Note we take a random color highest_card = max(highest_card, card) if highest_card else card + if count == 2: if has_pair: has_double_pair = True @@ -111,35 +116,30 @@ class Hand: has_carre = True carre = max(carre, card) if carre else card - print("".join([ - f"End of analysis: ", - f"Carre[{carre}]" if has_carre else "no carre | ", - f"Full[{full_des}|{full_par}]" if has_full else "no full | ", - f"Brelan[{brelan}]" if has_brelan else "no carre | ", - f"Double paire[{double_pair}|{pair}]" if has_double_pair else "no Dpaire | ", - f"Paire[{pair}]" if has_pair else "no paire | ", + print(" | ".join([ + f"ANALYSIS", + f"Carre[{carre}]" if has_carre else "no carre", + f"Full[{full_des}|{full_par}]" if has_full else "no full", + f"Brelan[{brelan}]" if has_brelan else "no carre", + f"Double paire[{double_pair}|{pair}]" if has_double_pair else "no Dpaire", + f"Paire[{pair}]" if has_pair else "no paire", f"Card[{highest_card}]" ]), end=" ") # Finished counting, let's return scores if has_carre: - print("LE CARRE, LE CARRE!") - score = (20 ^ 5) * carre.score() + score = (20 ** 5) * carre.score() elif has_full: - print("Fouloulou") - score = (20 ^ 4) * full_des.score() + full_par + score = (20 ** 4) * full_des.score() + full_par.score() elif has_brelan: - print("BRELAN!") - score = (20 ^ 3) * brelan.score() + score = (20 ** 3) * brelan.score() elif has_double_pair: - print("Double Paire!") - score = (20 ^ 2) * double_pair.score() + pair.score() + score = (20 ** 2) * double_pair.score() + pair.score() elif has_pair: - print("Paire!") - score = (20 ^ 2) * pair.score() + score = 20 * pair.score() else: score = highest_card.score() - print("-> score=", score) + print("\t-> score=\t", score) return score diff --git a/model/hands.py b/model/hands.py new file mode 100644 index 0000000..e57e862 --- /dev/null +++ b/model/hands.py @@ -0,0 +1,47 @@ +from model.data import Hand, Card, Color, Value + + +def carre(value) -> Hand: + return Hand([ + Card(value, Color.Hearts), + Card(value, Color.Clubs), + Card(value, Color.Diamonds), + Card(value, Color.Spades) + ]) + + +def brelan(value) -> Hand: + return Hand([ + Card(value, Color.Hearts), + Card(value, Color.Clubs), + Card(value, Color.Diamonds) + ]) + + +def pair(value) -> Hand: + return Hand([ + Card(value, Color.Hearts), + Card(value, Color.Clubs) + ]) + + +def single(low_value) -> Hand: + return Hand([ + Card(low_value, Color.Hearts) + ]) + + +def double_pair(value: Value, other: Value = None): + # Ensure no carre + if not other or other == value: + other = Value.Two if value == Value.Three else Value.Three + assert other != value + + return Hand([ + # Pair of value + Card(value, Color.Hearts), + Card(value, Color.Clubs), + # And pair of twos or threes + Card(other, Color.Hearts), + Card(other, Color.Clubs) + ]) \ No newline at end of file diff --git a/test/test_data.py b/test/test_data.py index bc87aed..fdeaa1c 100644 --- a/test/test_data.py +++ b/test/test_data.py @@ -1,8 +1,16 @@ from unittest import TestCase from model.data import Deck, Player, Card, Value, Color, Hand +from model.hands import brelan, pair, single, double_pair ACE_OF_HEARTS = Card(Value.Ace, Color.Hearts) +ACE_OF_SPADES = Card(Value.Ace, Color.Spades) +ACE_OF_DIAMONDS = Card(Value.Ace, Color.Diamonds) +ACE_OF_CLUBS = Card(Value.Ace, Color.Clubs) + +PAIR_ACE = pair(Value.Ace) +SINGLE_ACE = single(Value.Ace) +DOUBLE_PAIR_ACE = double_pair(Value.Ace) class TestDeck(TestCase): @@ -43,55 +51,82 @@ class TestPlayer(TestCase): pass +def lowest_card_and_rest(): + lowValue: Value = Value.Two + otherValues = list(Value) + otherValues.remove(lowValue) + + return lowValue, otherValues + + class TestHand(TestCase): def setUp(self) -> None: self.hand = Hand() def testSimple(self): - lowValue = Value.Two - for value in [ - Value.Three, - Value.Four, - Value.Five, - Value.Six, - Value.Seven, - Value.Eight, - Value.Nine, - Value.Ten, - Value.Jack, - Value.Queen, - Value.King, - Value.Ace, - ]: - highHand = Hand([Card(value, Color.Hearts)]) - lowHand = Hand([Card(lowValue, Color.Hearts)]) - - self.assertGreater(highHand.value(), lowHand.value()) + low_value, other_values = lowest_card_and_rest() + + for value in other_values: + high_hand = single(value) + low_hand = single(low_value) + + self.assertGreater(high_hand.value(), low_hand.value()) def testPair(self): - lowValue: Value = Value.Two - for value in [ - Value.Three, - Value.Four, - Value.Five, - Value.Six, - Value.Seven, - Value.Eight, - Value.Nine, - Value.Ten, - Value.Jack, - Value.Queen, - Value.King, - Value.Ace, - ]: - highHand: Hand = Hand([Card(value, Color.Hearts), Card(value, Color.Clubs)]) - singleHand: Hand = Hand([ACE_OF_HEARTS]) - lowHand: Hand = Hand([Card(lowValue, Color.Hearts), Card(lowValue, Color.Clubs)]) - - highScore = highHand.value() - singleScore = singleHand.value() - lowScore = lowHand.value() - - self.assertGreater(highScore, singleScore, f"Pair[{highHand.cards}] > Ace") - - self.assertGreater(highScore, lowScore, f"Pair[{highHand.cards}] > Pair[{lowHand.cards}]]") + low_value, other_values = lowest_card_and_rest() + + for value in other_values: + high_hand: Hand = pair(value) + low_hand: Hand = pair(low_value) + single_hand: Hand = single(Value.Ace) + + high_score = high_hand.value() + low_score = low_hand.value() + single_score = single_hand.value() + + self.assertGreater(high_score, low_score, f"Pair[{high_hand}] > Pair[{low_hand}]]") + self.assertGreater(high_score, single_score, f"Pair[{high_hand}] > Ace") + + def testDoublePair(self): + low_value, other_values = lowest_card_and_rest() + + for value in other_values: + high_hand: Hand = double_pair(value) + low_hand: Hand = double_pair(low_value) + pair_hand: Hand = PAIR_ACE + single_hand: Hand = SINGLE_ACE + + high_score = high_hand.value() + low_score = low_hand.value() + pair_score = pair_hand.value() + single_score = single_hand.value() + + # Consider case when we compare equal double pairs + low_cards = [c.value for c in low_hand.cards] + if all([card.value in low_cards for card in high_hand.cards]): + self.assertEqual(high_score, low_score, f"DoublePair[{high_hand}] == DoublePair[{low_hand}]") + else: + self.assertGreater(high_score, low_score, f"DoublePair[{high_hand}] > DoublePair[{low_hand}]") + self.assertGreater(high_score, pair_score, f"DoublePair[{high_hand}] > Pair[Ace]") + self.assertGreater(high_score, single_score, f"DoublePair[{high_hand}] > Ace") + + def testBrelan(self): + low_value, other_values = lowest_card_and_rest() + + for value in other_values: + high_hand: Hand = brelan(value) + low_hand: Hand = brelan(low_value) + double_pair_hand: Hand = DOUBLE_PAIR_ACE + pair_hand: Hand = PAIR_ACE + single_hand: Hand = SINGLE_ACE + + high_score = high_hand.value() + low_score = low_hand.value() + double_pair_score = double_pair_hand.value() + pair_score = pair_hand.value() + single_score = single_hand.value() + + self.assertGreater(high_score, low_score, f"Brelan[{high_hand}] > Brelan[{low_hand}]]") + self.assertGreater(high_score, double_pair_score, f"Brelan[{high_hand}] > Pair[Ace]") + self.assertGreater(high_score, pair_score, f"Brelan[{high_hand}] > Pair[Ace]") + self.assertGreater(high_score, single_score, f"Brelan[{high_hand}] > Ace")