feat: poker modified

This commit is contained in:
Krzysztof Rudnicki 2025-07-19 19:31:18 +02:00
parent a905f6e87e
commit 545a30a01f
6 changed files with 1475 additions and 0 deletions

View File

@ -0,0 +1,55 @@
# Texas Hold'em Modifier App
A fun web application that randomly applies modifiers to Texas Hold'em poker games with configurable probability.
## Features
- **Configurable Probability**: Adjust the chance of getting a modifier (0-100%)
- **15 Unique Modifiers**: Various game-changing rules like "High Stakes", "Wild Card", "Reverse Psychology", etc.
- **Statistics Tracking**: Keep track of rounds played and modifiers applied
- **Beautiful UI**: Modern, responsive design with poker-themed styling
- **Smooth Animations**: Visual feedback for button clicks and result displays
## How to Use
1. Open `index.html` in your web browser
2. Adjust the "Modifier Probability" slider to set the chance of getting a modifier
3. Click "Start Round" to begin a new round
4. The app will randomly decide whether to apply a modifier based on your probability setting
5. If a modifier is chosen, a random modifier will be selected and displayed
## Modifiers Included
- **High Stakes**: All bets are doubled
- **Wild Card**: Next card can be used as any card
- **Bluff Master**: See one opponent's card before betting
- **All-In Fever**: If someone goes all-in, everyone must match or fold
- **Lucky Sevens**: Any hand with a 7 beats a pair
- **Reverse Psychology**: Lowest hand wins
- **Split Pot**: Pot split between top 2 hands
- **Texas Twister**: Each player gets an extra hole card
- **Blind Luck**: Play blind until the river
- **Community Boost**: Extra community card revealed
- **Minimum Madness**: Minimum bet tripled
- **Suit Supremacy**: Random suit cards worth +1 rank
- **Quick Draw**: Betting time cut in half
- **Royal Treatment**: Face cards worth double
- **Chip Challenge**: Winner gets extra house chips
## Files
- `index.html`: Main HTML structure
- `style.css`: Styling and responsive design
- `script.js`: JavaScript functionality and modifier logic
## Customization
You can easily add new modifiers by using the `addModifier()` method:
```javascript
window.pokerApp.addModifier("Your Modifier Name", "Description of what it does");
```
## Browser Compatibility
Works in all modern web browsers (Chrome, Firefox, Safari, Edge).

View File

