From 189c4bde54d24b6176e2ce41aeca2904ffa8369a Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 5 Sep 2025 05:03:21 +0000 Subject: [PATCH] Add simulation functionality --- src/components/CrapsGame.tsx | 130 ++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/src/components/CrapsGame.tsx b/src/components/CrapsGame.tsx index 51526af..8fb71ad 100644 --- a/src/components/CrapsGame.tsx +++ b/src/components/CrapsGame.tsx @@ -4,7 +4,8 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Badge } from '@/components/ui/badge'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'; import { Checkbox } from '@/components/ui/checkbox'; -import { Dice1, Dice2, Dice3, Dice4, Dice5, Dice6, RotateCcw, Settings } from 'lucide-react'; +import { Slider } from '@/components/ui/slider'; +import { Dice1, Dice2, Dice3, Dice4, Dice5, Dice6, RotateCcw, Settings, Play } from 'lucide-react'; import SocialShare from '@/components/SocialShare'; interface CrapsGameProps { @@ -35,6 +36,16 @@ const CrapsGame: React.FC = ({ showSocialShare = false }) => { const [customLoseSums, setCustomLoseSums] = useState([2, 3, 12]); const [isCustomRules, setIsCustomRules] = useState(false); const [isRulesModalOpen, setIsRulesModalOpen] = useState(false); + + // Simulation state + const [simulationRounds, setSimulationRounds] = useState([10]); + const [isSimulating, setIsSimulating] = useState(false); + const [simulationResults, setSimulationResults] = useState<{ + wins: number; + losses: number; + averageTurns: number; + totalGames: number; + } | null>(null); const rollDice = () => { setIsRolling(true); @@ -66,11 +77,75 @@ const CrapsGame: React.FC = ({ showSocialShare = false }) => { }, 1000); }; + const simulateGame = () => { + const winSums = isCustomRules ? customWinSums : [7, 11]; + const loseSums = isCustomRules ? customLoseSums : [2, 3, 12]; + + let turns = 1; + let point: number | null = null; + + while (true) { + const die1 = Math.floor(Math.random() * 6) + 1; + const die2 = Math.floor(Math.random() * 6) + 1; + const sum = die1 + die2; + + if (point === null) { + // First roll (come out roll) + if (loseSums.includes(sum)) { + return { result: 'lose', turns }; + } else if (winSums.includes(sum)) { + return { result: 'win', turns }; + } else { + point = sum; + turns++; + } + } else { + // Subsequent rolls + if (sum === point) { + return { result: 'win', turns }; + } else if (sum === 7) { + return { result: 'lose', turns }; + } else { + turns++; + } + } + } + }; + + const runSimulation = async () => { + setIsSimulating(true); + const numGames = simulationRounds[0]; + let wins = 0; + let losses = 0; + let totalTurns = 0; + + // Add small delays to show progress + for (let i = 0; i < numGames; i++) { + const game = simulateGame(); + if (game.result === 'win') wins++; + else losses++; + totalTurns += game.turns; + + // Add a small delay every 10 games to show progress + if (i % 10 === 0) { + await new Promise(resolve => setTimeout(resolve, 50)); + } + } + + setSimulationResults({ + wins, + losses, + averageTurns: totalTurns / numGames, + totalGames: numGames + }); + setIsSimulating(false); + }; + const resetGame = () => { setDice1(null); setDice2(null); setGameResult(null); - setRollCount(0); + setSimulationResults(null); }; const sum = dice1 && dice2 ? dice1 + dice2 : null; @@ -127,6 +202,57 @@ const CrapsGame: React.FC = ({ showSocialShare = false }) => { + {/* Simulation Controls */} + + + Simulation + + Run multiple games to analyze win/loss statistics + + + +
+ + +
+ + + {simulationResults && ( +
+
+
{simulationResults.wins}
+
Wins
+
({((simulationResults.wins / simulationResults.totalGames) * 100).toFixed(1)}%)
+
+
+
{simulationResults.losses}
+
Losses
+
({((simulationResults.losses / simulationResults.totalGames) * 100).toFixed(1)}%)
+
+
+
{simulationResults.averageTurns.toFixed(1)}
+
Avg Turns
+
per game
+
+
+ )} +
+
+ {/* Rules */}