// SET MESSAGE (WIN/LOSE) function setMessage(text, status){ messageEl.textContent = text; messageEl.className = status; // 'win', 'lose', atau '' (tie) } // Simple Blackjack implementation const SUITS = ['♠','♥','♦','♣']; const RANKS = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']; // DOM const dealerHandEl = document.getElementById('dealer-hand'); const playerHandEl = document.getElementById('player-hand'); const dealerValueEl = document.getElementById('dealer-value'); const playerValueEl = document.getElementById('player-value'); const balanceEl = document.getElementById('balance'); const betInput = document.getElementById('bet-input'); const betBtn = document.getElementById('bet-btn'); const currentBetEl = document.getElementById('current-bet'); const hitBtn = document.getElementById('hit'); const standBtn = document.getElementById('stand'); const doubleBtn = document.getElementById('double'); const newRoundBtn = document.getElementById('new-round'); const messageEl = document.getElementById('message'); let deck = []; let dealer = []; let player = []; let dealerHidden = true; let balance = 0; // Will be initialized from server let currentBet = 0; let inRound = false; // Initialize balance from global gameBalance (set in html.php) if (typeof gameBalance !== 'undefined') { balance = gameBalance; } else { balance = 1000; // Fallback } function makeDeck(){ deck = []; for(const s of SUITS){ for(const r of RANKS){ deck.push({suit:s,rank:r}); } } } function shuffle(){ for(let i=deck.length-1;i>0;i--){ const j = Math.floor(Math.random()*(i+1)); [deck[i],deck[j]] = [deck[j],deck[i]]; } } function cardValue(card){ const r = card.rank; if(r==='A') return [1,11]; if(['J','Q','K'].includes(r)) return [10]; return [parseInt(r,10)]; } function handValues(hand){ let totals = [0]; for(const c of hand){ const vals = cardValue(c); const newTotals = []; for(const t of totals){ for(const v of vals){ newTotals.push(t+v); } } totals = Array.from(new Set(newTotals)); } const valid = totals.filter(t=>t<=21); if(valid.length) return Math.max(...valid); return Math.min(...totals); } function renderHand(el,hand,hideFirst=false){ el.innerHTML=''; hand.forEach((c,i)=>{ const div = document.createElement('div'); div.className='card'+(c.suit==='♥'||c.suit==='♦'?' red':''); if(hideFirst && i===0){ div.className='card back'; div.textContent='TERSEMBUNYI'; } else { const top = document.createElement('div'); top.textContent = c.rank + ' ' + c.suit; const bot = document.createElement('div'); bot.style.alignSelf='flex-end'; bot.textContent = c.rank + ' ' + c.suit; div.appendChild(top); div.appendChild(bot); } el.appendChild(div); }); } function updateUI(){ renderHand(dealerHandEl,dealer,dealerHidden); renderHand(playerHandEl,player,false); dealerValueEl.textContent = dealerHidden ? '??' : 'Nilai: '+handValues(dealer); playerValueEl.textContent = 'Nilai: '+handValues(player); balanceEl.textContent = balance.toLocaleString('id-ID'); currentBetEl.textContent = currentBet.toLocaleString('id-ID'); } // Function to update balance on server function updateBalanceOnServer() { fetch('html.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'update_balance=' + balance }) .catch(err => console.log('Balance update sent')); } function startRound(){ if(inRound) return; const bet = Number(betInput.value) || 0; if(bet <=0 || bet > balance){ alert(' BANK TIDAK CUKUP! '); return; } currentBet = bet; balance -= bet; inRound=true; dealerHidden=true; setMessage('', ''); // RESET MESSAGE makeDeck(); shuffle(); dealer = [deck.pop(), deck.pop()]; player = [deck.pop(), deck.pop()]; updateUI(); // NATURAL BLACKJACK if(handValues(player)===21){ dealerHidden=false; updateUI(); const dealerVal = handValues(dealer); if(dealerVal===21){ balance += currentBet; setMessage('Tie (seri).', ''); } else { const payout = Math.floor(currentBet * 2.5); balance += payout; setMessage('Blackjack! You Win!', 'win'); } inRound=false; currentBet=0; updateUI(); updateBalanceOnServer(); } } function playerHit(){ if(!inRound) return; player.push(deck.pop()); updateUI(); if(handValues(player) > 21){ dealerHidden=false; setMessage('Bust! You Lose!', 'lose'); inRound=false; currentBet=0; updateUI(); updateBalanceOnServer(); } } function playerStand(){ if(!inRound) return; dealerHidden=false; while(handValues(dealer)<17){ dealer.push(deck.pop()); } const pv = handValues(player); const dv = handValues(dealer); if(dv>21 || pv>dv){ balance += currentBet*2; setMessage('You Win!', 'win'); } else if(pv===dv){ balance += currentBet; setMessage('Tie (seri).', ''); } else { setMessage('You Lose!', 'lose'); } inRound=false; currentBet=0; updateUI(); updateBalanceOnServer(); } function playerDouble(){ if(!inRound) return; if(balance < currentBet){ alert('Bank tidak cukup untuk double.'); return; } balance -= currentBet; currentBet *= 2; player.push(deck.pop()); updateUI(); if(handValues(player)>21){ dealerHidden=false; setMessage('Bust! You Lose!', 'lose'); inRound=false; currentBet=0; updateUI(); updateBalanceOnServer(); return; } playerStand(); } // EVENTS betBtn.addEventListener('click', startRound); hitBtn.addEventListener('click', playerHit); standBtn.addEventListener('click', playerStand); doubleBtn.addEventListener('click', playerDouble); newRoundBtn.addEventListener('click', ()=>{ if(inRound && !confirm('Masih dalam ronde. Reset?')) return; balance = 1000; currentBet=0; inRound=false; dealer=[]; player=[]; deck=[]; dealerHidden=true; setMessage('Bank di-reset.', ''); updateUI(); }); // KEYBOARD window.addEventListener('keydown', e=>{ if(e.key==='h') playerHit(); if(e.key==='s') playerStand(); if(e.key==='d') playerDouble(); if(e.key==='Enter') startRound(); }); updateUI(); // TOP UP FEATURE // Tambahkan variabel global untuk top up let topUpAmount = 0; let topUpHistory = []; // DOM elements untuk top up const topUpBtn = document.getElementById('top-up-btn'); const topUpModal = document.getElementById('top-up-modal'); const topUpClose = document.getElementById('top-up-close'); const topUpInput = document.getElementById('top-up-input'); const topUpConfirm = document.getElementById('top-up-confirm'); const topUpHistoryEl = document.getElementById('top-up-history'); const topUpBalanceEl = document.getElementById('top-up-balance'); // Fungsi untuk menampilkan modal top up function showTopUpModal() { topUpModal.style.display = 'block'; topUpInput.value = ''; updateTopUpHistory(); } // Fungsi untuk menyembunyikan modal top up function hideTopUpModal() { topUpModal.style.display = 'none'; } // Fungsi untuk memproses top up function processTopUp() { const amount = Number(topUpInput.value) || 0; if (amount <= 0) { alert('Masukkan jumlah top up yang valid!'); return; } if (amount > 1000000) { alert('Maksimal top up adalah 1.000.000!'); return; } // Simulasi proses top up (dalam implementasi nyata, ini akan terhubung ke payment gateway) balance += amount; topUpAmount += amount; // Tambahkan ke riwayat top up topUpHistory.push({ amount: amount, date: new Date().toLocaleString('id-ID'), balanceAfter: balance }); // Update UI updateUI(); updateTopUpHistory(); // Tampilkan pesan sukses setMessage(`Top up berhasil! +${amount.toLocaleString('id-ID')}`, 'win'); // Sembunyikan modal hideTopUpModal(); } // Fungsi untuk memperbarui riwayat top up function updateTopUpHistory() { if (!topUpHistoryEl) return; topUpHistoryEl.innerHTML = ''; if (topUpHistory.length === 0) { topUpHistoryEl.innerHTML = '
Belum ada riwayat top up
'; return; } // Tampilkan maksimal 5 riwayat terbaru const recentHistory = topUpHistory.slice(-5).reverse(); recentHistory.forEach(record => { const historyItem = document.createElement('div'); historyItem.className = 'history-item'; historyItem.innerHTML = `