+
+ Total Heads:
0
-
-
Tails:
+
+ Total Tails:
0
@@ -32,23 +73,73 @@ function getCoinFlipHTML() {
`;
@@ -173,12 +409,73 @@ function initCoinFlip() {
const coinScene = coin.closest('.coin-scene');
const flipBtn = document.getElementById('flipCoin');
const result = document.getElementById('coinResult');
+
+ // Core Elements
const headsCountEl = document.getElementById('headsCount');
const tailsCountEl = document.getElementById('tailsCount');
- let headsCount = 0;
- let tailsCount = 0;
+ const predictHeadsBtn = document.getElementById('predictHeads');
+ const predictTailsBtn = document.getElementById('predictTails');
+ const predictionWrapper = predictHeadsBtn.closest('.prediction-cards');
+
+ // Scoreboard Elements
+ const statsWinsEl = document.getElementById('statsWins');
+ const statsLossesEl = document.getElementById('statsLosses');
+ const statsStreakEl = document.getElementById('statsStreak');
+ const statsBestStreakEl = document.getElementById('statsBestStreak');
+
+ // Retrieve stats from localStorage
+ let wins = parseInt(localStorage.getItem('coinflip_wins') || '0');
+ let losses = parseInt(localStorage.getItem('coinflip_losses') || '0');
+ let streak = parseInt(localStorage.getItem('coinflip_streak') || '0');
+ let bestStreak = parseInt(localStorage.getItem('coinflip_best_streak') || '0');
+ let headsCount = parseInt(localStorage.getItem('coinflip_heads') || '0');
+ let tailsCount = parseInt(localStorage.getItem('coinflip_tails') || '0');
let spinCount = 0;
+ let selectedPrediction = null;
+
+ // Render Initial Stats
+ function updateStatsUI() {
+ statsWinsEl.textContent = wins;
+ statsLossesEl.textContent = losses;
+ statsStreakEl.textContent = `🔥 ${streak}`;
+ statsBestStreakEl.textContent = `🏆 ${bestStreak}`;
+ headsCountEl.textContent = headsCount;
+ tailsCountEl.textContent = tailsCount;
+ }
+ updateStatsUI();
+
+ // Prediction cards event listeners
+ function selectPrediction(prediction) {
+ selectedPrediction = prediction;
+
+ predictHeadsBtn.classList.remove('selected');
+ predictTailsBtn.classList.remove('selected');
+
+ if (prediction === 'heads') {
+ predictHeadsBtn.classList.add('selected');
+ result.textContent = 'Predicted Heads! Ready to flip.';
+ } else if (prediction === 'tails') {
+ predictTailsBtn.classList.add('selected');
+ result.textContent = 'Predicted Tails! Ready to flip.';
+ }
+
+ result.className = 'coin-result'; // reset any win/lose classes
+ flipBtn.disabled = false;
+ }
+
+ predictHeadsBtn.addEventListener('click', () => {
+ if (!flipBtn.disabled || selectedPrediction === null) {
+ selectPrediction('heads');
+ }
+ });
+ predictTailsBtn.addEventListener('click', () => {
+ if (!flipBtn.disabled || selectedPrediction === null) {
+ selectPrediction('tails');
+ }
+ });
+
+ // 3D Coin Rotate Calculations
function setCoinFace(isHeads, seed) {
const targetY = isHeads ? 0 : 180;
const flipX = 360 * (4 + (seed % 3));
@@ -187,6 +484,7 @@ function initCoinFlip() {
coin.style.setProperty('--flip-y', `${flipY}deg`);
}
+ // Landing bounce effect
function triggerCoinLanding() {
coinScene.classList.remove('impact');
void coinScene.offsetWidth;
@@ -196,28 +494,66 @@ function initCoinFlip() {
}, 460);
}
+ // Main flip trigger
flipBtn.addEventListener('click', () => {
+ if (!selectedPrediction) return;
+
+ // Freeze controls during flip
flipBtn.disabled = true;
+ predictionWrapper.classList.add('disabled-cards');
result.textContent = 'Flipping...';
+ result.className = 'coin-result flipping';
coinScene.classList.add('rolling');
const isHeads = Math.random() < 0.5;
+ const flipResult = isHeads ? 'heads' : 'tails';
spinCount += 1;
+
setCoinFace(isHeads, spinCount);
setTimeout(() => {
coinScene.classList.remove('rolling');
triggerCoinLanding();
+
+ // Check win/loss logic
+ const isCorrect = (flipResult === selectedPrediction);
+
+ // Lifetime stats update
if (isHeads) {
- result.textContent = '👑 Heads!';
headsCount++;
- headsCountEl.textContent = headsCount;
} else {
- result.textContent = '🦅 Tails!';
tailsCount++;
- tailsCountEl.textContent = tailsCount;
}
+
+ if (isCorrect) {
+ wins++;
+ streak++;
+ if (streak > bestStreak) {
+ bestStreak = streak;
+ }
+ result.textContent = isHeads ? '👑 Heads! Correct prediction! 🎉' : '🦅 Tails! Correct prediction! 🎉';
+ result.className = 'coin-result win';
+ } else {
+ losses++;
+ streak = 0;
+ result.textContent = isHeads ? '👑 Heads! Wrong prediction. 😢' : '🦅 Tails! Wrong prediction. 😢';
+ result.className = 'coin-result lose';
+ }
+
+ // Persist scores
+ localStorage.setItem('coinflip_wins', wins);
+ localStorage.setItem('coinflip_losses', losses);
+ localStorage.setItem('coinflip_streak', streak);
+ localStorage.setItem('coinflip_best_streak', bestStreak);
+ localStorage.setItem('coinflip_heads', headsCount);
+ localStorage.setItem('coinflip_tails', tailsCount);
+
+ // Update scoreboard & stats views
+ updateStatsUI();
+
+ // Re-enable controls
flipBtn.disabled = false;
+ predictionWrapper.classList.remove('disabled-cards');
}, 1600);
});
}