JSFiddle - React, Tailwind, and code Playground

by jcubed111

HTML

<div class="row" name="0">
    <div class="cell" name="0">P</div>
    <div class="cell" name="1"></div>
    <div class="cell" name="2"></div>
    <div class="cell" name="3"></div>
    <div class="cell" name="4"></div>
</div>
<div class="row" name="1">
    <div class="cell" name="0"></div>
    <div class="cell" name="1"></div>
    <div class="cell" name="2"></div>
    <div class="cell" name="3"></div>
    <div class="cell" name="4"></div>
</div>
<div class="row" name="2">
    <div class="cell" name="0"></div>
    <div class="cell" name="1"></div>
    <div class="cell" name="2"></div>
    <div class="cell" name="3"></div>
    <div class="cell" name="4"></div>
</div>
<div class="row" name="3">
    <div class="cell" name="0"></div>
    <div class="cell" name="1"></div>
    <div class="cell" name="2"></div>
    <div class="cell" name="3"></div>
    <div class="cell" name="4"></div>
</div>
<div class="row" name="4">
    <div class="cell" name="0"></div>
    <div class="cell" name="1"></div>
    <div class="cell" name="2"></div>
    <div class="cell" name="3"></div>
    <div class="cell" name="4"></div>
</div>

CSS

.row{
    display: flex;
}

.cell{
    width: 100px;
    height: 100px;
    border: 1px solid #ccc;
    font-size: 80px;
    text-align: center;
}

.cell.hidden{
    background: #999;
}

.cell.blocker{
    background: #000;
}

JavaScript

// Taken From:
// https://stackoverflow.com/a/9997374/136924
function ccw(A,B,C) {
    return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0]);
}

// Return true if line segments AB and CD intersect
function intersect(A,B,C,D) {
    return ccw(A,C,D) != ccw(B,C,D) && ccw(A,B,C) != ccw(A,B,D);
}

/******************************************/


var filledCells = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],];
function cellFilled(x, y) {
	if(x<0 || y<0 || x>4 || y>4) return true;
    return filledCells[x][y];
}

var playerLocation = [0, 0];

for(let x=0; x<5; x++) {
	for(let y=0; y<5; y++) {
    	document.querySelector(`[name="${y}"] [name="${x}"]`).addEventListener('click', e => {
        	e.target.classList.toggle('blocker');
            filledCells[x][y] ^= 1;
            recalc();
        });
    }
}

function recalc() {
	// visible
    for(let x=0; x<5; x++) {
        for(let y=0; y<5; y++) {
            document.querySelector(`[name="${y}"] [name="${x}"]`).classList.toggle('hidden', !los(playerLocation, [x, y]))
        }
    }
    // move distance
    let unvisited = {};
    let visited = {};
    let current = playerLocation.join(',');
    for(let x=0; x<5; x++) {
        for(let y=0; y<5; y++) {
            unvisited[x+','+y] = [1000, 0]; // dist from player, next diag cost
        }
    }
    
}

const allPoints = [];
for(let x=0; x<5; x++) {
    for(let y=0; y<5; y++) {
        allPoints.push([x, y]);
    }
}

function los([x1, y1], [x2, y2]) {
    if(x1 == x2 && y1 == y2) return true;
    if(filledCells[x1][y1]) return false;
    if(filledCells[x2][y2]) return false;
    
    const blocked = allPoints.some(p => {
    	if(!filledCells[p[0]][p[1]]) return false;
        const d = 0.5;
        const ne = cellFilled(p[0]+1, p[1]+1) ? .501 : .499;
        const sw = cellFilled(p[0]-1, p[1]-1) ? .501 : .499;
        const se = cellFilled(p[0]+1, p[1]-1) ? .501 : .499;
        const nw = cellFilled(p[0]-1, p[1]+1) ? .501 : .499;
       ...