JSFiddle - React, Tailwind, and code Playground
HTML
<canvas width="1000" height="600"></canvas>
CSS
canvas{background-color:#eeeeee;}
JavaScript
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
const bish = { x: 4, y: 5 }
const w = canvas.width
const h = canvas.height
const nbLines = 20
const dh = h / nbLines
const nbColumns = 40
const dw = w / nbColumns
const obstacles = (function generateObstacles (percent) {
const n = Math.floor(nbLines * nbColumns * percent)
return Array(n).fill(0).map(x => {
return {
x: Math.floor(Math.random() * nbColumns),
y: Math.floor(Math.random() * nbLines)
}
})
})(0.2)
function restorePlot () {
ctx.clearRect(0, 0, w, h)
for (let i = 0; i <= nbLines; ++i) {
ctx.beginPath()
ctx.moveTo(0, i * dh)
ctx.lineTo(w - 1, i * dh)
ctx.stroke()
ctx.closePath()
}
for (let j = 0; j <= nbColumns; ++j) {
ctx.beginPath()
ctx.moveTo(j * dw, 0)
ctx.lineTo(j * dw, h - 1)
ctx.stroke()
ctx.closePath()
}
ctx.fillStyle = 'red'
obstacles.forEach(fillCell)
}
function getBishMoves ({ x, y }, obstacles) {
let br = Math.min(nbColumns - 1 + x, nbLines - 1 + y)
let tl = Math.min(x, y)
let tr = Math.min(nbColumns - 1 + x, y)
let bl = Math.min(x, nbLines - 1 + y)
obstacles.forEach(o => {
const relx = o.x - x
const rely = o.y - y
if (relx === rely) { // on x==y
if (relx > 0) {
br = Math.min(br, relx - 1)
} else {
tl = Math.min(tl, -relx - 1)
}
} else if (relx === -rely) {
if (relx > 0) {
tr = Math.min(tr, relx - 1)
} else {
bl = Math.min(bl, -relx - 1)
}
}
})
return { tl, br, tr, bl }
}
function plotBish (bish) {
ctx.fillStyle = 'black'
fillCell(bish)
}
function fillCell ({ x, y }) {
ctx.fillRect(x * dw, y * dh, dw, dh)
}
function plotBishMoves ({ x, y }, v) {
const { tl, br, tr, bl } = v
ctx.fillStyle = 'green'
for (let i = 1; i <= br; ++i) {
fillCell({ x: x + i, y: y + i })
}
for (let i = 1; i <= tl; ++i) {
fillCell({ x: x - i, y: y - i })
}
for (let i = 1; i <= tr;...