@ -0,0 +1,135 @@
# Texas Hold'em Modifier App - Python Version
A desktop application built with Python and tkinter that randomly applies modifiers to Texas Hold'em poker games with configurable probability.
## Requirements
- Python 3.6+
- tkinter (usually comes with Python)
## How to Run
```bash
python poker_modifier_app.py
```
## Features
- **Configurable Probability**: Adjust the chance of getting a modifier (0-100%) with a slider
- **50+ Poker & Drinking Modifiers**: Real poker variations with drinking game twists!
- **Statistics Tracking**: Keep track of rounds played and modifiers applied
- **Modern GUI**: Clean, poker-themed interface with visual feedback
- **Easy to Extend**: Simple methods to add new modifiers
## How to Use
1. Run the Python script
2. Adjust the "Modifier Probability" slider to set the chance of getting a modifier
3. Click "Start Round" to begin a new round
4. The app will randomly decide whether to apply a modifier based on your probability setting
5. If a modifier is chosen, a random modifier will be selected and displayed
## Modifiers Included
### Classic Poker Modifiers
- **High Stakes**: All bets are doubled
- **Wild Card**: Next card can be used as any card
- **Bluff Master**: See one opponent's card before betting
- **All-In Fever**: If someone goes all-in, everyone must match or fold
- **Lucky Sevens**: Any hand with a 7 beats a pair
- **Reverse Psychology**: Lowest hand wins
- **Split Pot**: Pot split between top 2 hands
- **Texas Twister**: Each player gets an extra hole card
- **Blind Luck**: Play blind until the river
- **Community Boost**: Extra community card revealed
- **Minimum Madness**: Minimum bet tripled
- **Suit Supremacy**: Random suit cards worth +1 rank
- **Quick Draw**: Betting time cut in half
- **Royal Treatment**: Face cards worth double
- **Chip Challenge**: Winner gets extra house chips
## Modifiers Included
### Classic Poker Modifiers
- **High Stakes**: All bets are doubled
- **Wild Card**: Next card can be used as any card
- **Bluff Master**: See one opponent's card before betting
- **All-In Fever**: If someone goes all-in, everyone must match or fold
- **Lucky Sevens**: Any hand with a 7 beats a pair
- **Reverse Psychology**: Lowest hand wins
- **Split Pot**: Pot split between top 2 hands
- **Texas Twister**: Each player gets an extra hole card
- **Blind Luck**: Play blind until the river
- **Community Boost**: Extra community card revealed
- **Minimum Madness**: Minimum bet tripled
- **Suit Supremacy**: Random suit cards worth +1 rank
- **Quick Draw**: Betting time cut in half
- **Royal Treatment**: Face cards worth double
- **Chip Challenge**: Winner gets extra house chips
### Drinking Game Modifiers
- **Red or Black**: Guess community card colors for double winnings
- **Pocket Rockets**: Pocket Aces trigger drinks for everyone else
- **Rainbow Flop**: 3-suit flop boosts flush draws
- **Suited Connectors**: Beat any pocket pair
- **Drink or Fold**: Choose to drink and stay in or fold
- **Shot Clock**: 10 seconds per decision or auto-fold
- **Double Down**: Pay double to see opponent's cards
- **Bad Beat Jackpot**: Losing with full house+ makes others drink
- **Chaser Round**: Previous loser gets bonus stack
- **Face Card Frenzy**: Each face card = take a sip
- **Burn Card Reveal**: Matching burn cards = drinks + chips
- **Pair Tax**: Pocket pairs cost extra or drink
- **Kicker Clash**: Lowest kicker in tie drinks
- **Color Blind**: Red cards +1, black cards -1
- **Sip and Tell**: Drink and honestly rate your hand
- **Last Call**: Final betting round, no more cards
- **Drink the River**: River helps you = others drink
- **Tipsy Tells**: Must make exaggerated expressions
- **House Rules**: Deuces wild but drink when used
- **Side Bet Madness**: Bet on what flop will contain
- **Fold Penalty**: Folders drink and sit out next hand
- **Straight Shooter**: Complete straight = pick someone to finish drink
- **Flush Rush**: First flush wins side pot from all
- **Ace High Drama**: Ace high wins double but finish drink
- **Bluff Check**: Caught bluffing = drink + penalty
- **Small Ball**: Only minimum bets allowed
- **Position Power**: Button sees everyone's first card
- **Community Chest**: 6 community cards total
- **Heads Up**: Only top 2 hands after flop continue
- **Dealer's Choice**: Dealer picks wild suits
- **Ante Up**: Double ante or take two drinks
- **Showdown Shuffle**: Simultaneous card reveal
- **Lucky Draw**: Extra card, choose best 2
- **Betting Blind**: First round before looking at cards
- **Chip and a Chair**: Short stack sees early community card
- **All Red**: Red cards boost hand level
- **Mississippi Stud**: Fold after flop for half bet back
## Code Structure
- `PokerModifierApp`: Main application class
- `setup_gui()`: Creates the tkinter interface
- `start_round()`: Main game logic for starting rounds
- `apply_random_modifier()`: Selects and displays a random modifier
- `show_no_modifier()`: Displays when no modifier is chosen
- `add_modifier()`: Method to add new modifiers
- `get_stats()`: Returns current statistics
## Customization
You can easily add new modifiers programmatically:
```python
app = PokerModifierApp()
app.add_modifier("Your Modifier Name", "Description of what it does")
app.run()
```
## GUI Components
- **Title**: Application header
- **Settings Panel**: Probability slider
- **Result Display**: Shows modifier or "no modifier" message
- **Start Button**: Triggers new round
- **Statistics**: Displays rounds played and modifiers applied

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Texas Hold'em Modifier App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>🃏 Texas Hold'em Modifier</h1>
<div class="game-area">
<div class="probability-settings">
<h3>Settings</h3>
<div class="setting">
<label for="modifierChance">Modifier Probability:</label>
<input type="range" id="modifierChance" min="0" max="100" value="30">
<span id="chanceValue">30%</span>
</div>
</div>
<div class="result-area">
<div id="resultDisplay" class="result-display">
<p>Click "Start Round" to begin!</p>
</div>
</div>
<button id="startRoundBtn" class="start-button">Start Round</button>
<div class="stats">
<div class="stat">
<span class="stat-label">Rounds Played:</span>
<span id="roundsCount">0</span>
</div>
<div class="stat">
<span class="stat-label">Modifiers Applied:</span>
<span id="modifiersCount">0</span>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@ -0,0 +1,831 @@
import tkinter as tk
from tkinter import ttk
import random
import time
class PokerModifierApp:
def __init__(self):
self.modifiers = [
# Hand Bonus Modifiers (Balatro-inspired)
{
"name": "Pair Bonus",
"description": "Any pocket pair: everyone else pays you 1 chip, even if you lose the hand."
},
{
"name": "Flush Fever",
"description": "Make a flush: collect 1 chip from each other player (separate from main pot)."
},
{
"name": "Straight Shot",
"description": "Complete a straight: choose one player to pay you half the current pot size."
},
{
"name": "Full House Party",
"description": "Make full house: everyone else pays 2 chips + takes 2 drinks."
},
{
"name": "High Card Hero",
"description": "Win with just high card: collect your normal winnings + 1 chip from each player."
},
# Card Enhancement Modifiers
{
"name": "Face Card Power",
"description": "All face cards (J, Q, K) count as Aces for this hand."
},
{
"name": "Red Suit Boost",
"description": "Hearts and Diamonds are worth +1 rank (Jack becomes Queen, etc.)"
},
{
"name": "Black Magic",
"description": "Spades and Clubs can be used as any suit for straights/flushes."
},
{
"name": "Lucky Sevens",
"description": "All 7s become wild cards that can be any rank."
},
{
"name": "Steel Cards",
"description": "Random rank chosen: {steel_rank}. All {steel_rank}s beat everything this hand!"
},
# Ante-Based Effects (Clear Money Source)
{
"name": "Bonus Pool",
"description": "Everyone puts 2 chips in bonus pool. First person to make any pair wins it all."
},
# Deck Manipulation (Balatro-style)
{
"name": "Deck Shuffle",
"description": "After dealing hole cards, shuffle deck and redeal all community cards."
},
{
"name": "Extra Draw",
"description": "Deal each player a 3rd hole card. Discard one before the flop."
},
{
"name": "Phantom Cards",
"description": "Deal 6 community cards, but randomly remove 1 before showdown."
},
# Special Betting Rules (Realistic Economics)
{
"name": "Escalation",
"description": "Each raise must be at least 2x the previous raise (not just matching)."
},
# Position and Action Modifiers
{
"name": "Button Bonus",
"description": "Dealer button acts last in ALL rounds"
},
{
"name": "Call Penalty",
"description": "Anyone who only calls (never raises) pays 1 chip penalty to pot."
},
# Information Warfare
{
"name": "Poker Face",
"description": "No talking, no expressions allowed. Pure silent poker this hand."
},
{
"name": "Truth or Consequences",
"description": "If asked 'good hand or bad hand?' you must answer truthfully or pay penalty."
},
{
"name": "Open Book",
"description": "Everyone plays with one hole card face-up."
},
# Drinking Game Integration
{
"name": "Liquid Courage",
"description": "Take a drink before betting to get chip bonus to all your bets."
},
{
"name": "Last Call",
"description": "Everyone must finish their current drink before the river card."
},
{
"name": "Shot Clock",
"description": "5 seconds to act or take a shot and auto-fold."
},
{
"name": "Drink Tax",
"description": "Each red card in your final hand = one sip (reveal afret play) ."
},
# Wild and Chaos Effects
{
"name": "Joker's Wild",
"description": "All Jacks become completely wild - any suit, any rank you choose."
},
{
"name": "Suit Swap",
"description": "Hearts become Spades, Diamonds become Clubs this hand."
},
{
"name": "Rank Revolution",
"description": "2s beat Aces this hand. All other ranks stay the same."
},
{
"name": "Time Warp",
"description": "Play the hand completely backwards: showdown first, then remove random cards from table !"
},
# Economic Effects (Clear Money Sources)
{
"name": "Poverty Mode",
"description": "All bets limited to 1 chip maximum this hand."
},
{
"name": "High Roller",
"description": "Minimum bet is 5x the entry this hand."
},
{
"name": "Charity Case",
"description": "Player with fewest chips get ther ente funded by richest player."
},
# Penalty-Based Modifiers (Clear Consequences)
{
"name": "Fold Tax",
"description": "Anyone who folds pays 5 chip to the pot immediately."
},
{
"name": "Bluff Fine",
"description": "Get caught bluffing = pay 2 chips to next hand's pot."
},
{
"name": "Speed Fine",
"description": "Take longer than 10 seconds to act = pay 1 chip to pot."
},
{
"name": "Talk Tax",
"description": "Every word spoken during betting costs 1 chip to the pot."
},
# Skill Challenges (With Clear Rewards/Penalties)
{
"name": "Memory Challenge",
"description": " Dealers holder names all community cards in order. Success = collect 1 chip from each player. Fail = pay 1 chip to each player."
},
{
"name": "Quick Draw",
"description": "Everyone pays 1 chip to quick-draw pot. First to correctly announce their hand wins the pot and cant pass."
},
{
"name": "Bluff Bonus",
"description": "Successfully bluff with 7-high or worse = collect 2 chips from each other player."
},
{
"name": "Prediction Pool",
"description": "Everyone puts 1 chip in pool. Guess the river card exactly = win the pool."
},
# Partnership Modifiers
{
"name": "Buddy System",
"description": "Each player chooses a partner. Partners share fate - both win or both lose."
},
{
"name": "Duo Power",
"description": "Partners can combine their hole cards - each player plays with 4 cards total."
},
{
"name": "Shared Vision",
"description": "Partners can show each other one hole card before betting starts."
},
{
"name": "Tag Team",
"description": "Partners alternate who plays each betting round (pre-flop, flop, turn, river)."
},
{
"name": "Power Couple",
"description": "If both partners make it to showdown, they both get +1 chip bonus from other players (revalt at the end of round)."
},
]
# Separate endgame modifiers for special handling
self.endgame_modifiers = [
# Classic Endgame Modifiers
{
"name": "Final Boss",
"description": "This is the last hand. Winner takes all remaining chips."
},
{
"name": "Sudden Death",
"description": "Anyone who folds is eliminated from the game."
},
{
"name": "Comeback Kid",
"description": "Player with the worst hand can't lose chips this round (reveal at the end of round)."
},
{
"name": "Double or Nothing",
"description": "Winner gets double payout, but everyone else pays double penalty."
},
# High Stakes Endgame
{
"name": "All In Madness",
"description": "Everyone must go all-in. No calling, no folding allowed this hand."
},
{
"name": "Chip Volcano",
"description": "Everyone puts half their remaining chips in the center. Winner takes the mountain."
},
{
"name": "Last Stand",
"description": "Player with fewest chips gets to act last in ALL betting rounds."
},
# Dramatic Reversals
{
"name": "Underdog Victory",
"description": "Worst hand wins the pot instead of best hand this round."
}
# Winner Takes All Variants
{
"name": "Crown Jewels",
"description": "Winner of this hand becomes the 'King' - all other players pay tribute (2 chips each)."
},
{
"name": "Championship Belt",
"description": "Winner takes 75% of all chips on the table. Remaining 25% goes for the second best."
},
# Elimination Mechanics
{
"name": "Battle Royale",
"description": "Lowest hand is eliminated. If tied, both eliminated."
},
{
"name": "Survivor",
"description": "Only players who improve their hand from pre-flop to river survive to next round."
},
#Time Pressure Endgame
{
"name": "Speed Round",
"description": "3 seconds to act or auto-fold. No exceptions, no delays."
},
{
"name": "Auction House",
"description": "Players bid chips to see each other's hole cards before betting."
},
{
"name": "Lightning Round",
"description": "Deal all 5 community cards at once. Betting happens after each card revealed."
},
# Psychological Warfare
{
"name": "Confession Booth",
"description": "Each player must truthfully state their biggest bluff this session."
},
{
"name": "Truth Serum",
"description": "Everyone must honestly rate their hand 1-10 before any betting."
},
{
"name": "Poker Face Off",
"description": "Staring contest: losers must reveal one hole card to the table."
},
# Endgame Economics
{
"name": "Wealth Redistribution",
"description": "Before the hand, richest player gives 3 chips to poorest player."
},
{
"name": "Emergency Fund",
"description": "All players with less than 5 chips get emergency funding from the pot."
},
{
"name": "Final Ante",
"description": "Everyone must put in their last 2 chips before seeing cards. No backing out."
},
# Apocalypse Modifiers
{
"name": "Nuclear Option",
"description": "Dealer burns the top 3 cards. Play with whatever's left in the deck."
},
{
"name": "Meteor Strike",
"description": "Remove all face cards from the deck for this hand only."
},
{
"name": "Solar Flare",
"description": "All suits become the same suit (dealer's choice)."
},
# Legacy Modifiers
{
"name": "Hall of Fame",
"description": "Winner's name gets written down as 'Champion of the Session'."
},
{
"name": "Legendary Hand",
"description": "This hand will be retold as a story. Play like legends."
},
{
"name": "Photo Finish",
"description": "Take a photo of the winning hand - it goes in the poker hall of fame."
},
# Chaos Theory
{
"name": "Butterfly Effect",
"description": "One random decision by dealer changes everything: flip a coin for each community card to reverse it."
},
{
"name": "Time Paradox",
"description": "Play the hand twice with same cards. Best average result wins."
},
{
"name": "Multiverse",
"description": "Deal 2 separate boards. Players choose which board to play after seeing both."
}
]
# Remove endgame modifiers from regular modifier list
endgame_modifier_names = [mod['name'] for mod in self.endgame_modifiers]
self.modifiers = [mod for mod in self.modifiers if mod['name'] not in endgame_modifier_names]
# Game state tracking
self.rounds_played = 0
self.modifiers_applied = 0
self.total_game_rounds = 20 # Default game length
self.endgame_threshold = 0.8 # Start endgame modifiers at 80% of total rounds
self.debug_mode = False
self.force_endgame = False
self.setup_gui()
def setup_gui(self):
# Create main window
self.root = tk.Tk()
self.root.title("🃏 Texas Hold'em Modifier")
self.root.geometry("650x750")
self.root.configure(bg='#0f4c3a')
self.root.resizable(True, True)
# Configure style
style = ttk.Style()
style.theme_use('clam')
# Main container
main_frame = tk.Frame(self.root, bg='#0f4c3a', padx=20, pady=20)
main_frame.pack(fill=tk.BOTH, expand=True)
# Title
title_label = tk.Label(
main_frame,
text="🃏 Texas Hold'em Modifier",
font=('Arial', 24, 'bold'),
fg='#ffd700',
bg='#0f4c3a'
)
title_label.pack(pady=(0, 20))
# Settings frame
settings_frame = tk.LabelFrame(
main_frame,
text="Settings",
font=('Arial', 12, 'bold'),
fg='#ffd700',
bg='#1a6b4d',
relief=tk.RIDGE,
bd=2
)
settings_frame.pack(fill=tk.X, pady=(0, 20), padx=10, ipady=10)
# Probability setting
prob_frame = tk.Frame(settings_frame, bg='#1a6b4d')
prob_frame.pack(fill=tk.X, padx=10, pady=5)
tk.Label(
prob_frame,
text="Modifier Probability:",
font=('Arial', 11, 'bold'),
fg='white',
bg='#1a6b4d'
).pack(side=tk.LEFT)
self.prob_var = tk.IntVar(value=30)
self.prob_scale = tk.Scale(
prob_frame,
from_=0,
to=100,
orient=tk.HORIZONTAL,
variable=self.prob_var,
command=self.update_prob_display,
bg='#1a6b4d',
fg='white',
highlightbackground='#1a6b4d',
troughcolor='#0f4c3a',
activebackground='#ffd700'
)
self.prob_scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(10, 5))
self.prob_label = tk.Label(
prob_frame,
text="30%",
font=('Arial', 11, 'bold'),
fg='#ffd700',
bg='#1a6b4d',
width=5
)
self.prob_label.pack(side=tk.RIGHT)
# Debug controls frame
debug_frame = tk.Frame(settings_frame, bg='#1a6b4d')
debug_frame.pack(fill=tk.X, padx=10, pady=5)
# Debug mode toggle
self.debug_var = tk.BooleanVar(value=False)
debug_check = tk.Checkbutton(
debug_frame,
text="Debug Mode",
variable=self.debug_var,
command=self.toggle_debug_mode,
bg='#1a6b4d',
fg='white',
selectcolor='#0f4c3a',
activebackground='#1a6b4d',
activeforeground='#ffd700',
font=('Arial', 10, 'bold')
)
debug_check.pack(side=tk.LEFT, padx=(0, 15))
# Force endgame button (only visible in debug mode)
self.force_endgame_button = tk.Button(
debug_frame,
text="Force Endgame",
command=self.toggle_force_endgame,
bg='#ff6b6b',
fg='white',
font=('Arial', 9, 'bold'),
relief=tk.RAISED,
bd=2
)
# Initially hidden
# Game length setting
length_frame = tk.Frame(settings_frame, bg='#1a6b4d')
length_frame.pack(fill=tk.X, padx=10, pady=5)
tk.Label(
length_frame,
text="Total Game Rounds:",
font=('Arial', 11, 'bold'),
fg='white',
bg='#1a6b4d'
).pack(side=tk.LEFT)
self.length_var = tk.IntVar(value=20)
self.length_scale = tk.Scale(
length_frame,
from_=5,
to=50,
orient=tk.HORIZONTAL,
variable=self.length_var,
command=self.update_length_display,
bg='#1a6b4d',
fg='white',
highlightbackground='#1a6b4d',
troughcolor='#0f4c3a',
activebackground='#ffd700'
)
self.length_scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(10, 5))
self.length_label = tk.Label(
length_frame,
text="20",
font=('Arial', 11, 'bold'),
fg='#ffd700',
bg='#1a6b4d',
width=5
)
self.length_label.pack(side=tk.RIGHT)
# Result display frame
self.result_frame = tk.Frame(
main_frame,
bg='#2d2d2d',
relief=tk.RIDGE,
bd=3,
height=150
)
self.result_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 20), padx=10)
self.result_frame.pack_propagate(False)
# Initial result text
self.result_label = tk.Label(
self.result_frame,
text="Click 'Start Round' to begin!",
font=('Arial', 14),
fg='#cccccc',
bg='#2d2d2d',
wraplength=500,
justify=tk.CENTER
)
self.result_label.pack(expand=True, fill=tk.BOTH, padx=20, pady=20)
# Button frame for Start and Reset
button_frame = tk.Frame(main_frame, bg='#0f4c3a')
button_frame.pack(fill=tk.X, pady=(0, 20), padx=10)
# Start button
self.start_button = tk.Button(
button_frame,
text="Start Round",
font=('Arial', 18, 'bold'),
bg='#ffd700',
fg='#0f4c3a',
activebackground='#ffed4e',
activeforeground='#0f4c3a',
relief=tk.RAISED,
bd=3,
command=self.start_round,
cursor='hand2'
)
self.start_button.pack(side=tk.LEFT, fill=tk.X, expand=True, ipady=10, padx=(0, 5))
# Reset button
self.reset_button = tk.Button(
button_frame,
text="Reset Game",
font=('Arial', 14, 'bold'),
bg='#ff6b6b',
fg='white',
activebackground='#ff5252',
activeforeground='white',
relief=tk.RAISED,
bd=3,
command=self.reset_game,
cursor='hand2'
)
self.reset_button.pack(side=tk.RIGHT, ipady=10, padx=(5, 0))
# Statistics frame
stats_frame = tk.Frame(main_frame, bg='#0f4c3a')
stats_frame.pack(fill=tk.X, padx=10)
# Rounds played
rounds_frame = tk.LabelFrame(
stats_frame,
text="Rounds Played",
font=('Arial', 10, 'bold'),
fg='#cccccc',
bg='#1a6b4d',
relief=tk.RIDGE,
bd=2
)
rounds_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 3))
self.rounds_label = tk.Label(
rounds_frame,
text="0",
font=('Arial', 20, 'bold'),
fg='#ffd700',
bg='#1a6b4d'
)
self.rounds_label.pack(pady=10)
# Modifiers applied
mods_frame = tk.LabelFrame(
stats_frame,
text="Modifiers Applied",
font=('Arial', 10, 'bold'),
fg='#cccccc',
bg='#1a6b4d',
relief=tk.RIDGE,
bd=2
)
mods_frame.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(3, 3))
self.mods_label = tk.Label(
mods_frame,
text="0",
font=('Arial', 20, 'bold'),
fg='#ffd700',
bg='#1a6b4d'
)
self.mods_label.pack(pady=10)
# Game phase indicator
phase_frame = tk.LabelFrame(
stats_frame,
text="Game Phase",
font=('Arial', 10, 'bold'),
fg='#cccccc',
bg='#1a6b4d',
relief=tk.RIDGE,
bd=2
)
phase_frame.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=(3, 0))
self.phase_label = tk.Label(
phase_frame,
text="Early",
font=('Arial', 16, 'bold'),
fg='#4CAF50',
bg='#1a6b4d'
)
self.phase_label.pack(pady=10)
def update_prob_display(self, value):
"""Update the probability percentage display"""
self.prob_label.config(text=f"{value}%")
def update_length_display(self, value):
"""Update the game length display"""
self.length_label.config(text=str(value))
self.total_game_rounds = int(value)
def toggle_debug_mode(self):
"""Toggle debug mode and show/hide debug controls"""
self.debug_mode = self.debug_var.get()
if self.debug_mode:
self.force_endgame_button.pack(side=tk.LEFT, padx=(0, 10))
print("🐛 Debug mode enabled")
else:
self.force_endgame_button.pack_forget()
self.force_endgame = False
print("🐛 Debug mode disabled")
def toggle_force_endgame(self):
"""Toggle forced endgame mode for testing"""
self.force_endgame = not self.force_endgame
if self.force_endgame:
self.force_endgame_button.config(text="Stop Force Endgame", bg='#4CAF50')
print("🎯 Forcing endgame modifiers")
else:
self.force_endgame_button.config(text="Force Endgame", bg='#ff6b6b')
print("🎯 Normal modifier selection restored")
def is_endgame(self):
"""Determine if we're in endgame phase"""
if self.debug_mode and self.force_endgame:
return True
endgame_round = int(self.total_game_rounds * self.endgame_threshold)
return self.rounds_played >= endgame_round
def start_round(self):
"""Start a new poker round and determine if modifier should be applied"""
# Button animation effect
self.start_button.config(relief=tk.SUNKEN)
self.root.after(100, lambda: self.start_button.config(relief=tk.RAISED))
# Update round counter
self.rounds_played += 1
self.rounds_label.config(text=str(self.rounds_played))
# Update game phase indicator
self.update_phase_indicator()
# Get current probability
modifier_chance = self.prob_var.get()
# Determine if modifier should be applied
random_value = random.random() * 100
should_apply_modifier = random_value < modifier_chance
if should_apply_modifier:
self.apply_random_modifier()
else:
self.show_no_modifier()
def update_phase_indicator(self):
"""Update the game phase indicator based on current round"""
if self.is_endgame():
self.phase_label.config(text="Endgame", fg='#ff6b6b')
elif self.rounds_played >= self.total_game_rounds * 0.6:
self.phase_label.config(text="Late", fg='#ffa500')
elif self.rounds_played >= self.total_game_rounds * 0.3:
self.phase_label.config(text="Mid", fg='#ffeb3b')
else:
self.phase_label.config(text="Early", fg='#4CAF50')
def apply_random_modifier(self):
"""Apply a random modifier and update display"""
# Update modifier counter
self.modifiers_applied += 1
self.mods_label.config(text=str(self.modifiers_applied))
# Determine which modifier pool to use
if self.is_endgame():
modifier_pool = self.endgame_modifiers
modifier_type = "🏁 ENDGAME"
bg_color = '#4a2d2d' # Darker red for endgame
else:
modifier_pool = self.modifiers
modifier_type = "🎲"
bg_color = '#2d4a2d' # Green for normal
# Select random modifier from appropriate pool
selected_modifier = random.choice(modifier_pool).copy()
# Special handling for Steel Cards - randomize the rank
if selected_modifier['name'] == 'Steel Cards':
ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace']
steel_rank = random.choice(ranks)
selected_modifier['description'] = selected_modifier['description'].format(steel_rank=steel_rank)
# Update result frame styling for modifier
self.result_frame.config(bg=bg_color, highlightbackground='#ffd700', highlightthickness=2)
# Update display with modifier info
modifier_text = f"{modifier_type} {selected_modifier['name']}\n\n{selected_modifier['description']}"
# Add endgame indicator if applicable
if self.is_endgame():
rounds_left = self.total_game_rounds - self.rounds_played
if rounds_left > 0:
modifier_text += f"\n\n⚠️ Endgame Phase - {rounds_left} rounds left"
else:
modifier_text += f"\n\n⚠️ FINAL ROUND!"
self.result_label.config(
text=modifier_text,
fg='#ffd700',
bg=bg_color,
font=('Arial', 14, 'bold')
)
def show_no_modifier(self):
"""Show no modifier message"""
# Update result frame styling for no modifier
self.result_frame.config(bg='#2d2d2d', highlightbackground='#666666', highlightthickness=1)
# Update display
self.result_label.config(
text="No modifier this round\n\nPlay normally",
fg='#cccccc',
bg='#2d2d2d',
font=('Arial', 14)
)
def reset_game(self):
"""Reset the game to initial state"""
self.rounds_played = 0
self.modifiers_applied = 0
self.force_endgame = False
# Update displays
self.rounds_label.config(text="0")
self.mods_label.config(text="0")
self.phase_label.config(text="Early", fg='#4CAF50')
# Reset result frame
self.result_frame.config(bg='#2d2d2d', highlightbackground='#666666', highlightthickness=1)
self.result_label.config(
text="Click 'Start Round' to begin!",
fg='#cccccc',
bg='#2d2d2d',
font=('Arial', 14)
)
# Reset force endgame button if visible
if self.debug_mode:
self.force_endgame_button.config(text="Force Endgame", bg='#ff6b6b')
print("🔄 Game reset to initial state")
def add_modifier(self, name, description):
"""Add a new modifier to the list"""
self.modifiers.append({"name": name, "description": description})
def get_stats(self):
"""Get current statistics"""
modifier_rate = 0 if self.rounds_played == 0 else (self.modifiers_applied / self.rounds_played) * 100
rounds_remaining = max(0, self.total_game_rounds - self.rounds_played)
return {
"rounds_played": self.rounds_played,
"modifiers_applied": self.modifiers_applied,
"modifier_rate": round(modifier_rate, 1),
"total_game_rounds": self.total_game_rounds,
"rounds_remaining": rounds_remaining,
"is_endgame": self.is_endgame(),
"debug_mode": self.debug_mode,
"force_endgame": self.force_endgame
}
def run(self):
"""Start the application"""
print("🃏 Texas Hold'em Modifier App started!")
print("Available methods: app.get_stats(), app.add_modifier(name, description)")
print("Debug features: Toggle debug mode to access force endgame controls")
print(f"Default game length: {self.total_game_rounds} rounds")
print(f"Endgame threshold: {int(self.endgame_threshold * 100)}% ({int(self.total_game_rounds * self.endgame_threshold)} rounds)")
self.root.mainloop()
if __name__ == "__main__":
app = PokerModifierApp()
app.run()

