let canvas = document.querySelector("canvas") //grab the canvas element
let ctx = canvas.getContext('2d') //drawing tools for changing the image
//A 2D array representing the state of the game
let data = [
[0,0,0],
[0,0,0],
[0,0,0]
]
//keep track of whose turn it is and how many turns have been made
let player = "X"
let turnCount = 1
function nextTurn(){
turnCount ++ //add one to the turn
if(player == "X") player = "O" //switch players
else player = "X"
document.querySelector(".turn").innerHTML = player //show whose turn it is
}
function drawData(){
for(let row in data){
for(let col in data[row]){
//for each cell, draw the color then draw an "X" or "O"
ctx.beginPath()
ctx.rect(canvas.width/3 * col, canvas.height/3 * row, canvas.width/3, canvas.height/3)
switch(data[row][col]){
case "X":
ctx.fillStyle = "#8af"
ctx.fill()
ctx.fillStyle = "white"
ctx.font = "30pt Arial"
ctx.textAlign = "center"
ctx.fillText(data[row][col], canvas.width/3 * (col)+50, canvas.height/3 * (row) +65)
break;
case "O":
ctx.fillStyle = "#fa8"
ctx.fill()
ctx.fillStyle = "white"
ctx.font = "30pt Arial"
ctx.textAlign = "center"
ctx.fillText(data[row][col], canvas.width/3 * (col)+50, canvas.height/3 * (row) +65)
break;
default:
ctx.fillStyle = "#333"
ctx.fill()
break;
}
}
}
}
drawData() //draw the empty board at the start
//show possible moves on hover
canvas.onmousemove = (e) =>{
//redraw the board
ctx.clearRect(0,0,canvas.width,canvas.height)
drawData()
//find the mouse on the 3x3 grid in terms of row and column
let mx = e.clientX - canvas.getBoundingClientRect().left
let my = e.clientY - canvas.getBoundingClientRect().top
let c = Math.floor(mx / canvas.width *3)
let r = Math.floor(my / canvas.height *3)
//if an empty square, show your symbol
if(data[r][c] == 0){
ctx.fillStyle = "#fff6"
ctx.font = "30pt Arial"
ctx.textAlign = "center"
ctx.fillText(player, canvas.width/3 * (c)+50, canvas.height/3 * (r) +65)
}
}
//handle player choice
canvas.onclick = (e) =>{
//find the mouse on the 3x3 grid in terms of row and column
let mx = e.clientX - canvas.getBoundingClientRect().left
let my = e.clientY - canvas.getBoundingClientRect().top
let c = Math.floor(mx / canvas.width *3)
let r = Math.floor(my / canvas.height *3)
//if an empty square, claim the square
if(data[r][c] == 0){
data[r][c] = player
checkForWin(player) //check if player won
nextTurn() //check to next players turn
}
//redraw the screen to show new state
ctx.clearRect(0,0,canvas.width,canvas.height)
drawData()
}
function checkForWin(turn){
let win = false
//check rows
if(data[0][0] == turn && data[0][1] == turn && data[0][2] == turn) win = true
if(data[1][0] == turn && data[1][1] == turn && data[1][2] == turn) win = true
if(data[2][0] == turn && data[2][1] == turn && data[2][2] == turn) win = true
//check columns
if(data[0][0] == turn && data[1][0] == turn && data[2][0] == turn) win = true
if(data[0][1] == turn && data[1][1] == turn && data[2][1] == turn) win = true
if(data[0][2] == turn && data[1][2] == turn && data[2][2] == turn) win = true
//check diagonals
if(data[0][0] == turn && data[1][1] == turn && data[2][2] == turn) win = true
if(data[0][2] == turn && data[1][1] == turn && data[2][0] == turn) win = true
if(win) {
canvas.onclick = null
canvas.onmousemove = null
setTimeout(function(){alert("player " + turn + " wins!")},500)
}
else{
//check if turns are up without a winner
if(turnCount > 8){
canvas.onclick = null
canvas.onmousemove = null
setTimeout(function(){alert("The game has ended in a tie!")},500)
}
}
}