Skip to content

Commit

Permalink
Gin rummy (#46)
Browse files Browse the repository at this point in the history
* mypy everything

* run mypy over everything

* add gin rummy [wip]
'

* add more gin rummy logic

* turns

* fx mypy

* OK

* do it

* gin rummy

* OK

* deadwood calculation

* deadwood is done

* types

* OK
  • Loading branch information
cdrappi authored May 29, 2023
1 parent dd12d3b commit 997b0a8
Show file tree
Hide file tree
Showing 21 changed files with 1,413 additions and 792 deletions.
26 changes: 15 additions & 11 deletions card_utils/deck/__init__.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
""" constants to build the deck of cards and score the game """

ranks = list('23456789TJQKA')
suits = list('cdhs')
from typing import List, Tuple

cards = [f'{r}{s}' for r in ranks for s in suits]
ranks: List[str] = list("23456789TJQKA")
suits: List[str] = list("cdhs")

card_choices = [(f'{rank}{suit}', f'{rank} of {suit}')
for (rank, suit) in cards]
cards: List[str] = [f"{r}{s}" for r in ranks for s in suits]
_cards_rds: List[Tuple[str, str]] = [(r, s) for r in ranks for s in suits]

suit_ids = {'c': 0, 'd': 1, 'h': 2, 's': 3}
card_choices = [
(f"{rank}{suit}", f"{rank} of {suit}") for (rank, suit) in _cards_rds
]

suit_ids = {"c": 0, "d": 1, "h": 2, "s": 3}
rank_ids = {rank: index for index, rank in enumerate(ranks)}

card_id_map = {card: index for index, card in enumerate(cards)}
reverse_card_id_map = {index: card for card, index in card_id_map.items()}

digit_map = {d: int(d) for d in '23456789'}
common_rank_to_value = {'T': 10, 'J': 11, 'Q': 12, 'K': 13}
digit_map = {d: int(d) for d in "23456789"}
common_rank_to_value = {"T": 10, "J": 11, "Q": 12, "K": 13}
common_rank_to_value.update(digit_map)

ace_high_rank_to_value = {'A': 14}
ace_high_rank_to_value = {"A": 14}
ace_high_rank_to_value.update(common_rank_to_value)

ace_low_rank_to_value = {'A': 1}
ace_low_rank_to_value = {"A": 1}
ace_low_rank_to_value.update(common_rank_to_value)

rank_to_value = ace_low_rank_to_value

value_to_rank = {14: 'A', 1: 'A'}
value_to_rank = {14: "A", 1: "A"}
value_to_rank.update({v: r for r, v in common_rank_to_value.items()})
33 changes: 21 additions & 12 deletions card_utils/deck/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import random

from typing import List, Dict
from card_utils import deck


def random_deck():
Card = str


def random_deck() -> List[Card]:
"""
:return: ([str]) randomly shuffled deck of 52 cards
"""
Expand All @@ -12,12 +15,12 @@ def random_deck():
return deck_copy


def rank_partition(cards):
def rank_partition(cards) -> Dict[str, List[str]]:
"""
:param cards: ([str])
:return: ({str: [str]} rank --> [suit]
"""
rank_to_suits = {}
rank_to_suits: Dict[str, List[str]] = {}
for rank, suit in cards:
if rank not in rank_to_suits:
rank_to_suits[rank] = []
Expand All @@ -26,12 +29,12 @@ def rank_partition(cards):
return rank_to_suits


def suit_partition(cards):
def suit_partition(cards) -> Dict[str, List[str]]:
"""
:param cards: ([str])
:return: ({str: [str]} suit --> [ranks]
"""
suit_to_ranks = {}
suit_to_ranks: Dict[str, List[str]] = {}
for rank, suit in cards:
if suit not in suit_to_ranks:
suit_to_ranks[suit] = []
Expand All @@ -40,7 +43,13 @@ def suit_partition(cards):
return suit_to_ranks


def ranks_to_sorted_values(ranks, aces_high, aces_low, distinct=False, reverse=False):
def ranks_to_sorted_values(
ranks,
aces_high,
aces_low,
distinct=False,
reverse=False,
) -> List[int]:
"""
:param ranks: ([str])
:param aces_high: (bool)
Expand All @@ -54,8 +63,8 @@ def ranks_to_sorted_values(ranks, aces_high, aces_low, distinct=False, reverse=F

if not (aces_high or aces_low):
raise ValueError(
'Call to ranks_to_sorted_values: '
'Aces cannot be neither high nor low! Makes no sense'
"Call to ranks_to_sorted_values: "
"Aces cannot be neither high nor low! Makes no sense"
)

if distinct:
Expand All @@ -65,13 +74,13 @@ def ranks_to_sorted_values(ranks, aces_high, aces_low, distinct=False, reverse=F

for rank in ranks:
value = deck.ace_low_rank_to_value[rank]
if value == deck.ace_low_rank_to_value['A']:
if value == deck.ace_low_rank_to_value["A"]:
if aces_low:
# 1
values.append(deck.ace_low_rank_to_value['A'])
values.append(deck.ace_low_rank_to_value["A"])
if aces_high:
# 14
values.append(deck.ace_high_rank_to_value['A'])
values.append(deck.ace_high_rank_to_value["A"])
else:
values.append(value)

Expand Down
10 changes: 5 additions & 5 deletions card_utils/games/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import List
from typing import Dict, List, Tuple

from card_utils.deck import ace_high_rank_to_value, cards, suits
from card_utils.deck import ace_high_rank_to_value, suits
from card_utils.deck.utils import suit_partition


def canonize_hand(hand: List[str]) -> List[str]:
def canonize_hand(hand: List[str]) -> Tuple[List[str], Dict[str, str]]:
"""
:param hand: (List[str])
:return: (List[str])
Expand All @@ -14,8 +14,8 @@ def canonize_hand(hand: List[str]) -> List[str]:
ordered_suits = sorted(hand_suits, key=lambda k: (-len(hand_suits[k]), k))
suit_map = dict(zip(ordered_suits, suits))
hand = [
f'{rank}{suit_map[suit]}'
f"{rank}{suit_map[suit]}"
for suit in ordered_suits
for rank in sorted(hand_suits[suit], key=ace_high_rank_to_value.get)
for rank in sorted(hand_suits[suit], key=ace_high_rank_to_value.get) # type: ignore
]
return hand, suit_map
23 changes: 0 additions & 23 deletions card_utils/games/gin/deal.py

This file was deleted.

Loading

0 comments on commit 997b0a8

Please sign in to comment.