Spaces:
Sleeping
Sleeping
import streamlit as st | |
import streamlit.components.v1 as components | |
# Configure the Streamlit page | |
st.set_page_config( | |
page_title="Slot Machine Game", | |
page_icon="π°", | |
layout="wide", | |
initial_sidebar_state="collapsed" | |
) | |
# Custom CSS to modify Streamlit's default styling | |
st.markdown(""" | |
<style> | |
.main > div { | |
padding-top: 1rem; | |
} | |
#root > div:nth-child(1) > div > div > div > div > section > div { | |
padding-top: 0rem; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# Title | |
st.title("π° Slot Machine") | |
# HTML/JavaScript slot machine game | |
slot_machine_html = """ | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>40-Card Slot Machine</title> | |
<style> | |
body { margin: 0; background: #1a1a1a; color: #fff; font-family: Arial, sans-serif; } | |
.game-container { | |
width: 1024px; | |
height: 768px; | |
margin: 0 auto; | |
position: relative; | |
background: #2a2a2a; | |
padding: 20px; | |
border-radius: 10px; | |
border: 2px solid gold; | |
box-sizing: border-box; | |
} | |
.grid-container { | |
display: grid; | |
grid-template-columns: repeat(5, 1fr); | |
gap: 5px; | |
margin: 20px 0; | |
height: calc(100% - 120px); | |
} | |
.reel { | |
aspect-ratio: 1; | |
background: #333; | |
border: 2px solid gold; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-size: 32px; | |
position: relative; | |
transition: transform 0.3s; | |
} | |
.controls { | |
text-align: center; | |
margin-top: 20px; | |
position: absolute; | |
bottom: 20px; | |
width: calc(100% - 40px); | |
} | |
.button { | |
background: linear-gradient(45deg, #FFD700, #FFA500); | |
color: #000; | |
padding: 15px 30px; | |
border: none; | |
border-radius: 25px; | |
cursor: pointer; | |
font-size: 18px; | |
font-weight: bold; | |
transition: all 0.3s ease; | |
} | |
.button:hover { transform: scale(1.1); } | |
.button:disabled { | |
background: #666; | |
cursor: not-allowed; | |
} | |
#balance, #timer { | |
position: absolute; | |
top: 10px; | |
font-size: 24px; | |
background: #FFD700; | |
color: #000; | |
padding: 10px; | |
border-radius: 5px; | |
z-index: 10; | |
} | |
#balance { left: 10px; } | |
#timer { right: 10px; } | |
@keyframes spin { | |
0% { transform: rotateY(0deg); } | |
100% { transform: rotateY(360deg); } | |
} | |
.spinning { | |
animation: spin 0.5s linear infinite; | |
} | |
.win-line { | |
position: absolute; | |
background: rgba(255, 215, 0, 0.5); | |
z-index: 1; | |
pointer-events: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="game-container"> | |
<div id="balance">$100.00</div> | |
<div id="timer">10</div> | |
<div class="grid-container"> | |
<!-- 40 reels will be created by JavaScript --> | |
</div> | |
<div class="controls"> | |
<button class="button" onclick="spin()">SPIN ($1)</button> | |
</div> | |
</div> | |
<script> | |
// Previous JavaScript code remains exactly the same | |
let balance = 100; | |
let timer = 10; | |
let timerInterval; | |
let spinning = false; | |
let spinTimeouts = []; | |
const symbols = ['π°', 'π', '7οΈβ£', 'π²', 'π', 'π', 'π', 'π']; | |
let currentState = Array(40).fill(''); | |
const ROWS = 8; | |
const COLS = 5; | |
// Initialize grid | |
function initializeGrid() { | |
const grid = document.querySelector('.grid-container'); | |
grid.innerHTML = ''; | |
for (let i = 0; i < ROWS * COLS; i++) { | |
const reel = document.createElement('div'); | |
reel.className = 'reel'; | |
reel.id = `reel-${i}`; | |
reel.textContent = symbols[Math.floor(Math.random() * symbols.length)]; | |
grid.appendChild(reel); | |
} | |
} | |
function updateBalance(amount) { | |
balance += amount; | |
document.getElementById('balance').textContent = `$${balance.toFixed(2)}`; | |
} | |
function spin() { | |
if (spinning || balance < 1) return; | |
updateBalance(-1); | |
spinning = true; | |
resetTimer(); | |
document.querySelectorAll('.win-line').forEach(line => line.remove()); | |
for (let i = 0; i < ROWS * COLS; i++) { | |
const reel = document.getElementById(`reel-${i}`); | |
reel.classList.add('spinning'); | |
const delay = 2000 + Math.random() * 2000; | |
spinTimeouts.push(setTimeout(() => stopReel(i), delay)); | |
} | |
} | |
function stopReel(index) { | |
const reel = document.getElementById(`reel-${index}`); | |
const symbol = symbols[Math.floor(Math.random() * symbols.length)]; | |
reel.textContent = symbol; | |
reel.classList.remove('spinning'); | |
currentState[index] = symbol; | |
const stillSpinning = document.querySelectorAll('.spinning').length; | |
if (stillSpinning === 0) { | |
spinning = false; | |
checkWins(); | |
} | |
} | |
function checkWins() { | |
let winningLines = []; | |
for (let row = 0; row < ROWS; row++) { | |
let startIdx = row * COLS; | |
let currentSymbol = currentState[startIdx]; | |
let count = 1; | |
for (let col = 1; col < COLS; col++) { | |
if (currentState[startIdx + col] === currentSymbol) { | |
count++; | |
} else { | |
if (count >= 3) { | |
winningLines.push({ | |
start: startIdx + col - count, | |
count: count, | |
direction: 'horizontal', | |
row: row | |
}); | |
} | |
currentSymbol = currentState[startIdx + col]; | |
count = 1; | |
} | |
} | |
if (count >= 3) { | |
winningLines.push({ | |
start: startIdx + COLS - count, | |
count: count, | |
direction: 'horizontal', | |
row: row | |
}); | |
} | |
} | |
let totalWin = 0; | |
winningLines.forEach(line => { | |
const multiplier = line.count - 2; | |
const baseWin = Math.min(multiplier * 10, 100); | |
totalWin += baseWin; | |
showWinLine(line); | |
}); | |
if (totalWin > 0) { | |
updateBalance(totalWin); | |
setTimeout(() => { | |
document.querySelectorAll('.win-line').forEach(line => line.remove()); | |
}, 3000); | |
} | |
} | |
function showWinLine(line) { | |
const winLine = document.createElement('div'); | |
winLine.className = 'win-line'; | |
const firstReel = document.getElementById(`reel-${line.start}`); | |
const reelWidth = firstReel.offsetWidth; | |
const reelHeight = firstReel.offsetHeight; | |
winLine.style.width = `${reelWidth * line.count}px`; | |
winLine.style.height = '4px'; | |
winLine.style.top = `${(line.row * reelHeight) + (reelHeight / 2)}px`; | |
winLine.style.left = `${(line.start % COLS) * reelWidth}px`; | |
document.querySelector('.grid-container').appendChild(winLine); | |
} | |
function resetTimer() { | |
clearInterval(timerInterval); | |
timer = 10; | |
document.getElementById('timer').textContent = timer; | |
timerInterval = setInterval(() => { | |
timer--; | |
document.getElementById('timer').textContent = timer; | |
if (timer <= 0) { | |
resetGame(); | |
} | |
}, 1000); | |
} | |
function resetGame() { | |
spinning = false; | |
clearInterval(timerInterval); | |
spinTimeouts.forEach(timeout => clearTimeout(timeout)); | |
spinTimeouts = []; | |
document.querySelectorAll('.spinning').forEach(reel => reel.classList.remove('spinning')); | |
document.querySelectorAll('.win-line').forEach(line => line.remove()); | |
resetTimer(); | |
} | |
// Initialize the game | |
initializeGrid(); | |
resetTimer(); | |
</script> | |
</body> | |
</html> | |
""" | |
# Create the Streamlit component | |
components.html( | |
slot_machine_html, | |
height=800, # Slightly taller than game height to account for padding | |
width=1050, # Slightly wider than game width to account for padding | |
) |