African Mancala (Hard Mode) – Wagers & Payouts

🌍 African Mancala (Hard Mode) – Wagers, Tax & Payouts 🌍

Authentic Oware Game with Traditional Wooden Board & Seeds
Tax: 16% • Winner: 75% • House: 25%
Ready to play! Set your wager and start the game.
Turn: —
Mode: —
Rules: sow seeds counter-clockwise, skipping opponent's store. Last seed in own store → extra turn. Last seed in empty pit on own side → capture + opposite seeds.
/* Config */ const TAX_RATE = 0.16, WINNER_SHARE = 0.75, HOUSE_SHARE = 0.25; const HOLES_PER_SIDE = 6, SEEDS_PER_HOLE = 4; const LINK_EXPIRY_MINUTES = 60; // 1 hour expiry /* State */ let mode="single", board=[], turn=0, gameActive=false, wagers={p1:0,p2:0}; let gameRoom = null; let playerRole = null; // 'host' or 'guest' let expiryTimer = null; /* Simulated Server Storage - Using localStorage with expiry for demo */ function getGameRooms() { try { const stored = localStorage.getItem('mancala_game_rooms'); if (!stored) return {}; const rooms = JSON.parse(stored); const now = Date.now(); // Clean up expired rooms for (const [roomId, room] of Object.entries(rooms)) { if (now > room.expiresAt) { delete rooms[roomId]; } } localStorage.setItem('mancala_game_rooms', JSON.stringify(rooms)); return rooms; } catch (e) { return {}; } } function saveGameRoom(roomId, room) { try { const rooms = getGameRooms(); rooms[roomId] = room; localStorage.setItem('mancala_game_rooms', JSON.stringify(rooms)); return true; } catch (e) { console.error('Failed to save room:', e); return false; } } function deleteGameRoom(roomId) { try { const rooms = getGameRooms(); delete rooms[roomId]; localStorage.setItem('mancala_game_rooms', JSON.stringify(rooms)); return true; } catch (e) { return false; } } /* Game Room Management */ function createGameRoom(hostWager) { const roomId = generateRoomId(); const room = { id: roomId, host: { name: "Player 1", wager: hostWager, connected: true, ready: true }, guest: null, status: "waiting", // waiting, active, finished, cancelled board: null, turn: 0, createdAt: Date.now(), expiresAt: Date.now() + (LINK_EXPIRY_MINUTES * 60 * 1000) }; if (saveGameRoom(roomId, room)) { return room; } return null; } function generateRoomId() { return Math.random().toString(36).substr(2, 9).toUpperCase(); } function joinGameRoom(roomId, guestWager) { const rooms = getGameRooms(); const room = rooms[roomId]; if (!room) { return { success: false, message: "Room not found" }; } if (Date.now() > room.expiresAt) { deleteGameRoom(roomId); return { success: false, message: "Room has expired" }; } if (room.guest) { return { success: false, message: "Room is full" }; } if (room.status !== "waiting") { return { success: false, message: "Game already started" }; } if (guestWager !== room.host.wager) { return { success: false, message: `Wager must be KSh ${room.host.wager}` }; } room.guest = { name: "Player 2", wager: guestWager, connected: true, ready: true }; room.status = "active"; if (saveGameRoom(roomId, room)) { return { success: true, room: room }; } return { success: false, message: "Failed to join room" }; } function cancelGameRoom(roomId) { const rooms = getGameRooms(); const room = rooms[roomId]; if (room && room.status === "waiting") { deleteGameRoom(roomId); return true; } return false; } /* URL Parameter Handling */ function getUrlParameter(name) { try { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); } catch (e) { console.log('URL parameter reading not available in this environment'); return null; } } function updateUrl(roomId = null) { try { const url = new URL(window.location); if (roomId) { url.searchParams.set('room', roomId); } else { url.searchParams.delete('room'); } window.history.replaceState({}, '', url); } catch (e) { console.log('URL manipulation not available in this environment'); // In iframe/restricted environments, we'll just store the room ID locally try { if (roomId) { sessionStorage.setItem('currentRoomId', roomId); } else { sessionStorage.removeItem('currentRoomId'); } } catch (storageErr) { console.log('Session storage not available'); } } } /* Helpers */ const $=id=>document.querySelector(id); const fmt=n=>(isNaN(n)||n===null)?"—":"KSh "+Number(n).toFixed(0); function initBoard(){ board=new Array(14).fill(0); for(let i=0;i=7;i--) root.appendChild(pitEl(i,1)); // Player 1 store (bottom right) root.appendChild(storeEl(6,"P1 Store")); // Empty div for grid spacing root.appendChild(document.createElement("div")); // Player 1 pits (bottom row, left to right: 0,1,2,3,4,5) for(let i=0;i<=5;i++) root.appendChild(pitEl(i,0)); // Empty div for grid spacing root.appendChild(document.createElement("div")); // Update status $("#turnLabel").textContent="Turn: "+(turn===0?"Player 1":(mode==="single"?"System":"Player 2")); $("#modeLabel").textContent="Mode: "+(mode==="single"?"Single vs System":"Online Multiplayer"); } function pitEl(i,owner){ const d=document.createElement("div"); d.className="pit"; if(!gameActive||!(turn===owner)||board[i]===0) d.classList.add("disabled"); const seedCount = board[i]; if(seedCount > 0) { d.innerHTML = `
${createSeedVisuals(seedCount)}
${seedCount}
`; } else { d.innerHTML = `
0
`; } d.onclick=()=>onPitClick(i,owner); return d; } function storeEl(i,name){ const d=document.createElement("div"); d.className="store"; const seedCount = board[i]; if(seedCount > 0) { d.innerHTML = `
${createSeedVisuals(Math.min(seedCount, 12))}
${seedCount}
`; } else { d.innerHTML = `
0
`; } return d; } function createSeedVisuals(count) { const maxVisible = count > 8 ? 8 : count; let seedsHtml = ''; for(let i = 0; i < maxVisible; i++) { const rotation = Math.random() * 360; const offsetX = Math.random() * 20 - 10; const offsetY = Math.random() * 20 - 10; seedsHtml += `
`; } return seedsHtml; } function isGameOver(){ return [0,1,2,3,4,5].every(i=>board[i]===0)||[7,8,9,10,11,12].every(i=>board[i]===0); } function collectRemaining(){ let p1=[0,1,2,3,4,5].reduce((a,i)=>a+board[i],0); let p2=[7,8,9,10,11,12].reduce((a,i)=>a+board[i],0); board[6]+=p1; board[13]+=p2; for(let i of [0,1,2,3,4,5])board[i]=0; for(let i of [7,8,9,10,11,12])board[i]=0; } function makeMove(from,pl){ return new Promise((resolve) => { let seeds=board[from]; board[from]=0; let i=from; animateSeedMovement(from, seeds, pl, () => { const ownStore=(pl===0?6:13); const ownSide=(pl===0?[0,1,2,3,4,5]:[7,8,9,10,11,12]); if(ownSide.includes(i)&&board[i]===1){ let opp=12-i; if(board[opp]>0){ board[ownStore]+=board[opp]+1; board[i]=0; board[opp]=0; renderBoard(); } } if(isGameOver())collectRemaining(); resolve(i===ownStore); }); while(seeds>0){ i=(i+1)%14; if(pl===0&&i===13)continue; if(pl===1&&i===6)continue; board[i]++; seeds--; } }); } function animateSeedMovement(startPit, seedCount, player, callback) { let currentPit = startPit; let remainingSeeds = seedCount; function animateNextSeed() { if (remainingSeeds <= 0) { callback(); return; } do { currentPit = (currentPit + 1) % 14; if(player === 0 && currentPit === 13) continue; if(player === 1 && currentPit === 6) continue; break; } while(true); createMovingSeedAnimation(startPit, currentPit, () => { renderBoard(); remainingSeeds--; setTimeout(animateNextSeed, 200); }); } renderBoard(); setTimeout(animateNextSeed, 300); } function createMovingSeedAnimation(fromPit, toPit, callback) { const fromElement = document.querySelector(`#board .pit:nth-child(${getPitDisplayIndex(fromPit) + 1}), #board .store:nth-child(${getPitDisplayIndex(fromPit) + 1})`); const toElement = document.querySelector(`#board .pit:nth-child(${getPitDisplayIndex(toPit) + 1}), #board .store:nth-child(${getPitDisplayIndex(toPit) + 1})`); if (!fromElement || !toElement) { callback(); return; } const animatedSeed = document.createElement('div'); animatedSeed.className = 'animated-seed'; animatedSeed.style.cssText = ` position: absolute; width: 12px; height: 12px; background: radial-gradient(circle at 30% 30%, #deb887, #a0522d, #8b4513, #654321); border-radius: 50%; box-shadow: inset 2px 2px 4px rgba(255,255,255,0.4), inset -2px -2px 4px rgba(0,0,0,0.4), 0 2px 6px rgba(0,0,0,0.4); z-index: 100; pointer-events: none; transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); `; const fromRect = fromElement.getBoundingClientRect(); const toRect = toElement.getBoundingClientRect(); const boardRect = document.querySelector('#board').getBoundingClientRect(); animatedSeed.style.left = (fromRect.left - boardRect.left + fromRect.width/2 - 6) + 'px'; animatedSeed.style.top = (fromRect.top - boardRect.top + fromRect.height/2 - 6) + 'px'; document.querySelector('#board').appendChild(animatedSeed); setTimeout(() => { animatedSeed.style.left = (toRect.left - boardRect.left + toRect.width/2 - 6) + 'px'; animatedSeed.style.top = (toRect.top - boardRect.top + toRect.height/2 - 6) + 'px'; animatedSeed.style.transform = 'scale(1.2)'; }, 10); setTimeout(() => { animatedSeed.remove(); callback(); }, 450); } function getPitDisplayIndex(pitIndex) { const displayOrder = [13, 12, 11, 10, 9, 8, 7, 6, -1, 0, 1, 2, 3, 4, 5, -1]; return displayOrder.indexOf(pitIndex); } function systemChooseMove(){ const pits=[12,11,10,9,8,7].filter(i=>board[i]>0); if(pits.length===0)return null; let best=pits[0], bestScore=-Infinity; for(let pit of pits){ let snapshot=board.slice(); let seeds=snapshot[pit]; snapshot[pit]=0; let idx=pit; while(seeds>0){ idx=(idx+1)%14; if(idx===6)continue; snapshot[idx]++; seeds--; } let score=snapshot[13]-snapshot[6]; if(idx===13)score+=2; if(score>bestScore){bestScore=score;best=pit;} } return best; } function computePayouts(winner){ const isOnline=(mode==="online"); const isSingle=(mode==="single"); const gross=isOnline?(wagers.p1+wagers.p2):(wagers.p1*2); // System matches wager in single mode const tax=gross*TAX_RATE; const net=gross-tax; let winnerText="",wPay=0,hPay=net*HOUSE_SHARE; if(winner==="Draw"){ winnerText="Draw"; return{gross,tax,net,winnerText,winnerPayout:0,housePayout:hPay}; } if(isOnline){ wPay=net*WINNER_SHARE; winnerText=winner+" Wins"; } else{ // Single player mode if(winner==="P1"){ wPay=net*WINNER_SHARE; winnerText="You Win"; }else{ hPay=net; // House takes all if system wins winnerText="System Wins"; } } return{gross,tax,net,winnerText,winnerPayout:wPay,housePayout:hPay}; } function updatePayoutPanel(p){ $("#p1w").textContent=wagers.p1?fmt(wagers.p1):"—"; if(mode==="online"){ $("#p2wRow").style.display=""; $("#p2Label").textContent="Player 2 Wager"; $("#p2w").textContent=wagers.p2?fmt(wagers.p2):"—"; } else if(mode==="single"){ $("#p2wRow").style.display=""; $("#p2Label").textContent="System Wager"; $("#p2w").textContent=wagers.p1?fmt(wagers.p1):"—"; } else{ $("#p2wRow").style.display="none"; } $("#grossPot").textContent=p?fmt(p.gross):"—"; $("#taxAmt").textContent=p?fmt(p.tax):"—"; $("#netPot").textContent=p?fmt(p.net):"—"; $("#winnerPay").textContent=p?fmt(p.winnerPayout):"—"; $("#housePay").textContent=p?fmt(p.housePayout):"—"; $("#result").textContent=p?p.winnerText:"—"; } function startSinglePlayerGame(){ let w1=+$("#wager1").value; if(!w1 || w1<100)return setMsg("Enter valid wager (minimum KSh 100)",true); wagers={p1:w1,p2:w1}; // System matches the wager mode="single"; initBoard(); turn=0; gameActive=true; // Show system match info $("#systemMatchInfo").style.display="block"; $("#systemPotAmount").textContent=fmt(w1*2); renderBoard(); setMsg("Game started! You vs System. System matched your wager.",false); updatePayoutPanel(null); // Hide online controls $("#online-controls").style.display="none"; $("#single-controls").style.display="block"; } function generateOnlineGame(){ let w1=+$("#wager1").value; if(!w1 || w1<100)return setMsg("Enter valid wager (minimum KSh 100)",true); // Simulate deposit processing setMsg("💳 Processing deposit...",false); setTimeout(()=>{ gameRoom = createGameRoom(w1); if (!gameRoom) { setMsg("Failed to create game room. Please try again.", true); return; } playerRole = "host"; wagers={p1:w1,p2:0}; // Generate shareable game URL - fallback for iframe environments let gameUrl; try { gameUrl = `${window.location.origin}${window.location.pathname}?room=${gameRoom.id}`; } catch (e) { // Fallback URL for iframe environments gameUrl = `https://mancala-game.example.com/play?room=${gameRoom.id}`; } $("#shareLink").value = gameUrl; $("#currentRoomId").textContent = gameRoom.id; // Update UI $("#generateLinkBtn").style.display="none"; $("#link-display").style.display="block"; $("#gameRoomInfo").style.display="block"; $("#systemMatchInfo").style.display="none"; updateUrl(gameRoom.id); startExpiryTimer(); setupSocialSharing(gameUrl, w1); setMsg("✅ Deposit successful! Share the link to invite opponent.",false); },1500); } function startExpiryTimer(){ if(expiryTimer) clearInterval(expiryTimer); expiryTimer = setInterval(()=>{ if(!gameRoom) return; const timeLeft = gameRoom.expiresAt - Date.now(); if(timeLeft <= 0){ clearInterval(expiryTimer); $("#linkStatus").textContent="❌ Link Expired"; $("#linkStatus").className="status-expired"; $("#linkExpiry").textContent=""; $("#cancelGameBtn").textContent="🔄 Create New Game"; setMsg("Link expired. Create a new game to play.",true); return; } const minutes = Math.floor(timeLeft / 60000); const seconds = Math.floor((timeLeft % 60000) / 1000); $("#linkExpiry").textContent=`Expires in: ${minutes}:${seconds.toString().padStart(2,'0')}`; },1000); } function setupSocialSharing(gameUrl, wager){ const message = `🎮 Join me for African Mancala! Wager: KSh ${wager} Winner takes 75% of pot after tax Room ID: ${gameRoom.id} ${gameUrl}`; const encodedMessage = encodeURIComponent(message); const encodedUrl = encodeURIComponent(gameUrl); // Social media sharing with fallback URLs $("#whatsappShare").href = `https://wa.me/?text=${encodedMessage}`; $("#twitterShare").href = `https://twitter.com/intent/tweet?text=${encodedMessage}`; $("#telegramShare").href = `https://t.me/share/url?url=${encodedUrl}&text=${encodeURIComponent('🎮 Join me for African Mancala! Room: '+gameRoom.id+' | Wager: KSh '+wager)}`; $("#facebookShare").href = `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`; $("#smsShare").onclick = ()=>{ try { if (navigator.share) { navigator.share({ title: 'African Mancala Game', text: message, url: gameUrl }); } else { const smsUrl = `sms:?body=${encodedMessage}`; window.open(smsUrl); } } catch (e) { // Fallback - copy to clipboard try { navigator.clipboard.writeText(message); setMsg("📱 Message copied to clipboard!", false); } catch (clipErr) { setMsg("📱 Copy the room ID: " + gameRoom.id, false); } } }; } function joinOnlineGame(roomId, guestWager){ const result = joinGameRoom(roomId, guestWager); if(!result.success){ setMsg(`❌ ${result.message}`,true); return; } gameRoom = result.room; playerRole = "guest"; wagers = {p1: gameRoom.host.wager, p2: guestWager}; // Start the game immediately initBoard(); turn = 0; gameActive = true; mode = "online"; $("#gameRoomInfo").style.display="block"; $("#currentRoomId").textContent = roomId; $("#hostStatus").textContent = "Connected"; $("#guestStatus").textContent = "Connected (You)"; renderBoard(); updatePayoutPanel(null); setMsg("✅ Joined game successfully! Game started.",false); // Hide join controls $("#joinRoomControls").style.display="none"; $("#toggleJoinBtn").style.display="none"; $("#online-controls").style.display="none"; } function cancelOnlineGame(){ if(gameRoom && playerRole === "host"){ if(cancelGameRoom(gameRoom.id)){ setMsg("💰 Game cancelled. Deposit refunded.",false); } } // Reset UI $("#generateLinkBtn").style.display="block"; $("#link-display").style.display="none"; $("#gameRoomInfo").style.display="none"; if(expiryTimer) clearInterval(expiryTimer); gameRoom = null; playerRole = null; updateUrl(); } function endGame(){ gameActive=false; renderBoard(); let p1=board[6],p2=board[13]; let winner="Draw"; if(p1>p2)winner="P1"; else if(p2>p1)winner=(mode==="single"?"System":"P2"); const pay=computePayouts(winner); updatePayoutPanel(pay); showResultsPanel(p1, p2, winner, pay); setMsg("Game Over: "+pay.winnerText,false); // Clean up online game if(gameRoom) { gameRoom.status = "finished"; saveGameRoom(gameRoom.id, gameRoom); if(expiryTimer) clearInterval(expiryTimer); } } function showResultsPanel(p1Score, p2Score, winner, payouts) { const resultsPanel = $("#resultsPanel"); const p2Label = mode === "single" ? "System" : "Player 2"; $("#p1Score").textContent = p1Score; $("#p2Score").textContent = p2Score; $("#p2ScoreLabel").textContent = p2Label; let resultText = ""; let celebrationText = ""; let payoutText = ""; if (winner === "Draw") { resultText = "🤝 It's a Draw!"; celebrationText = "🤝 Great Game!"; payoutText = "No winner - House takes commission"; $("#winnerCelebration").style.background = "linear-gradient(145deg, rgba(245, 158, 11, 0.2), rgba(245, 158, 11, 0.1))"; } else if (winner === "P1") { resultText = "🎉 Player 1 Wins!"; celebrationText = "🎉 Congratulations! 🎉"; payoutText = `You win ${fmt(payouts.winnerPayout)}!`; $("#winnerCelebration").style.background = "linear-gradient(145deg, rgba(34, 197, 94, 0.2), rgba(34, 197, 94, 0.1))"; } else if (winner === "System") { resultText = "🤖 System Wins!"; celebrationText = "🤖 System Victory!"; payoutText = "Better luck next time!"; $("#winnerCelebration").style.background = "linear-gradient(145deg, rgba(239, 68, 68, 0.2), rgba(239, 68, 68, 0.1))"; } else { resultText = "🎉 Player 2 Wins!"; celebrationText = "🎉 Congratulations Player 2! 🎉"; payoutText = playerRole === "guest" ? `You win ${fmt(payouts.winnerPayout)}!` : `Player 2 wins ${fmt(payouts.winnerPayout)}!`; $("#winnerCelebration").style.background = "linear-gradient(145deg, rgba(34, 197, 94, 0.2), rgba(34, 197, 94, 0.1))"; } $("#gameResult").textContent = resultText; $("#celebrationText").textContent = celebrationText; $("#payoutAmount").textContent = payoutText; $("#totalWagered").textContent = fmt(payouts.gross); $("#taxDeducted").textContent = `-${fmt(payouts.tax)}`; $("#netPool").textContent = fmt(payouts.net); $("#winnerAmount").textContent = fmt(payouts.winnerPayout); $("#houseAmount").textContent = fmt(payouts.housePayout); if (winner === "Draw") { $("#winnerLabel").textContent = "No Winner:"; $("#loserRow").style.display = "none"; } else { $("#winnerLabel").textContent = `${payouts.winnerText} (75%):`; $("#loserRow").style.display = "flex"; } resultsPanel.style.display = "block"; setTimeout(() => { resultsPanel.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }, 100); } function startNewGame() { $("#resultsPanel").style.display = "none"; $("#wager1").value = ""; $("#mode").value = "single"; // Reset all UI elements $("#online-controls").style.display = "none"; $("#single-controls").style.display = "block"; $("#gameRoomInfo").style.display = "none"; $("#systemMatchInfo").style.display = "none"; $("#link-display").style.display = "none"; $("#generateLinkBtn").style.display = "block"; $("#joinRoomControls").style.display = "none"; $("#toggleJoinBtn").style.display = "none"; // Clean up if(expiryTimer) clearInterval(expiryTimer); gameRoom = null; playerRole = null; wagers = {p1: 0, p2: 0}; initBoard(); gameActive = false; turn = 0; mode = "single"; renderBoard(); updatePayoutPanel(null); setMsg("Ready for a new game! Set your wager and start playing.", false); updateUrl(); window.scrollTo({ top: 0, behavior: 'smooth' }); } async function onPitClick(i,owner){ if(!gameActive||turn!==owner||board[i]===0)return; let extra = await makeMove(i,owner); renderBoard(); if(isGameOver())return endGame(); if(!extra){ turn=1-turn; renderBoard(); if(mode==="single"&&turn===1)setTimeout(systemTurn,800); } } async function systemTurn(){ if(!gameActive)return; let m=systemChooseMove(); if(m===null)return endGame(); let extra = await makeMove(m,1); renderBoard(); if(isGameOver())return endGame(); if(!extra){ turn=0; renderBoard(); }else { setTimeout(systemTurn,800); } } function setMsg(t,err){ $("#message").textContent=t; $("#message").style.color=err?"#ef4444":"#22c55e"; } // Event Listeners $("#mode").onchange = function(e) { const isOnline = e.target.value === "online"; $("#online-controls").style.display = isOnline ? "block" : "none"; $("#single-controls").style.display = isOnline ? "none" : "block"; $("#systemMatchInfo").style.display = "none"; if (isOnline) { $("#toggleJoinBtn").style.display = "block"; } else { $("#toggleJoinBtn").style.display = "none"; $("#joinRoomControls").style.display = "none"; } }; $("#startBtn").onclick = startSinglePlayerGame; $("#generateLinkBtn").onclick = generateOnlineGame; $("#cancelGameBtn").onclick = function() { if ($("#cancelGameBtn").textContent.includes("Create New")) { // Reset for new game cancelOnlineGame(); setMsg("Ready to create a new game!", false); } else { cancelOnlineGame(); } }; $("#copyLinkBtn").onclick = function() { const shareLink = $("#shareLink"); shareLink.select(); shareLink.setSelectionRange(0, 99999); try { document.execCommand('copy'); $("#copyLinkBtn").textContent = "✅ Copied!"; setTimeout(() => { $("#copyLinkBtn").textContent = "📋 Copy"; }, 2000); } catch (err) { setMsg("Failed to copy link", true); } }; $("#toggleJoinBtn").onclick = function() { const joinControls = $("#joinRoomControls"); if (joinControls.style.display === "none" || !joinControls.style.display) { joinControls.style.display = "grid"; $("#toggleJoinBtn").textContent = "❌ Cancel Join"; $("#generateLinkBtn").style.display = "none"; } else { joinControls.style.display = "none"; $("#toggleJoinBtn").textContent = "🔗 Have a Room ID?"; $("#generateLinkBtn").style.display = "block"; } }; $("#joinRoomBtn").onclick = function() { const roomId = $("#roomIdInput").value.trim().toUpperCase(); const wager = +$("#wager1").value; if (!roomId) { setMsg("Enter a room ID", true); return; } if (!wager || wager < 100) { setMsg("Enter a valid wager amount", true); return; } setMsg("🔍 Looking for game room...", false); setTimeout(() => { joinOnlineGame(roomId, wager); }, 1000); }; $("#roomIdInput").oninput = function(e) { e.target.value = e.target.value.toUpperCase(); }; $("#resetBtn").onclick = function() { if (gameActive) { if (!confirm("Are you sure you want to reset the active game?")) { return; } } // Clean up any active online game if (gameRoom && playerRole === "host" && gameRoom.status === "waiting") { cancelGameRoom(gameRoom.id); } if (expiryTimer) clearInterval(expiryTimer); // Reset all state wagers = {p1: 0, p2: 0}; gameRoom = null; playerRole = null; initBoard(); gameActive = false; turn = 0; mode = "single"; // Reset UI $("#mode").value = "single"; $("#wager1").value = ""; $("#online-controls").style.display = "none"; $("#single-controls").style.display = "block"; $("#gameRoomInfo").style.display = "none"; $("#systemMatchInfo").style.display = "none"; $("#resultsPanel").style.display = "none"; $("#link-display").style.display = "none"; $("#generateLinkBtn").style.display = "block"; $("#joinRoomControls").style.display = "none"; $("#toggleJoinBtn").style.display = "none"; $("#roomIdInput").value = ""; renderBoard(); updatePayoutPanel(null); setMsg("Game reset. Ready to play!", false); updateUrl(); }; // Initialize on page load window.onload = function() { try { // Check if there's a room ID in URL or session storage let roomId = getUrlParameter('room'); // Fallback to session storage for iframe environments if (!roomId) { try { roomId = sessionStorage.getItem('currentRoomId'); } catch (e) { console.log('Session storage not available'); } } if (roomId) { // Auto-switch to online mode and show join controls $("#mode").value = "online"; $("#online-controls").style.display = "block"; $("#single-controls").style.display = "none"; $("#toggleJoinBtn").style.display = "block"; $("#roomIdInput").value = roomId; $("#joinRoomControls").style.display = "grid"; $("#generateLinkBtn").style.display = "none"; $("#toggleJoinBtn").textContent = "❌ Cancel Join"; setMsg(`🔗 Room ${roomId} found! Enter your wager and click Join.`, false); } else { initBoard(); renderBoard(); setMsg("Ready to play! Set your wager and start the game.", false); } } catch (e) { console.log('Initialization error handled:', e); // Default initialization initBoard(); renderBoard(); setMsg("Ready to play! Set your wager and start the game.", false); } updatePayoutPanel(null); }; // Cleanup on page unload window.onbeforeunload = function() { if (expiryTimer) clearInterval(expiryTimer); // Clean up any waiting rooms if (gameRoom && playerRole === "host" && gameRoom.status === "waiting") { cancelGameRoom(gameRoom.id); } };