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;
...