View File

@ -0,0 +1,175 @@
class PokerModifierApp {
constructor() {
this.modifiers = [
{
name: "High Stakes",
description: "All bets are doubled this round!"
},
{
name: "Wild Card",
description: "The next card revealed can be used as any card!"
},
{
name: "Bluff Master",
description: "Players can see one opponent's card before betting."
},
{
name: "All-In Fever",
description: "If someone goes all-in, everyone must match or fold."
},
{
name: "Lucky Sevens",
description: "Any hand with a 7 beats a pair!"
},
{
name: "Reverse Psychology",
description: "Lowest hand wins this round!"
},
{
name: "Split Pot",
description: "The pot is split between the top 2 hands."
},
{
name: "Texas Twister",
description: "Each player gets an extra hole card this round."
},
{
name: "Blind Luck",
description: "All players must play blind (no looking at cards) until the river."
},
{
name: "Community Boost",
description: "An extra community card is revealed (6 total)."
},
{
name: "Minimum Madness",
description: "Minimum bet is tripled this round."
},
{
name: "Suit Supremacy",
description: "All cards of the chosen suit (random) are worth +1 rank."
},
{
name: "Quick Draw",
description: "Betting time is cut in half - make decisions fast!"
},
{
name: "Royal Treatment",
description: "Face cards (J, Q, K) are worth double."
},
{
name: "Chip Challenge",
description: "Winner gets extra chips from the house!"
}
];
this.roundsPlayed = 0;
this.modifiersApplied = 0;
this.initializeElements();
this.attachEventListeners();
this.updateChanceDisplay();
}
initializeElements() {
this.startButton = document.getElementById('startRoundBtn');
this.resultDisplay = document.getElementById('resultDisplay');
this.modifierChanceSlider = document.getElementById('modifierChance');
this.chanceValueDisplay = document.getElementById('chanceValue');
this.roundsCountDisplay = document.getElementById('roundsCount');
this.modifiersCountDisplay = document.getElementById('modifiersCount');
}
attachEventListeners() {
this.startButton.addEventListener('click', () => this.startRound());
this.modifierChanceSlider.addEventListener('input', () => this.updateChanceDisplay());
}
updateChanceDisplay() {
const chance = this.modifierChanceSlider.value;
this.chanceValueDisplay.textContent = `${chance}%`;
}
startRound() {
// Add button animation
this.startButton.style.transform = 'scale(0.95)';
setTimeout(() => {
this.startButton.style.transform = '';
}, 150);
// Update round counter
this.roundsPlayed++;
this.roundsCountDisplay.textContent = this.roundsPlayed;
// Get current probability
const modifierChance = parseInt(this.modifierChanceSlider.value);
// Determine if a modifier should be applied
const randomValue = Math.random() * 100;
const shouldApplyModifier = randomValue < modifierChance;
if (shouldApplyModifier) {
this.applyRandomModifier();
} else {
this.showNoModifier();
}
// Add some visual feedback with animation
this.resultDisplay.style.opacity = '0';
this.resultDisplay.style.transform = 'scale(0.8)';
setTimeout(() => {
this.resultDisplay.style.opacity = '1';
this.resultDisplay.style.transform = 'scale(1)';
}, 200);
}
applyRandomModifier() {
// Update modifier counter
this.modifiersApplied++;
this.modifiersCountDisplay.textContent = this.modifiersApplied;
// Select random modifier
const randomIndex = Math.floor(Math.random() * this.modifiers.length);
const selectedModifier = this.modifiers[randomIndex];
// Update display
this.resultDisplay.className = 'result-display has-modifier';
this.resultDisplay.innerHTML = `
<div class="modifier-title">🎲 ${selectedModifier.name}</div>
<div class="modifier-description">${selectedModifier.description}</div>
`;
}
showNoModifier() {
this.resultDisplay.className = 'result-display no-modifier';
this.resultDisplay.innerHTML = `
<div class="no-modifier-text">No modifier this round</div>
<div style="font-size: 0.9rem; color: #999; margin-top: 0.5rem;">Play normally</div>
`;
}
// Method to add new modifiers (for future expansion)
addModifier(name, description) {
this.modifiers.push({ name, description });
}
// Method to get statistics
getStats() {
return {
roundsPlayed: this.roundsPlayed,
modifiersApplied: this.modifiersApplied,
modifierRate: this.roundsPlayed > 0 ? (this.modifiersApplied / this.roundsPlayed * 100).toFixed(1) : 0
};
}
}
// Initialize the app when the page loads
document.addEventListener('DOMContentLoaded', () => {
window.pokerApp = new PokerModifierApp();
// Add some console info for developers
console.log('🃏 Texas Hold\'em Modifier App loaded!');
console.log('Access the app instance via window.pokerApp');
console.log('Available methods: getStats(), addModifier(name, description)');
});

