Projects/5-Card_Stud_Poker - With_Chips(1) - Copy.py

243 lines
7.3 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.

# 5-Card_Stud_Poker.py
import random
from collections import Counter
from hand_utils import evaluate_hand, Tuple, List, Card, SUITS, RANKS
starting_chips = 0 # Default starting chips for each player
rank_counts = Counter()
@staticmethod
def setup_players():
num_players = int(input("Enter number of players (25): "))
while True:
if 2 <= num_players <= 5:
break
else:
print("Invalid number of players. Please enter a number between 2 and 5.")
num_players = int(input("Enter number of players (25): "))
players = []
for i in range(num_players):
name = f"Player {i+1}"
while True:
try:
starting_chips = int(input(f"Enter starting chips for {name}: "))
if starting_chips <= 0:
print("Starting chips must be a positive number.")
continue
break
except ValueError:
print("Please enter a valid integer.")
players.append(Player(name, starting_chips))
return players
@staticmethod
def deal_round(deck, players, round_num):
print(f"\n--- Round {round_num} ---")
for player in players:
if not player.folded:
player.receive_card(deck.deal_card())
print(player.show_hand())
@staticmethod
def determine_winner(players):
best_score = (-1, -1)
winner = None
for player in players:
if player.folded:
continue
full_hand = [player.hole_card] + player.face_up_cards
score = evaluate_hand(full_hand)
print(f"{player.name} hand score: {score}")
if score > best_score:
best_score = score
winner = player
if winner:
print(f"\n🏆 {winner.name} wins with: {winner.reveal_full_hand()}")
def deal_initial_cards(deck, players):
for player in players:
player.receive_hole_card(deck.deal_card()) # face-down
player.receive_face_up_card(deck.deal_card()) # first face-up
@staticmethod
def betting_round(players, current_bet, pot):
print("\n--- Betting Round ---")
for player in players:
if player.folded:
continue
print(f"\n{player.name}'s turn. Current bet: {current_bet}. Chips: {player.chips}")
while True:
action = input(f"{player.name}, do you want to call, raise or fold 'c', 'r', or 'f'? ").strip().lower()
if action == 'f':
player.folded = True
print(f"{player.name} folds.")
break
elif action == 'c':
try:
bet = player.place_bet(current_bet)
pot += bet
print(f"{player.name} calls and bets {bet}.")
break
except ValueError as e:
print(e)
elif action == 'r':
try:
raise_amount = int(input("Enter raise amount: "))
total_bet = current_bet + raise_amount
bet = player.place_bet(total_bet)
current_bet = total_bet
pot += bet
print(f"{player.name} raises to {total_bet}.")
break
except ValueError as e:
print(e)
else:
print("Invalid action. Please enter 'call', 'raise', or 'fold'.")
return current_bet, pot
@staticmethod
def play():
deck = Deck()
players = setup_players()
deal_initial_cards(deck, players)
current_bet = 10
pot = 0
for round_num in range(1, 4):
print(f"\n--- Round {round_num} ---")
for player in players:
if not player.folded:
player.receive_face_up_card(deck.deal_card())
print(player.show_hand())
current_bet, pot = betting_round(players=players, current_bet=current_bet, pot=pot)
print("\n--- Showdown ---")
for player in players:
if not player.folded:
print(player.reveal_full_hand())
print(f"\nTotal pot: {pot}")
# Simulate betting round
current_bet, pot = betting_round(players, current_bet, pot)
pot += current_bet * sum(1 for p in players if not p.folded)
# Showdown
print("\n--- Showdown ---")
for player in players:
if not player.folded:
print(player.reveal_full_hand())
determine_winner(players)
print(f"\nTotal pot: {pot}")
print("\n--- Final Chip Stacks ---")
for player in players:
print(f"{player.name}: {player.chips} chips")
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, starting_chips: int):
self.name = name
self.hold_card: Card = None
self.face_up_cards: List[Card] = []
self.hand: List[Card] = []
self.folded = False
self.chips = starting_chips
def place_bet(self, amount):
if amount > self.chips:
raise ValueError(f"{self.name} doesn't have enough chips to bet {amount}.")
self.chips -= amount
return amount
def receive_hole_card(self, card):
self.hole_card = card
def receive_face_up_card(self, card):
self.face_up_cards.append(card)
def show_hand(self):
return f"{self.name}: | {' | '.join(str(card) for card in self.face_up_cards)} |"
def reveal_full_hand(self):
return f"{self.name}: | {str(self.hole_card)} | {' | '.join(str(card) for card in self.face_up_cards)} |"
def hand_rank(self) -> Tuple[int, List[int]]:
return evaluate_hand(self.hand)
def make_decision(self):
high_ranks = {'J', 'Q', 'K', 'A'}
visible_ranks = [card.rank for card in self.face_up_cards]
if any(rank in high_ranks for rank in visible_ranks):
return 'call'
else:
return 'fold'
def hand_rank_name(rank: int) -> str:
names = {
9: "Royal Flush",
8: "Straight Flush",
7: "Four of a Kind",
6: "Full House",
5: "Flush",
4: "Straight",
3: "Three of a Kind",
2: "Two Pair",
1: "One Pair",
0: "High Card"
}
return names.get(rank, "Unknown Hand")
class Game:
def __init__(self):
self.deck = Deck()
self.players = setup_players()
for player in self.players:
player.hand = self.deck.deal_hand()
def deal_initial_cards(deck, players):
for player in players:
player.receive_card(deck.deal_card()) # hole card
player.receive_card(deck.deal_card()) # first face-up card
def deal_round(deck, players, round_num):
print(f"\n--- Round {round_num} ---")
for player in players:
if not player.folded:
player.receive_card(deck.deal_card())
print(player.show_hand())
def main():
print("Welcome to 5-Card Stud Poker!")
play()
if __name__ == "__main__":
main()