parent
3f88e0d595
commit
ecba4f1cba
@ -0,0 +1,175 @@
|
|||||||
|
'use strict'
|
||||||
|
/* eslint-env browser */
|
||||||
|
/* eslint-disable no-labels */
|
||||||
|
|
||||||
|
const grid = document.body.querySelector('.ttt-grid')
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
x: document.body.querySelector('.ttt-icon-x'),
|
||||||
|
o: document.body.querySelector('.ttt-icon-o'),
|
||||||
|
}
|
||||||
|
|
||||||
|
let paused = true
|
||||||
|
|
||||||
|
const cells = {}
|
||||||
|
const axes = ['y', 'x']
|
||||||
|
const players = ['x', 'o']
|
||||||
|
|
||||||
|
function fill(cell, player) {
|
||||||
|
cell.value = player
|
||||||
|
|
||||||
|
cell.el.appendChild(icons[player].cloneNode(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
for (let y = 1; y <= 3; y++) {
|
||||||
|
for (let x = 1; x <= 3; x++) {
|
||||||
|
const cell = cells[y][x]
|
||||||
|
|
||||||
|
cell.el.classList.remove('ttt-blink')
|
||||||
|
|
||||||
|
cell.el.firstChild && cell.el.removeChild(cell.el.firstChild)
|
||||||
|
|
||||||
|
cell.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { empty } = check()
|
||||||
|
|
||||||
|
play(empty)
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkLine(line, complete) {
|
||||||
|
for (const player of players) {
|
||||||
|
if (line[player].length === 3) {
|
||||||
|
complete.player = player
|
||||||
|
|
||||||
|
complete.cells.push(...line[player])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(dryrun) {
|
||||||
|
const empty = []
|
||||||
|
const complete = {
|
||||||
|
player: null,
|
||||||
|
cells: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const axis of axes) {
|
||||||
|
const diagonal = { o: [], x: [] }
|
||||||
|
|
||||||
|
for (let a = 1; a <= 3; a++) {
|
||||||
|
const y = a
|
||||||
|
const x = axis === 'y' ? y : 4 - y
|
||||||
|
|
||||||
|
const cell = cells[y][x]
|
||||||
|
|
||||||
|
cell.value && diagonal[cell.value].push(cell)
|
||||||
|
|
||||||
|
const straight = { o: [], x: [] }
|
||||||
|
|
||||||
|
for (let b = 1; b <= 3; b++) {
|
||||||
|
const y = axis === 'y' ? a : b
|
||||||
|
const x = axis === 'y' ? b : a
|
||||||
|
|
||||||
|
const cell = cells[y][x]
|
||||||
|
|
||||||
|
cell.value ? straight[cell.value].push(cell) : empty.push(cell)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkLine(straight, complete)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkLine(diagonal, complete)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dryrun) {
|
||||||
|
if (complete.player) {
|
||||||
|
complete.cells.forEach(({ el }) => el.classList.add('ttt-blink'))
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
reset()
|
||||||
|
}, 1200)
|
||||||
|
} else if (!empty.length) {
|
||||||
|
setTimeout(() => {
|
||||||
|
reset()
|
||||||
|
}, 1200)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { winner: complete.player, empty: [...new Set(empty)] }
|
||||||
|
}
|
||||||
|
|
||||||
|
function play(cells) {
|
||||||
|
setTimeout(() => {
|
||||||
|
let found = false
|
||||||
|
|
||||||
|
search: for (const cell of cells) {
|
||||||
|
for (const player of players) {
|
||||||
|
cell.value = player
|
||||||
|
|
||||||
|
const { winner, empty } = check(true)
|
||||||
|
|
||||||
|
if (winner || !empty) {
|
||||||
|
found = true
|
||||||
|
|
||||||
|
fill(cell, 'x')
|
||||||
|
|
||||||
|
break search
|
||||||
|
} else {
|
||||||
|
cell.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
const cell = cells[Math.round(Math.random() * (cells.length - 1))]
|
||||||
|
|
||||||
|
fill(cell, 'x')
|
||||||
|
}
|
||||||
|
|
||||||
|
const { winner, empty } = check()
|
||||||
|
|
||||||
|
if (!winner && empty) {
|
||||||
|
paused = false
|
||||||
|
}
|
||||||
|
}, 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let y = 1; y <= 3; y++) {
|
||||||
|
for (let x = 1; x <= 3; x++) {
|
||||||
|
const el = grid.querySelector(
|
||||||
|
`.ttt-row:nth-child(${y}) .ttt-cell:nth-child(${x})`
|
||||||
|
)
|
||||||
|
|
||||||
|
el.addEventListener('click', () => {
|
||||||
|
if (paused) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const cell = cells[y][x]
|
||||||
|
|
||||||
|
if (!cell.value) {
|
||||||
|
paused = true
|
||||||
|
|
||||||
|
fill(cell, 'o')
|
||||||
|
|
||||||
|
const { winner, empty } = check()
|
||||||
|
|
||||||
|
!winner && play(empty)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
cells[y] = cells[y] || {}
|
||||||
|
|
||||||
|
cells[y][x] = {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
el,
|
||||||
|
value: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset()
|
Reference in new issue