Projects/poker_class_version.py

141 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
from typing import List, Tuple
SUITS = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
RANK_VALUES = {rank: i for i, rank in enumerate(RANKS, 2)}
class Card:
def __init__(self, rank: str, suit: str):
self.rank = rank.strip().upper()
self.suit = suit.strip().capitalize()
def __repr__(self):
return f"{self.rank} of {self.suit}"
def __eq__(self, other):
return isinstance(other, Card) and self.rank == other.rank and self.suit == other.suit
class Deck:
def __init__(self):
self.cards: List[Card] = [Card(rank, suit) for suit in SUITS for rank in RANKS]
random.shuffle(self.cards)
def deal_card(self) -> Card:
return self.cards.pop(0)
def deal_hand(self, num: int = 5) -> List[Card]:
hand = self.cards[:num]
del self.cards[:num]
return hand
class Player:
def __init__(self, name: str, deck: Deck):
self.name = name
self.hand: List[Card] = deck.deal_hand()
def show_hand(self):
return '\n '.join(str(card) for card in self.hand)
def replace_card(self, old_card: Card, new_card: Card) -> bool:
for i, card in enumerate(self.hand):
if card == old_card:
self.hand[i] = new_card
return True
return False
def hand_rank(self) -> Tuple[int, List[int]]:
ranks = sorted([RANK_VALUES[card.rank] for card in self.hand], reverse=True)
suits = [card.suit for card in self.hand]
rank_counts = {r: ranks.count(r) for r in ranks}
is_flush = len(set(suits)) == 1
is_straight = all(ranks[i] - 1 == ranks[i+1] for i in range(len(ranks)-1))
counts = sorted(rank_counts.values(), reverse=True)
if ranks == [14, 5, 4, 3, 2]: # Ace-low straight
is_straight = True
ranks = [5, 4, 3, 2, 1]
if is_straight and is_flush:
return (8, ranks)
elif counts[0] == 4:
return (7, ranks)
elif counts[0] == 3 and counts[1] == 2:
return (6, ranks)
elif is_flush:
return (5, ranks)
elif is_straight:
return (4, ranks)
elif counts[0] == 3:
return (3, ranks)
elif counts[0] == 2 and counts[1] == 2:
return (2, ranks)
elif counts[0] == 2:
return (1, ranks)
else:
return (0, ranks)
class Game:
def __init__(self):
self.deck = Deck()
self.player1 = Player("Player 1", self.deck)
self.player2 = Player("Player 2", self.deck)
def prompt_card_replacement(self, player: Player):
while True:
try:
num = int(input(f"{player.name}, how many cards do you want to pull? (03): "))
if 0 <= num <= 3:
break
else:
print("Invalid number. Please choose between 0 and 3.")
except ValueError:
print("Invalid input. Please enter a number between 0 and 3.")
replacements_done = 0
while replacements_done < num:
print("\nYour current hand:\n", player.show_hand())
user_input = input("Enter a card to replace (e.g., A of Spades): ").strip()
if ' of ' not in user_input:
print("Invalid format. Use 'Rank of Suit'.")
continue
rank, suit = user_input.split(' of ', 1)
old_card = Card(rank, suit)
if old_card not in player.hand:
print(f"{old_card} not found in your hand. Please try again.")
continue
new_card = self.deck.deal_card()
if player.replace_card(old_card, new_card):
print(f"Replaced {old_card} with {new_card}")
replacements_done += 1
else:
print("Replacement failed unexpectedly.")
def play(self):
print("Initial hands:")
print("Player 1:\n", self.player1.show_hand())
print("Player 2:\n", self.player2.show_hand())
self.prompt_card_replacement(self.player1)
self.prompt_card_replacement(self.player2)
rank1 = self.player1.hand_rank()
rank2 = self.player2.hand_rank()
print("\nFinal hands:")
print("Player 1:\n", self.player1.show_hand())
print("Player 2:\n", self.player2.show_hand())
if rank1 > rank2:
print("Player 1 wins!", rank1)
elif rank2 > rank1:
print("Player 2 wins!", rank2)
else:
print("It's a tie!")
if __name__ == "__main__":
Game().play()