From 489df7b113238edc1d79fb3c759d297945c09620 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Nov 2025 02:35:15 +0000 Subject: [PATCH] Fix tie detection in Presents Puzzle - Both players now properly tie when they find all 26 presents on the same turn - Single simulation displays "It's a tie!" message when both finish together - Batch simulation (100 rounds) now tracks and displays ties separately - Updated results grid to show three columns: Alice, Bob, and Ties - Fixed logic to check both players on the same iteration - No longer unfairly favors Alice in tie scenarios --- src/components/PresentsPuzzle.tsx | 77 ++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/src/components/PresentsPuzzle.tsx b/src/components/PresentsPuzzle.tsx index 93da4e1..e84e976 100644 --- a/src/components/PresentsPuzzle.tsx +++ b/src/components/PresentsPuzzle.tsx @@ -23,7 +23,7 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro const [aliceFound, setAliceFound] = useState(0); const [bobFound, setBobFound] = useState(0); const [isRunning, setIsRunning] = useState(false); - const [winner, setWinner] = useState<'alice' | 'bob' | null>(null); + const [winner, setWinner] = useState<'alice' | 'bob' | 'tie' | null>(null); const [simulationResults, setSimulationResults] = useState({ alice: 0, bob: 0, ties: 0 }); const [hasSimulated, setHasSimulated] = useState(false); @@ -49,7 +49,7 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro }; // Simulate one round - const simulateRound = (presents: Set): 'alice' | 'bob' => { + const simulateRound = (presents: Set): 'alice' | 'bob' | 'tie' => { const aliceOrder = getAliceOrder(); const bobOrder = getBobOrder(); @@ -57,18 +57,21 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro let bobCount = 0; for (let i = 0; i < 100; i++) { - if (presents.has(aliceOrder[i])) { - aliceCount++; - if (aliceCount === 26) return 'alice'; - } + const aliceFoundPresent = presents.has(aliceOrder[i]); + const bobFoundPresent = presents.has(bobOrder[i]); - if (presents.has(bobOrder[i])) { - bobCount++; - if (bobCount === 26) return 'bob'; - } + if (aliceFoundPresent) aliceCount++; + if (bobFoundPresent) bobCount++; + + // Check if both reached 26 on the same turn (tie) + if (aliceCount === 26 && bobCount === 26) return 'tie'; + + // Check individual winners + if (aliceCount === 26) return 'alice'; + if (bobCount === 26) return 'bob'; } - return 'alice'; // Default, though this should never happen + return 'tie'; // Default, though this should never happen }; // Animate a single simulation @@ -88,7 +91,7 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro let aliceCount = 0; let bobCount = 0; - let currentWinner: 'alice' | 'bob' | null = null; + let currentWinner: 'alice' | 'bob' | 'tie' | null = null; for (let i = 0; i < 100 && !currentWinner; i++) { await new Promise(resolve => setTimeout(resolve, 50)); // Animation delay @@ -99,20 +102,26 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro setAliceOpened(prev => new Set(prev).add(aliceBox)); setBobOpened(prev => new Set(prev).add(bobBox)); - if (presents.has(aliceBox)) { + const aliceFoundPresent = presents.has(aliceBox); + const bobFoundPresent = presents.has(bobBox); + + if (aliceFoundPresent) { aliceCount++; setAliceFound(aliceCount); - if (aliceCount === 26) { - currentWinner = 'alice'; - } } - if (presents.has(bobBox)) { + if (bobFoundPresent) { bobCount++; setBobFound(bobCount); - if (bobCount === 26 && !currentWinner) { - currentWinner = 'bob'; - } + } + + // Check for tie first (both reach 26 on same turn) + if (aliceCount === 26 && bobCount === 26) { + currentWinner = 'tie'; + } else if (aliceCount === 26) { + currentWinner = 'alice'; + } else if (bobCount === 26) { + currentWinner = 'bob'; } } @@ -140,8 +149,10 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro const winner = simulateRound(presents); if (winner === 'alice') { results.alice++; - } else { + } else if (winner === 'bob') { results.bob++; + } else { + results.ties++; } } @@ -236,7 +247,10 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro
- {winner === 'alice' ? '🎉 Alice' : '🎉 Bob'} found all 26 presents first! + {winner === 'tie' + ? "🤝 It's a tie! Both found all 26 presents at the same time!" + : `🎉 ${winner === 'alice' ? 'Alice' : 'Bob'} found all 26 presents first!` + }
@@ -285,7 +299,7 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro Results from 100 Simulations -
+
{simulationResults.alice} @@ -304,15 +318,26 @@ const PresentsPuzzle = ({ showSocialShare = false, shareUrl }: PresentsPuzzlePro {((simulationResults.bob / 100) * 100).toFixed(1)}%
+
+
+ {simulationResults.ties} +
+
Ties
+
+ {((simulationResults.ties / 100) * 100).toFixed(1)}% +
+

- {simulationResults.alice > simulationResults.bob + {simulationResults.alice > simulationResults.bob && simulationResults.alice > simulationResults.ties ? '💡 Alice tends to win more often!' - : simulationResults.bob > simulationResults.alice + : simulationResults.bob > simulationResults.alice && simulationResults.bob > simulationResults.ties ? '💡 Bob tends to win more often!' - : '💡 They appear equally likely to win!' + : simulationResults.ties > simulationResults.alice && simulationResults.ties > simulationResults.bob + ? '💡 Ties are most common!' + : '💡 The results are quite balanced!' }