From 829ed53bdaeff4c0ea165450697fcb09edd70604 Mon Sep 17 00:00:00 2001 From: Donald Calloway Date: Sat, 20 Sep 2025 12:03:16 -0700 Subject: [PATCH] Commit of Final 5-Card_Stud_Poker_Game (Final) --- 5-Card_Stud_Poker_Game (Final).py | 312 +++++++++++++++++++++++++ __pycache__/hand_utils.cpython-313.pyc | Bin 6669 -> 7404 bytes 2 files changed, 312 insertions(+) create mode 100644 5-Card_Stud_Poker_Game (Final).py diff --git a/5-Card_Stud_Poker_Game (Final).py b/5-Card_Stud_Poker_Game (Final).py new file mode 100644 index 0000000..0738538 --- /dev/null +++ b/5-Card_Stud_Poker_Game (Final).py @@ -0,0 +1,312 @@ +# 5-Card_Stud_Poker_Game.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 (2–5): ")) + 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 (2–5): ")) + + players = [] + for i in range(num_players): + name = input(f"Enter name for Player {i+1} (or press Enter for default): ").strip() + if not name: + 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.") + player = Player(name=name, starting_chips=starting_chips) + player.active = True # Ensure player is active at start + players.append(player) + 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, pot): + best_score = (-1, -1) + + winner = None + pot = pot + + for player in players: + if player.folded: + player.active = False + 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: + winner.chips += pot + print(f"\nšŸ† {winner.name} wins the pot with: {winner.reveal_full_hand()} and {winner.chips} chips") + +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.") + # Check if only one player remains + active_players = [p for p in players if not p.folded and p.active and p.chips > 0] + if len(active_players) == 1: + winner = active_players[0] + winner.chips += pot + print(f"{winner.name} wins the pot of {pot} chips by default!") + show_final_stacks(players, pot) + continue_prompt(players) + break + else: + players.remove(player) # Remove folded player from active players + 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(players): + deck = Deck() + deal_initial_cards(deck, players) + + current_bet = 10 + pot = 0 + + # Run betting round, determine winner, update chips + 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, pot) + show_final_stacks(players, pot) + +def show_final_stacks(players, pot): + print(f"\nTotal pot: {pot}") + print("\n--- Final Chip Stacks ---") + for player in players: + print(f"{player.name}: {player.chips} chips") + continue_prompt(players) + +def continue_prompt(players): + response = input("Play another round? (y/n): ").lower() + if response == 'y': + add_new_players(players) + reset_round(players) + play(players) + return True + else: + print("Game over. Thanks for playing!") + exit() + return False + +def add_new_players(players): + while True: + name = input("Enter new player name (or press Enter to skip): ") + if not name: + reset_round(players) + play(players) + break + 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.") + continue + player = Player(name=name, starting_chips=starting_chips) + player.active = True # Ensure new player is active at start + print(f"{player.name} enters the game with {player.chips} chips.") + players.append(player) # Default starting chips for new players + reset_round(players) + play(players) + return players + +def reset_round(players): + for p in players: + if p.active and p.chips <= 0: + print(f"{p.name} is out of chips and removed from the game.") + players.remove(p) + continue + elif not p.active and p.chips > 0: + p.active = True + print(f"{p.name} re-enters the game with {p.chips} chips.") + # Discard active player's previous hands, reset round-specific flags + p.folded = False + p.active = True + p.hand = [] + p.face_up_cards = [] + p.hole_card = None + elif p.active and p.chips > 0: + p.folded = False + p.hand = [] + p.face_up_cards = [] + p.hole_card = None + +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 + self.active = False + + 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 'c' + else: + return 'f' + + +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!") + players = setup_players() + while True: + play(players) # Pass persistent player list + if not continue_prompt(players): + break + + +if __name__ == "__main__": + main() + + + + \ No newline at end of file diff --git a/__pycache__/hand_utils.cpython-313.pyc b/__pycache__/hand_utils.cpython-313.pyc index d93cbc32de71c96b59021deec9d8da76532b8a3b..026e1fd19a5316c3a42606c4cdbad02200c0d3b0 100644 GIT binary patch delta 2549 zcma)7OH3PA6rJ&RJY&z;7-K_dGbqH^#NnfoDh5JAA_#>*0%PaXpwbB#aAU^p8?2}- zLexl=D)pDXq^0V{X*Xn5M{Kfec4-tHjs6ovfS>gvXsgyjF z&ghAP)leyLWtAl;$&q!uX_DGYnb8P_gr=_{H%q-rx^wqTx1EQU=+K?+t)T}bFU%E>a3;Z+dl zL2Qbs+T|%cjFIEO^~0lg16*UC3V{t_kMZ+w2sImmZ$oG_5Qw^8eS*t&ZD1?FI6a?5 zKZ<@HTj_f&wB{|XWFK0$qG6qeZAaM?G-;Eq1HcW^Pi+f6aumq0sbEeew1QcOAXzd< z-S&FxFdnS6*&A5)D1C!F&$iKTxn7`u<{H|E3@vg3USu4gn9Q+aGD1?H(n}2@=ioF# zLyilkA8c#a9f#P3I);gx+8M<@&UT+?7*&LSDRi1)Ls&*waZ{JMnTgv%#Vw=y zfM>1jP|s1N2eylXMLmU&TPA$;zH_f{gkdgXF^#1N4Gf&r(@vqC^;1=7?Wi*1DjSKp z+F6A^2wjfb+u4Jlioqyi*{EXy+)L%1@4_w@?uv^@t;SXPhWk?T9a+{KN==pLnzH9O z2cAX4vjZpzsj~m7Vqp4gl|Eb1FP3e0q4+9E-jI|arBbCTN%^2#RndBPqNPo)q1UTy zh!t-;(F)}#FYYOp8XRB?I)#R!OW;ntLce$I^GtysygM4jj zY~6$wFr*jZ2tpqM&VjJ?@3_UQW+iWe#HI_uiGZV#;J=d`Mu;LDp^ML<)ElP3n*HoF#u&Y0GBW;eCAfnOxr8u{&;#1% zJLZwZ?EcN25pUAa1f_cV+#R5|yzQZ#B(3kl@Yeq!%X9RZw~3uaf6JHuk3Z~BRiro| zjhP;n2#&o1e^yOp5(9*!35g*?nCKrHnL68lDn6hX{UP}}2_@=_$v zMV{E5Uj{bZo)_43pzcUxnYWmoT^+wYp9|&!>%nMV>dtfB^sBnF!)1X?c5YR@oy>LR zg7-XkL+iorywsEDdcgS0rk~iQmzh-dk2Jh!u4TvDRsVG5II-G)doEX(ejM}*SF5jqNc~I*Zb#o7z zY=94K&QTx#u+9efhtCZFccZOFiE3vQnE#@E_&SqAXTysvp8(w{Dy`}dL-$^3F8^f9ieB~~lx_dyV`f$`0-UtWauF^m_|dx@wkEB! z%&e`1+X1)fxR~StFY_sG*KsK+0&Xes*;%2?im(&|o}}{}OAeI{Al0zOtf7lYacXF1 zka^0P3r3t?yQGq^NhTi|EaZtf&0#pe}AG4DKaA z@IK=Z1pGU{@qUKsCx2U}m}YWD7=-5=fG0#fDJQ{3g>sg;1J`Z|qeN*(SvYMD8% zn3VprmFga9JCYA|G$z)QsPi>{$^sn~B`O^yJ#;j3-`U4%Msna(hL1yi#i)sJ!=Q;Y zSPRk&)U5}j7r>_=x$kNe;xuy_OfUJ})hTIa>Q`!&1N8H2Rq+tko3%~VZ2-jk*5HKnrM#Oe;g zd;{*LP^GccKv2D44m5NfEmY?sNVloPEb;% zb^VXQ^mA84Opk$ra4x;NxfsWI9pf?5?P;*m<3<1Q@erBzyyS(i94Qi}LIrL962*6}Clk-aa^Y;>HkZ4)oxXW(&lSu|?RmZ(WU3;M%~I7N zyS{|0oR@pAs@LtGcV(hEXEv6*n48*jwdSR^Jl_T#yh0xO15K4KmMXDFHv87*R)3z8 zNlQcUSfYjh(Jm)~+yk#A(aAq(HG$nlwnSLib(p~Z+;2(5_+QK>uoH@tyx%Y!zC>5z z22(JstZiU@r(x=H7uMHTF+HA(JEjYR4`Gx%X=oO%gF}yW^;_a@JWZ}NjvsU9xZLDT p;VJ53+}oRXlJ}0@Q@>H}oZkx${zb9p&w7wFpwg4#YjLF4^e?79a|{3g