View File

@ -0,0 +1,234 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #0f4c3a, #1a6b4d);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
}
.container {
max-width: 600px;
width: 90%;
padding: 2rem;
}
h1 {
text-align: center;
font-size: 2.5rem;
margin-bottom: 2rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.game-area {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 2rem;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.probability-settings {
margin-bottom: 2rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.probability-settings h3 {
margin-bottom: 1rem;
color: #ffd700;
text-align: center;
}
.setting {
display: flex;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.setting label {
font-weight: bold;
min-width: 150px;
}
#modifierChance {
flex: 1;
min-width: 150px;
height: 8px;
background: rgba(255, 255, 255, 0.2);
border-radius: 5px;
outline: none;
appearance: none;
}
#modifierChance::-webkit-slider-thumb {
appearance: none;
width: 20px;
height: 20px;
background: #ffd700;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#modifierChance::-moz-range-thumb {
width: 20px;
height: 20px;
background: #ffd700;
border-radius: 50%;
cursor: pointer;
border: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#chanceValue {
font-weight: bold;
color: #ffd700;
min-width: 40px;
text-align: center;
}
.result-area {
margin: 2rem 0;
min-height: 120px;
display: flex;
align-items: center;
justify-content: center;
}
.result-display {
text-align: center;
padding: 2rem;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
border: 2px solid rgba(255, 255, 255, 0.1);
min-height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
transition: all 0.3s ease;
}
.result-display.no-modifier {
border-color: rgba(128, 128, 128, 0.5);
background: rgba(128, 128, 128, 0.1);
}
.result-display.has-modifier {
border-color: #ffd700;
background: rgba(255, 215, 0, 0.1);
box-shadow: 0 0 20px rgba(255, 215, 0, 0.3);
}
.modifier-title {
font-size: 1.5rem;
font-weight: bold;
color: #ffd700;
margin-bottom: 0.5rem;
}
.modifier-description {
font-size: 1rem;
line-height: 1.4;
color: #fff;
}
.no-modifier-text {
font-size: 1.2rem;
color: #ccc;
}
.start-button {
width: 100%;
padding: 1rem 2rem;
font-size: 1.5rem;
font-weight: bold;
background: linear-gradient(45deg, #ffd700, #ffed4e);
color: #0f4c3a;
border: none;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(255, 215, 0, 0.3);
margin-bottom: 2rem;
}
.start-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(255, 215, 0, 0.4);
background: linear-gradient(45deg, #ffed4e, #ffd700);
}
.start-button:active {
transform: translateY(0);
box-shadow: 0 2px 10px rgba(255, 215, 0, 0.3);
}
.stats {
display: flex;
justify-content: space-around;
gap: 1rem;
flex-wrap: wrap;
}
.stat {
background: rgba(255, 255, 255, 0.1);
padding: 1rem;
border-radius: 8px;
text-align: center;
flex: 1;
min-width: 150px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.stat-label {
display: block;
font-size: 0.9rem;
color: #ccc;
margin-bottom: 0.5rem;
}
.stat span:last-child {
font-size: 1.5rem;
font-weight: bold;
color: #ffd700;
}
@media (max-width: 600px) {
.container {
padding: 1rem;
}
h1 {
font-size: 2rem;
}
.game-area {
padding: 1.5rem;
}
.setting {
flex-direction: column;
align-items: stretch;
}
.setting label {
min-width: auto;
text-align: center;
}
.stats {
flex-direction: column;
}
}