Update 2025-04-17_20:04:08
This commit is contained in:
102
static/app.js
Normal file
102
static/app.js
Normal file
@ -0,0 +1,102 @@
|
||||
// /var/www/minitactix/static/app.js
|
||||
let board = []
|
||||
let playerSymbol = ''
|
||||
let npcSymbol = ''
|
||||
let playerEmoji = ''
|
||||
let npcEmoji = ''
|
||||
let gameOver = false
|
||||
|
||||
const EMOJIS = ['❌', '⭕', '🔴', '🟢', '🟡', '🟣', '⭐', '💠', '🧿', '🧩']
|
||||
|
||||
function startGame(symbol) {
|
||||
playerSymbol = symbol
|
||||
npcSymbol = symbol === 'X' ? 'O' : 'X'
|
||||
|
||||
const shuffled = EMOJIS.sort(() => 0.5 - Math.random())
|
||||
playerEmoji = shuffled[0]
|
||||
npcEmoji = shuffled[1]
|
||||
|
||||
document.getElementById('symbol-chooser').classList.add('hidden')
|
||||
document.getElementById('board').classList.remove('hidden')
|
||||
document.getElementById('restart').classList.remove('hidden')
|
||||
document.getElementById('info').textContent = `You are ${playerEmoji} — NPC is ${npcEmoji}`
|
||||
initBoard()
|
||||
randomNPCMoves(3 + Math.floor(Math.random() * 3))
|
||||
renderBoard()
|
||||
}
|
||||
|
||||
function initBoard() {
|
||||
board = Array(16).fill('')
|
||||
}
|
||||
|
||||
function renderBoard() {
|
||||
const boardDiv = document.getElementById('board')
|
||||
boardDiv.innerHTML = ''
|
||||
board.forEach((val, idx) => {
|
||||
const tile = document.createElement('div')
|
||||
tile.className = 'tile'
|
||||
tile.textContent = val === playerSymbol ? playerEmoji : (val === npcSymbol ? npcEmoji : '')
|
||||
tile.onclick = () => playerMove(idx)
|
||||
if (val !== '' || gameOver) tile.onclick = null
|
||||
boardDiv.appendChild(tile)
|
||||
})
|
||||
}
|
||||
|
||||
function playerMove(index) {
|
||||
if (board[index] !== '' || gameOver) return
|
||||
board[index] = playerSymbol
|
||||
if (checkWin(playerSymbol)) {
|
||||
endGame(`${playerEmoji} wins!`)
|
||||
return
|
||||
}
|
||||
if (board.includes('')) {
|
||||
randomNPCMoves(1)
|
||||
if (checkWin(npcSymbol)) {
|
||||
endGame(`${npcEmoji} wins!`)
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!board.includes('')) endGame("It's a draw!")
|
||||
renderBoard()
|
||||
}
|
||||
|
||||
function randomNPCMoves(count) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
const free = board.map((v, i) => v === '' ? i : null).filter(v => v !== null)
|
||||
if (free.length === 0) return
|
||||
const pick = free[Math.floor(Math.random() * free.length)]
|
||||
board[pick] = npcSymbol
|
||||
}
|
||||
}
|
||||
|
||||
function checkWin(sym) {
|
||||
const lines = [
|
||||
[0,1,2], [1,2,3],
|
||||
[4,5,6], [5,6,7],
|
||||
[8,9,10], [9,10,11],
|
||||
[12,13,14], [13,14,15],
|
||||
[0,4,8], [4,8,12],
|
||||
[1,5,9], [5,9,13],
|
||||
[2,6,10], [6,10,14],
|
||||
[3,7,11], [7,11,15],
|
||||
[0,5,10], [1,6,11],
|
||||
[4,9,14], [5,10,15],
|
||||
[2,5,8], [3,6,9],
|
||||
[6,9,12], [7,10,13]
|
||||
]
|
||||
return lines.some(line => line.every(i => board[i] === sym))
|
||||
}
|
||||
|
||||
function endGame(msg) {
|
||||
document.getElementById('status').textContent = msg
|
||||
gameOver = true
|
||||
renderBoard()
|
||||
}
|
||||
|
||||
// PWA service worker registration
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('service-worker.js')
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user