(Conway's) Game of Life

View Project

HTML

            
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Life</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js" defer></script>
</head>
<body>
    <canvas id="step0" width=400 height=400></canvas>
    <canvas id="step1" width=400 height=400></canvas>
    <canvas id="step2" width=400 height=400></canvas>
</body>
</html>
            
        

CSS

            
body{
    margin: 0;
}
canvas{
    border: 1px solid black;
}
            
        

JS

            
let step0Canvas = document.querySelector("#step0")
let step1Canvas = document.querySelector("#step1")
let step2Canvas = document.querySelector("#step2")
let s0 = step0Canvas.getContext("2d")
let s1 = step1Canvas.getContext("2d")
let s2 = step2Canvas.getContext("2d")


function drawGrid(ctx){
    ctx.beginPath()
    ctx.strokeStyle = "black"
    for(let i = 0; i < 10; i ++){
        ctx.moveTo(0,step0Canvas.height/10*i)
        ctx.lineTo(step0Canvas.width,step0Canvas.height/10*i)
    }
    for(let j = 0; j < 10; j ++){
        ctx.moveTo(step0Canvas.width/10*j,0)
        ctx.lineTo(step0Canvas.width/10*j,step0Canvas.height)
    }
    ctx.stroke()
}


let data = [...Array(10).keys()].map(i=>[...Array(10).fill(0)])
console.log(data)

step0Canvas.onmousemove = (e) => {
    s0.clearRect(0,0,step0Canvas.width,step0Canvas.height)
    let mx = e.clientX - step0Canvas.getBoundingClientRect().left
    let my = e.clientY - step0Canvas.getBoundingClientRect().top
    let sr = Math.floor(my/step0Canvas.height*10)
    let sc = Math.floor(mx/step0Canvas.width*10)
    drawData(data, s0)
    highlight(sr,sc)
    drawGrid(s0)
}

function drawData(dat, ctx){
    for(let r = 0; r<10; r ++){
        for (let c = 0; c < 10; c++) {
            if(dat[r][c]) {
                ctx.beginPath()
                ctx.rect(c*step0Canvas.width/10, r*step0Canvas.height/10, step0Canvas.width/10,step0Canvas.height/10)
                ctx.fillStyle = "black"
                ctx.fill()
            }
        }
    }
}

function highlight(r,c){
    s0.beginPath()
    s0.rect(c*step0Canvas.width/10, r*step0Canvas.height/10, step0Canvas.width/10,step0Canvas.height/10)
    s0.fillStyle = "yellow"
    s0.fill()
}

drawGrid(s0)
drawGrid(s1)
drawGrid(s2)


function muteData(r,c){
    if(data[r][c]) data[r][c] = 0
    else data[r][c] = 1
}

step0Canvas.onclick = (e) => {
    s0.clearRect(0,0,step0Canvas.width,step0Canvas.height)
    let mx = e.clientX - step0Canvas.getBoundingClientRect().left
    let my = e.clientY - step0Canvas.getBoundingClientRect().top
    let sr = Math.floor(my/step0Canvas.height*10)
    let sc = Math.floor(mx/step0Canvas.width*10)
    muteData(sr,sc)
    drawData(data, s0)
    highlight(sr,sc)
    drawGrid(s0)
    let temp = [...Array(10).keys()].map(i=>[...Array(10).fill(0)])
    for(let r =0; r<10; r++){
        for(let c =0; c<10; c++){
            if(data[r][c]){
                if(r>0) {
                    if(c>0) temp[r-1][c-1] += 1
                    if(c<9) temp[r-1][c+1] += 1
                    temp[r-1][c] += 1
                }
                if(r<9) {
                    if(c>0) temp[r+1][c-1] += 1
                    if(c<9) temp[r+1][c+1] += 1
                    temp[r+1][c] += 1
                }
                if(c>0) temp[r][c-1] += 1
                if(c<9) temp[r][c+1] += 1
            }
        }
    }
    let newData = [...Array(10).keys()].map(i=>[...Array(10)].map(j=>0))
    for(let r =0; r<10; r++){
        for(let c =0; c<10; c++){
            if(data[r][c]){
                if(temp[r][c]<2) newData[r][c] = 0
                else if (temp[r][c] > 3) newData[r][c] = 0
                else newData[r][c] = 1
            }
            else{
                if (temp[r][c] == 3) newData[r][c] = 1
                else newData[r][c] = 0
            }
        }
    }
    s1.clearRect(0,0,step1Canvas.width,step1Canvas.height)
    drawData(newData, s1)
    drawGrid(s1)
    temp = [...Array(10).keys()].map(i=>[...Array(10).fill(0)])
    for(let r =0; r<10; r++){
        for(let c =0; c<10; c++){
            if(newData[r][c]){
                if(r>0) {
                    if(c>0) temp[r-1][c-1] += 1
                    if(c<9) temp[r-1][c+1] += 1
                    temp[r-1][c] += 1
                }
                if(r<9) {
                    if(c>0) temp[r+1][c-1] += 1
                    if(c<9) temp[r+1][c+1] += 1
                    temp[r+1][c] += 1
                }
                if(c>0) temp[r][c-1] += 1
                if(c<9) temp[r][c+1] += 1
            }
        }
    }
    let newerData = [...Array(10).keys()].map(i=>[...Array(10)].map(j=>0))
    for(let r =0; r<10; r++){
        for(let c =0; c<10; c++){
            if(newData[r][c]){
                if(temp[r][c]<2) newerData[r][c] = 0
                else if (temp[r][c] > 3) newerData[r][c] = 0
                else newerData[r][c] = 1
            }
            else{
                if (temp[r][c] == 3) newerData[r][c] = 1
                else newerData[r][c] = 0
            }
        }
    }
    s2.clearRect(0,0,step2Canvas.width,step2Canvas.height)
    drawData(newerData, s2)
    drawGrid(s2)
}