```javascript
class SlotMachine extends HTMLElement {
constructor() {
super();
this.balance = 1000;
this.bet = 10;
this.isSpinning = false;
this.symbols = ['🍒', '🍋', '🍊', '🍉', '⭐', '💎', '7️⃣'];
this.symbolValues = {
'🍒': 2,
'🍋': 3,
'🍊': 4,
'🍉': 5,
'⭐': 10,
'💎': 20,
'7️⃣': 50
};
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.render();
this.setupEventListeners();
this.updateDisplay();
}
render() {
this.shadowRoot.innerHTML = `
💰 Balance: $1000
Payouts (x bet)
🍒 3x2x
🍋 3x3x
🍊 3x4x
🍉 3x5x
⭐ 3x10x
💎 3x20x
7️⃣ 3x50x JACKPOT!
`;
}
setupEventListeners() {
this.shadowRoot.getElementById('spinBtn').addEventListener('click', () => this.spin());
this.shadowRoot.getElementById('increaseBet').addEventListener('click', () => this.changeBet(5));
this.shadowRoot.getElementById('decreaseBet').addEventListener('click', () => this.changeBet(-5));
}
changeBet(amount) {
if (this.isSpinning) return;
this.bet = Math.max(5, Math.min(100, this.bet + amount));
this.updateDisplay();
}
async spin() {
if (this.isSpinning || this.balance < this.bet) {
if (this.balance < this.bet) {
this.showMessage('❌ Insufficient balance!', 'lose');
}
return;
}
this.isSpinning = true;
this.balance -= this.bet;
this.updateDisplay();
const reel1 = this.shadowRoot.getElementById('reel1');
const reel2 = this.shadowRoot.getElementById('reel2');
const reel3 = this.shadowRoot.getElementById('reel3');
const spinBtn = this.shadowRoot.getElementById('spinBtn');
spinBtn.textContent = 'SPINNING...';
spinBtn.disabled = true;
reel1.classList.add('spinning');
reel2.classList.add('spinning');
reel3.classList.add('spinning');
// Simulate spinning
const spinDuration = 2000;
const spinInterval = 100;
const startTime = Date.now();
const spinReels = setInterval(() => {
reel1.textContent = this.symbols[Math.floor(Math.random() * this.symbols.length)];
reel2.textContent = this.symbols[Math.floor(Math.random() * this.symbols.length)];
reel3.textContent = this.symbols[Math.floor(Math.random() * this.symbols.length)];
if (Date.now() - startTime > spinDuration) {
clearInterval(spinReels);
this.stopSpin();
}
}, spinInterval);
}
stopSpin() {
const reel1 = this.shadowRoot.getElementById('reel1');
const reel2 = this.shadowRoot.getElementById('reel2');
const reel3 = this.shadowRoot.getElementById('reel3');
const spinBtn = this.shadowRoot.getElementById('spinBtn');
reel1.classList.remove('spinning');
reel2.classList.remove('spinning');
reel3.classList.remove('spinning');
// Final results
const result1 = this.symbols[Math.floor(Math.random() * this.symbols.length)];
const result2 = this.symbols[Math.floor(Math.random() * this.symbols.length)];
const result3 = this.symbols[Math.floor(Math.random() * this.symbols.length)];
reel1.textContent = result1;
reel2.textContent = result2;
reel3.textContent = result3;
this.calculateWinnings(result1, result2, result3);
spinBtn.textContent = 'SPIN';
spinBtn.disabled = false;
this.isSpinning = false;
}
calculateWinnings(r1, r2, r3) {
if (r1 === r2 && r2 === r3) {
const multiplier = this.symbolValues[r1];
const winnings = this.bet * multiplier;
this.balance += winnings;
this.showMessage(`🎉 JACKPOT! You won $${winnings}!`, 'win');
// Generate redemption code for big wins
if (winnings >= 100) {
setTimeout(() => {
alert(`🏆 CONGRATULATIONS! You've earned a redemption code: WIN-${Math.random().toString(36).substr(2, 9).toUpperCase()}`);
}, 1000);
}
} else if (r1 === r2 || r2 === r3 || r1 === r3) {
const smallWin = this.bet * 0.5;
this.balance += smallWin;
this.showMessage(`💰 Small win! $${smallWin}`, 'win');
} else {
this.showMessage('😔 Try again!', 'lose');
}
this.updateDisplay();
}
showMessage(text, type) {
const messageEl = this.shadowRoot.getElementById('message');
messageEl.textContent = text;
messageEl.className = `message ${type}`;
}
updateDisplay() {
this.shadowRoot.getElementById('balance').textContent = this.balance;
this.shadowRoot.getElementById('betAmount').textContent = this.bet;