Skip to content

Commit

Permalink
Add new properties and make messages more descriptive
Browse files Browse the repository at this point in the history
  • Loading branch information
AussieSeaweed committed Apr 9, 2024
1 parent c0c9f17 commit c654890
Show file tree
Hide file tree
Showing 9 changed files with 469 additions and 142 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ Changelog

All notable changes to this project will be documented in this file.

Version 0.4.17 (April 9, 2024)
------------------------------

**Changed**

- Make error/warning messages more descriptive.

**Added**

- Censored hole cards ``pokerkit.state.State.get_censored_hole_cards()``.
- Turn index ``pokerkit.state.State.turn_index``.

Version 0.4.16 (April 5, 2024)
------------------------------

Expand Down
8 changes: 7 additions & 1 deletion pokerkit/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ def iterate_interval(s: str) -> Iterator[frozenset[Card]]:
i3 = index(r3)

if i1 - i0 != i3 - i2:
raise ValueError(f'error in pattern {repr(raw_range)}')
raise ValueError(
(
f'Pattern {repr(raw_range)} is invalid because the two'
' pairs of ranks that bounds the dash-separated notation'
' must be a shifted version of the other.'
),
)

if i0 > i2:
i0, i1, i2, i3 = i2, i3, i0, i1
Expand Down
90 changes: 55 additions & 35 deletions pokerkit/hands.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ class Hand(Hashable, ABC):
>>> h0 = ShortDeckHoldemHand('6s7s8s9sTs')
>>> h1 = ShortDeckHoldemHand('7c8c9cTcJc')
>>> h2 = ShortDeckHoldemHand('2c2d2h2s3h')
>>> h2 = ShortDeckHoldemHand('2c2d2h2s3h') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand '2c2d2h2s3h'
ValueError: The cards '2c2d2h2s3h' form an invalid ShortDeckHoldemHand h...
>>> h0
6s7s8s9sTs
>>> h1
Expand Down Expand Up @@ -85,7 +85,12 @@ def __init__(self, cards: CardsLike) -> None:
self.__cards = Card.clean(cards)

if not self.lookup.has_entry(self.cards):
raise ValueError(f'invalid hand \'{repr(self)}\'')
raise ValueError(
(
f'The cards {repr(cards)} form an invalid'
f' {type(self).__qualname__} hand.'
),
)

