let canvas = document.querySelector("canvas")
let c = canvas.getContext('2d')
let dim = 8
let blankPlate = [...Array(dim).keys().map(i => [...Array(dim).keys().map(j=>0)])]
let map = structuredClone(blankPlate)
let mask = structuredClone(blankPlate)
function drawCell(row,col){
if(!mask[row][col]){
c.beginPath()
c.rect(canvas.width/dim*col,canvas.height/dim*row,canvas.width/dim,canvas.height/dim)
c.fillStyle = "gold"
c.fill()
c.beginPath()//left side
c.moveTo(canvas.width/dim*col,canvas.height/dim*row)
c.lineTo(canvas.width/dim*(col+.2),canvas.height/dim*(row+.2))
c.lineTo(canvas.width/dim*(col+.2),canvas.height/dim*(row+.8))
c.lineTo(canvas.width/dim*col,canvas.height/dim*(row+1))
c.fillStyle = "sandybrown"
c.fill()
c.beginPath()//right side
c.moveTo(canvas.width/dim*(col+1),canvas.height/dim*row)
c.lineTo(canvas.width/dim*(col+.8),canvas.height/dim*(row+.2))
c.lineTo(canvas.width/dim*(col+.8),canvas.height/dim*(row+.8))
c.lineTo(canvas.width/dim*(col+1),canvas.height/dim*(row+1))
c.fillStyle = "lemonchiffon"
c.fill()
c.beginPath()//top side
c.moveTo(canvas.width/dim*col,canvas.height/dim*row)
c.lineTo(canvas.width/dim*(col+.2),canvas.height/dim*(row+.2))
c.lineTo(canvas.width/dim*(col+.8),canvas.height/dim*(row+.2))
c.lineTo(canvas.width/dim*(col+1),canvas.height/dim*row)
c.fillStyle = "khaki"
c.fill()
c.beginPath()//bottom side
c.moveTo(canvas.width/dim*col,canvas.height/dim*(row+1))
c.lineTo(canvas.width/dim*(col+.2),canvas.height/dim*(row+.8))
c.lineTo(canvas.width/dim*(col+.8),canvas.height/dim*(row+.8))
c.lineTo(canvas.width/dim*(col+1),canvas.height/dim*(row+1))
c.fillStyle = "chocolate"
c.fill()
}
else{
c.beginPath()
c.fillStyle = map[row][col]=="B" ? "coral" : "sandybrown"
c.fillRect(canvas.width/dim*col,canvas.height/dim*row,canvas.width/dim, canvas.height/dim)
c.beginPath()
c.fillStyle = "#444"
c.font = (200/dim)+"pt Arial"
c.textAlign = "center"
c.fillText(map[row][col],canvas.width/dim*(col+.5),canvas.height/dim*(row+.75))
}
}
function drawGrid(){
for(let x = canvas.width/dim; x < canvas.width; x+= canvas.width/dim){
c.beginPath()
c.moveTo(x,0)
c.lineTo(x,canvas.height)
c.strokeStyle = "gray"
c.stroke()
}
for(let y = canvas.height/dim; y < canvas.height; y+= canvas.height/dim){
c.beginPath()
c.moveTo(0,y)
c.lineTo(canvas.width,y)
c.strokeStyle = "gray"
c.stroke()
}
}
function populateMap(row,col){
mask[row][col] = 1
let count = 0
while(count < Math.floor(dim*dim/5)){
let randRow = Math.floor(Math.random()*dim)
let randCol = Math.floor(Math.random()*dim)
if(Math.abs(row - randRow) > 1 || Math.abs(col - randCol) > 1){
map[randRow][randCol] = "B"
count ++
}
}
map.forEach((row,r)=>{
row.forEach((col,c)=>{
let tally = 0
if(r>0){
if(map[r-1][c] == "B") tally ++
if(c>0){
if(map[r-1][c-1] == "B") tally ++
}
if(c0){
if(map[r][c-1] == "B") tally ++
}
if(c0){
if(map[r+1][c-1] == "B") tally ++
}
if(c 0){
console.log(check1.length)
let [cellrow,cellcol] = check1.shift()
mask[cellrow][cellcol] = 1
if(map[cellrow][cellcol] == 0){
//clear surrrounding squares
//row above
if(cellrow > 0){
if(cellcol > 0){
if(!check2.some(item=>item[0] == cellrow-1 && item[1] == cellcol-1)){
check1.push([cellrow-1,cellcol-1])
check2.push([cellrow-1,cellcol-1])
}
}
if(!check2.some(item=>item[0] == cellrow-1 && item[1] == cellcol)){
check1.push([cellrow-1,cellcol])
check2.push([cellrow-1,cellcol])
}
if(col < dim-1){
if(!check2.some(item=>item[0] == cellrow-1 && item[1] == cellcol+1)){
check1.push([cellrow-1,cellcol+1])
check2.push([cellrow-1,cellcol+1])
}
}
}
//same row
if(cellcol > 0){
if(!check2.some(item=>item[0] == cellrow && item[1] == cellcol-1)){
check1.push([cellrow,cellcol-1])
check2.push([cellrow,cellcol-1])
}
}
if(col < dim-1){
if(!check2.some(item => item[0] == cellrow && item[1] == cellcol+1)){
check1.push([cellrow,cellcol+1])
check2.push([cellrow,cellcol+1])
}
}
//row below
if(cellrow < dim-1){
if(cellcol > 0){
if(!check2.some(item => item[0] == cellrow+1 && item[1] == cellcol-1)){
check1.push([cellrow+1,cellcol-1])
check2.push([cellrow+1,cellcol-1])
}
}
if(!check2.some(item => item[0] == cellrow+1 && item[1] == cellcol)){
check1.push([cellrow+1,cellcol])
check2.push([cellrow+1,cellcol])
}
if(col < dim-1){
if(!check2.some(item => item[0] == cellrow+1 && item[1] == cellcol+1)){
check1.push([cellrow+1,cellcol+1])
check2.push([cellrow+1,cellcol+1])
}
}
}
}
else if(map[cellrow][cellcol] == "B"){
canvas.onclick = null
setTimeout(function(){
for(let row = 0; row < dim; row ++){
for(let col = 0; col < dim; col ++){
mask[row][col] = 1
}
}
drawMap()
drawGrid()
setTimeout(function(){begin("You have lost the game.")},1000)
},1000)
}
else{
}
}
drawMap()
drawGrid()
}
let clickHandler = (e) => {
let mx = e.clientX - canvas.getBoundingClientRect().left
let my = e.clientY - canvas.getBoundingClientRect().top
let mcol = Math.floor(mx/canvas.width*dim)
let mrow = Math.floor(my/canvas.height*dim)
if(populated){
clearSquare(mrow,mcol)
}
else{
populateMap(mrow,mcol)
clearSquare(mrow,mcol)
populated = true
}
}
let populated = false
canvas.onclick = null
function begin(msg){
let message = ""
let defaultMessage = "For an n x n grid, choose an n between 4-20."
if(msg) message += msg + " " + defaultMessage
dim = 0
let tries = 0
while (tries < 3 && Math.abs(12-dim) > 8){
dim = parseInt(prompt(message))
tries++
}
if(Math.abs(12 - dim) > 8) dim = 10
blankPlate = [...Array(dim).keys().map(i => [...Array(dim).keys().map(j=>0)])]
map = structuredClone(blankPlate)
mask = structuredClone(blankPlate)
populated = false
canvas.onclick = clickHandler
drawMap()
drawGrid()
}
begin()