Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 83 additions & 15 deletions cribbage/scoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,23 @@ def __init__(self):
def check(self, hand):
raise NotImplementedError


class HasPairTripleQuad(ScoreCondition):
class HandScoring:
score = None
description = ""
def __init__(self, hand_cards, starter_card):
self.hand_cards = hand_cards
self.starter_card = starter_card
#self.is_crib = is_crib
self.all_cards = hand_cards.copy()
self.all_cards.append(starter_card)

class NinHand(HandScoring):
def check(self):
ncounter = CountCombinationsEqualToN(n=15)
s,description = ncounter.check(self.all_cards)
return s, description

class HasPairTripleQuad_DuringPlay(ScoreCondition):
def check(self, cards):
description = None
pair_rank = ""
Expand All @@ -38,6 +53,27 @@ def check(self, cards):
description = "Double Pair Royal (%s)" % pair_rank
return score, description

class HasPairTripleQuad_InHand(HandScoring):
def check(self):
description = ""
score = 0
if len(self.all_cards) > 1:
ranks = [card.rank['rank'] for card in self.all_cards]
pos_pair = {x:ranks.count(x) for x in ranks}
for k,v in pos_pair.items():
if v == 2:
#found a pair
score += 2
description += "Pair (%s)" % k
elif v == 3:
#found three of a kind
score += 6
description += "Three of a kind (%s)" % k
elif v == 4:
#found four of a kind
score += 12
description += "Four of a kind (%s)" % k
return score, description

class ExactlyEqualsN(ScoreCondition):

Expand All @@ -52,7 +88,7 @@ def check(self, cards):
return score, description


class HasStraight_InHand(ScoreCondition):
class HasStraight_InHand(HandScoring):

@staticmethod
def _enumerate_straights(cards):
Expand All @@ -74,12 +110,12 @@ def _enumerate_straights(cards):
if not subset:
straights_deduped.append(s)
return straights_deduped

@classmethod
def check(cls, cards):

def check(self):
description = ""
points = 0
straights = cls._enumerate_straights(cards)
#cards = self.all_cards
straights = self._enumerate_straights(self.all_cards)
for s in straights:
assert len(s) >= 3, "Straights must be 3 or more cards."
description += "%d-card straight " % len(s)
Expand Down Expand Up @@ -123,11 +159,43 @@ def check(self, cards):
return score, description


class HasFlush(ScoreCondition):
def check(self, cards):
card_suits = [card.get_suit() for card in cards]
suit_count = card_suits.count(cards[-1].get_suit())
score = suit_count if suit_count >= 4 else 0
assert score < 6, "Flush score exceeded 5"
description = "" if score < 4 else ("%d-card flush" % score)
return score, description
class HasFlush(HandScoring):
def __init__(self,hand_cards,starter_card,is_crib):
self.is_crib = is_crib
super().__init__(hand_cards,starter_card)

def check(self):
if self.is_crib:
card_suits = [card.get_suit() for card in self.hand_cards]
card_suits.append(self.starter_card.get_suit())
d = {x:card_suits.count(x) for x in card_suits}
if max(d.values()) == 5:
self.score = 5
self.description = "5-card flush, 5 score"
else:
self.score = 0
elif not(self.is_crib):
card_suits = [card.get_suit() for card in self.hand_cards]
d = {x:card_suits.count(x) for x in card_suits}
if max(d.values()) == 4:
v = list(d.values())
k=list(d.keys())
flush_suit = k[v.index(max(v))]
if flush_suit == self.starter_card.get_suit():
self.score = 5
self.description = "5-card flush, 5 score"
else:
self.score = 4
self.description = "4-card flush, 4 score"
else:
self.score = 0
else:
raise Exception("Crib or hand not specified")
return self.score, self.description

#card_suits = [card.get_suit() for card in cards]
#suit_count = card_suits.count(cards[-1].get_suit())
#score = suit_count if suit_count >= 4 else 0
#assert score < 6, "Flush score exceeded 5"
#description = "" if score < 4 else ("%d-card flush" % score)

22 changes: 12 additions & 10 deletions cribbage/cribbagegame.py → cribbagegame.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Cribbage game."""
import random
import scoring
from player import HumanPlayer, RandomPlayer
from playingcards import Deck
from cribbage import scoring
from cribbage.player import HumanPlayer, RandomPlayer
from cribbage.playingcards import Deck

DEBUG = True # Debug flag for debugging output

Expand Down Expand Up @@ -184,13 +184,15 @@ def play(self):
for p in self.game.players:
p_cards_played = [move['card'] for move in self.table if move['player'] == p]
print("Scoring " + str(p) + "'s hand: " + str(p_cards_played + [self.starter]))
score = self._score_hand(cards=p_cards_played + [self.starter]) # Include starter card as part of hand
#score = self._score_hand(cards=p_cards_played + [self.starter]) # Include starter card as part of hand
score = self._score_hand(hand = p_cards_played, s_card = self.starter, is_crib = False)
if score:
self.game.board.peg(p, score)

# Score the crib
print("Scoring the crib: " + str(self.crib + [self.starter]))
score = self._score_hand(cards=(self.crib + [self.starter])) # Include starter card as part of crib
#score = self._score_hand(cards=(self.crib + [self.starter])) # Include starter card as part of crib
score = self._score_hand(hand = self.crib, s_card = self.starter, is_crib = True)
if score:
self.game.board.peg(self.dealer, score)

Expand All @@ -202,24 +204,24 @@ def _score_play(self, card_seq):
"""
score = 0
score_scenarios = [scoring.ExactlyEqualsN(n=15), scoring.ExactlyEqualsN(n=31),
scoring.HasPairTripleQuad(), scoring.HasStraight_DuringPlay()]
scoring.HasPairTripleQuad_DuringPlay(), scoring.HasStraight_DuringPlay()]
for scenario in score_scenarios:
s, desc = scenario.check(card_seq[:])
score += s
print("[SCORE] " + desc) if desc else None
return score

def _score_hand(self, cards):
def _score_hand(self, hand, s_card, is_crib):
"""Score a hand at the end of a round.

:param cards: Cards in a single player's hand.
:return: Points earned by player.
"""
score = 0
score_scenarios = [scoring.CountCombinationsEqualToN(n=15),
scoring.HasPairTripleQuad(), scoring.HasStraight_InHand(), scoring.HasFlush()]
score_scenarios = [scoring.NinHand(hand, s_card),
scoring.HasPairTripleQuad_InHand(hand, s_card), scoring.HasStraight_InHand(hand, s_card), scoring.HasFlush(hand, s_card, is_crib)]
for scenario in score_scenarios:
s, desc = scenario.check(cards[:])
s, desc = scenario.check()
score += s
print("[EOR SCORING] " + desc) if desc else None
return score
Expand Down
Empty file added test/__init__.py
Empty file.
4 changes: 2 additions & 2 deletions test/test_cribbagegame.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest
from player import RandomPlayer
import cribbagegame
from cribbage.player import RandomPlayer
import cribbagegame as cribbagegame


class TestCribbageBoard(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion test/test_playingcards.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import unittest
from playingcards import Card, Deck
from cribbage.playingcards import Card, Deck


class TestCardClass(unittest.TestCase):
Expand Down
Loading