def __eq__(self, other: Any) -> bool:
if type(self) != type(other): # noqa: E721
Expand Down Expand Up @@ -223,7 +228,12 @@ def from_game(
max_hand = hand

if max_hand is None:
raise ValueError('no valid hand')
raise ValueError(
(
f'No valid {type(cls).__qualname__} hand can be formed'
' from the hole and board cards.'
),
)

return max_hand

Expand All @@ -246,18 +256,18 @@ class StandardHighHand(StandardHand):
>>> h0 < h1 < h2 < h3 < h4
True
>>> h = StandardHighHand('4c5dThJsAcKh2h')
>>> h = StandardHighHand('4c5dThJsAcKh2h') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand '4c5dThJsAcKh2h'
ValueError: The cards '4c5dThJsAcKh2h' form an invalid StandardHighHand ...
>>> h = StandardHighHand('Ac2c3c4c')
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2c3c4c'
ValueError: The cards 'Ac2c3c4c' form an invalid StandardHighHand hand.
>>> h = StandardHighHand(())
Traceback (most recent call last):
...
ValueError: invalid hand ''
ValueError: The cards () form an invalid StandardHighHand hand.
"""

low = False
Expand All @@ -274,18 +284,18 @@ class StandardLowHand(StandardHand):
>>> h0 < h1 < h2 < h3 < h4
True
>>> h = StandardLowHand('4c5dThJsAcKh2h')
>>> h = StandardLowHand('4c5dThJsAcKh2h') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand '4c5dThJsAcKh2h'
ValueError: The cards '4c5dThJsAcKh2h' form an invalid StandardLowHand h...
>>> h = StandardLowHand('Ac2c3c4c')
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2c3c4c'
ValueError: The cards 'Ac2c3c4c' form an invalid StandardLowHand hand.
>>> h = StandardLowHand(())
Traceback (most recent call last):
...
ValueError: invalid hand ''
ValueError: The cards () form an invalid StandardLowHand hand.
"""

low = True
Expand All @@ -304,18 +314,18 @@ class ShortDeckHoldemHand(CombinationHand):
>>> h0 < h1 < h2 < h3 < h4
True
>>> h = ShortDeckHoldemHand('4c5dThJsAcKh2h')
>>> h = ShortDeckHoldemHand('4c5dThJsAcKh2h') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand '4c5dThJsAcKh2h'
>>> h = ShortDeckHoldemHand('Ac2c3c4c5c')
ValueError: The cards '4c5dThJsAcKh2h' form an invalid ShortDeckHoldemHa...
>>> h = ShortDeckHoldemHand('Ac2c3c4c5c') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2c3c4c5c'
ValueError: The cards 'Ac2c3c4c5c' form an invalid ShortDeckHoldemHand ...
>>> h = ShortDeckHoldemHand(())
Traceback (most recent call last):
...
ValueError: invalid hand ''
ValueError: The cards () form an invalid ShortDeckHoldemHand hand.
"""

lookup = ShortDeckHoldemLookup()
Expand All @@ -332,26 +342,26 @@ class EightOrBetterLowHand(CombinationHand):
>>> h0 < h1 < h2
True
>>> h = EightOrBetterLowHand('AcAsAd2s4s')
>>> h = EightOrBetterLowHand('AcAsAd2s4s') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand 'AcAsAd2s4s'
>>> h = EightOrBetterLowHand('TsJsQsKsAs')
ValueError: The cards 'AcAsAd2s4s' form an invalid EightOrBetterLowHand ...
>>> h = EightOrBetterLowHand('TsJsQsKsAs') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand 'TsJsQsKsAs'
>>> h = EightOrBetterLowHand('4c5dThJsAcKh2h')
ValueError: The cards 'TsJsQsKsAs' form an invalid EightOrBetterLowHand ...
>>> h = EightOrBetterLowHand('4c5dThJsAcKh2h') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: invalid hand '4c5dThJsAcKh2h'
ValueError: The cards '4c5dThJsAcKh2h' form an invalid EightOrBetterLowH...
>>> h = EightOrBetterLowHand('Ac2c3c4c')
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2c3c4c'
ValueError: The cards 'Ac2c3c4c' form an invalid EightOrBetterLowHand hand.
>>> h = EightOrBetterLowHand(())
Traceback (most recent call last):
...
ValueError: invalid hand ''
ValueError: The cards () form an invalid EightOrBetterLowHand hand.
"""

lookup = EightOrBetterLookup()
Expand All @@ -374,11 +384,11 @@ class RegularLowHand(CombinationHand):
>>> h = RegularLowHand('4c5dThJsAcKh2h')
Traceback (most recent call last):
...
ValueError: invalid hand '4c5dThJsAcKh2h'
ValueError: The cards '4c5dThJsAcKh2h' form an invalid RegularLowHand hand.
>>> h = RegularLowHand(())
Traceback (most recent call last):
...
ValueError: invalid hand ''
ValueError: The cards () form an invalid RegularLowHand hand.
"""

lookup = RegularLookup()
Expand Down Expand Up @@ -434,7 +444,12 @@ def from_game(
max_hand = hand

if max_hand is None:
raise ValueError('no valid hand')
raise ValueError(
(
f'No valid {type(cls).__qualname__} hand can be formed'
' from the hole and board cards.'
),
)

return max_hand

Expand Down Expand Up @@ -521,7 +536,12 @@ def from_game(
max_hand = hand

if max_hand is None:
raise ValueError('no valid hand')
raise ValueError(
(
f'No valid {type(cls).__qualname__} hand can be formed'
' from the hole and board cards.'
),
)

return max_hand

Expand Down Expand Up @@ -579,23 +599,23 @@ class BadugiHand(Hand):
>>> h = BadugiHand('Ac2d3c4s5c')
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2d3c4s5c'
ValueError: The cards 'Ac2d3c4s5c' form an invalid BadugiHand hand.
>>> h = BadugiHand('Ac2d3c4s')
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2d3c4s'
ValueError: The cards 'Ac2d3c4s' form an invalid BadugiHand hand.
>>> h = BadugiHand('AcAd3h4s')
Traceback (most recent call last):
...
ValueError: invalid hand 'AcAd3h4s'
ValueError: The cards 'AcAd3h4s' form an invalid BadugiHand hand.
>>> h = BadugiHand('Ac2c')
Traceback (most recent call last):
...
ValueError: invalid hand 'Ac2c'
ValueError: The cards 'Ac2c' form an invalid BadugiHand hand.
>>> h = BadugiHand(())
Traceback (most recent call last):
...
ValueError: invalid hand ''
ValueError: The cards () form an invalid BadugiHand hand.
"""

lookup = BadugiLookup()
Expand Down Expand Up @@ -676,7 +696,7 @@ class KuhnPokerHand(Hand):
>>> h = KuhnPokerHand('As')
Traceback (most recent call last):
...
ValueError: invalid hand 'As'
ValueError: The cards 'As' form an invalid KuhnPokerHand hand.
"""

lookup = KuhnPokerLookup()
Expand Down
25 changes: 15 additions & 10 deletions pokerkit/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def __post_init__(self) -> None:

@abstractmethod
def _add_entries(self) -> None:
pass
pass # pragma: no cover

def __reset_ranks(self) -> None:
indices = set()
Expand Down Expand Up @@ -206,7 +206,7 @@ def get_entry(self, cards: CardsLike) -> Entry:
>>> entry = lookup.get_entry('Ah6h7s8c2s')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards 'Ah6h7s8c2s' form an invalid hand.
:param cards: The cards to look up.
:return: The corresponding lookup entry.
Expand All @@ -215,7 +215,7 @@ def get_entry(self, cards: CardsLike) -> Entry:
key = self._get_key(cards)

if key not in self.__entries:
raise ValueError('cards form an invalid hand')
raise ValueError(f'The cards {repr(cards)} form an invalid hand.')

return self.__entries[key]

Expand All @@ -227,7 +227,7 @@ def get_entry_or_none(self, cards: CardsLike) -> Entry | None:
>>> lookup.get_entry('Ah6h7s8c2s')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards 'Ah6h7s8c2s' form an invalid hand.
>>> lookup.get_entry_or_none('Ah6h7s8c2s') is None
True
Expand Down Expand Up @@ -300,7 +300,7 @@ class StandardLookup(Lookup):
>>> e2 = lookup.get_entry('AcAdAhAsAc')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards 'AcAdAhAsAc' form an invalid hand.
>>> e0 < e1
True
>>> e0.label
Expand Down Expand Up @@ -346,7 +346,7 @@ class ShortDeckHoldemLookup(Lookup):
>>> e2 = lookup.get_entry('Ah2h3s4c5s')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards 'Ah2h3s4c5s' form an invalid hand.
>>> e0 < e1
True
>>> e0.label
Expand Down Expand Up @@ -406,7 +406,7 @@ class RegularLookup(Lookup):
>>> e2 = lookup.get_entry('3s4sQhTc')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards '3s4sQhTc' form an invalid hand.
>>> e0 < e1
True
>>> e0.label
Expand Down Expand Up @@ -447,7 +447,7 @@ class BadugiLookup(Lookup):
>>> e2 = lookup.get_entry('AcAdAhAs')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards 'AcAdAhAs' form an invalid hand.
>>> e0 > e1
True
>>> e0.label
Expand All @@ -466,7 +466,12 @@ def _get_key(self, cards: CardsLike) -> tuple[int, bool]:
cards = Card.clean(cards)

if not Card.are_rainbow(cards):
raise ValueError('cards not rainbow')
raise ValueError(
(
'Badugi hands must be rainbow (i.e. of distinct suits) but'
f' the cards {repr(cards)} are not.'
),
)

return super()._get_key(cards)

Expand Down Expand Up @@ -495,7 +500,7 @@ class KuhnPokerLookup(Lookup):
>>> e2 = lookup.get_entry('2?')
Traceback (most recent call last):
...
ValueError: cards form an invalid hand
ValueError: The cards '2?' form an invalid hand.
>>> e0 < e1
True
>>> e0.label
Expand Down
Loading

0 comments on commit c654890

Please sign in to comment.