Added Collections module; modified class Hand, added methods to get all melds and best meld combo; added function to find non-overlapping meld combos; fleshed out game start
This commit is contained in:
parent
e179d71d41
commit
5406155c5d
@ -1,7 +1,8 @@
|
|||||||
import random
|
import random
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from itertools import combinations
|
||||||
|
|
||||||
|
# Define card ranks and their order for runs
|
||||||
RANK_ORDER = {str(n): n for n in range(2, 11)}
|
RANK_ORDER = {str(n): n for n in range(2, 11)}
|
||||||
RANK_ORDER.update({"A": 1, "J": 11, "Q": 12, "K": 13})
|
RANK_ORDER.update({"A": 1, "J": 11, "Q": 12, "K": 13})
|
||||||
class Card:
|
class Card:
|
||||||
@ -42,6 +43,7 @@ class DiscardPile:
|
|||||||
self.cards.append(card)
|
self.cards.append(card)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Hand:
|
class Hand:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cards = []
|
self.cards = []
|
||||||
@ -51,12 +53,25 @@ class Hand:
|
|||||||
|
|
||||||
def remove(self, card):
|
def remove(self, card):
|
||||||
self.cards.remove(card)
|
self.cards.remove(card)
|
||||||
|
|
||||||
def melds(self):
|
def get_all_melds(self):
|
||||||
|
"""Returns all valid sets and runs from current hand."""
|
||||||
return find_sets(self.cards) + find_runs(self.cards)
|
return find_sets(self.cards) + find_runs(self.cards)
|
||||||
|
|
||||||
|
def best_meld_combo(self):
|
||||||
|
"""Returns the optimal non-overlapping meld combination."""
|
||||||
|
all_melds = self.get_all_melds()
|
||||||
|
combos = non_overlapping_meld_combos(all_melds)
|
||||||
|
best = max(combos, key=lambda combo: len(set(c for meld in combo for c in meld)), default=[])
|
||||||
|
return best
|
||||||
|
|
||||||
|
def deadwood(self):
|
||||||
|
"""Returns list of cards not used in best meld combo."""
|
||||||
|
used = set(c for meld in self.best_meld_combo() for c in meld)
|
||||||
|
return [c for c in self.cards if c not in used]
|
||||||
|
|
||||||
def deadwood_points(self):
|
def deadwood_points(self):
|
||||||
return sum(c.value for c in self.cards) # placeholder
|
return sum(c.value for c in self.deadwood())
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Hand({self.cards})"
|
return f"Hand({self.cards})"
|
||||||
@ -107,7 +122,6 @@ def find_sets(cards):
|
|||||||
groups[c.rank].append(c)
|
groups[c.rank].append(c)
|
||||||
return [group for group in groups.values() if len(group) >= 3]
|
return [group for group in groups.values() if len(group) >= 3]
|
||||||
|
|
||||||
|
|
||||||
# Function to detect runs
|
# Function to detect runs
|
||||||
def find_runs(cards):
|
def find_runs(cards):
|
||||||
runs = []
|
runs = []
|
||||||
@ -133,7 +147,34 @@ def find_runs(cards):
|
|||||||
if len(temp) >= 3:
|
if len(temp) >= 3:
|
||||||
runs.append(temp)
|
runs.append(temp)
|
||||||
return runs
|
return runs
|
||||||
|
|
||||||
|
|
||||||
|
def non_overlapping_meld_combos(all_melds):
|
||||||
|
"""
|
||||||
|
Given a list of all possible melds (sets and runs),
|
||||||
|
return all combinations where no card is used more than once.
|
||||||
|
"""
|
||||||
|
valid_combos = []
|
||||||
|
for r in range(1, len(all_melds) + 1):
|
||||||
|
for combo in combinations(all_melds, r):
|
||||||
|
used = set()
|
||||||
|
overlap = False
|
||||||
|
for meld in combo:
|
||||||
|
for card in meld:
|
||||||
|
if card in used:
|
||||||
|
overlap = True
|
||||||
|
break
|
||||||
|
used.add(card)
|
||||||
|
if overlap:
|
||||||
|
break
|
||||||
|
if not overlap:
|
||||||
|
valid_combos.append(combo)
|
||||||
|
return valid_combos
|
||||||
|
|
||||||
|
# start a game with two players
|
||||||
|
if __name__ == "__main__":
|
||||||
|
players = [Player("Alice"), Player("Bob")]
|
||||||
|
game = Game(players)
|
||||||
|
game.play_round()
|
||||||
|
# Further game logic would go here
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user