@logic-pad/core
Version:
78 lines (77 loc) • 3.08 kB
JavaScript
import BTModule, { BTTile, IntArray2D, createOneTileResult, } from '../data.js';
export default class AreaNumberBTModule extends BTModule {
constructor(instr) {
super();
Object.defineProperty(this, "instr", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.instr = instr;
}
checkGlobal(grid) {
const thisX = Math.floor(this.instr.x);
const thisY = Math.floor(this.instr.y);
const tile = grid.getTile(thisX, thisY);
if (tile === BTTile.Empty)
return createOneTileResult(grid, { x: thisX, y: thisY });
const visited = IntArray2D.create(grid.width, grid.height);
const sameTileQueue = [{ x: thisX, y: thisY }];
const usableTileQueue = [];
let sameCellCount = 0;
let usableCellCount = 0;
visited.set(thisX, thisY, 1);
// Count same tile
while (sameTileQueue.length > 0) {
const curPos = sameTileQueue.pop();
sameCellCount += 1;
for (const edge of grid.getEdges(curPos)) {
if (visited.get(edge.x, edge.y))
continue;
const edgeTile = grid.getTile(edge.x, edge.y);
if (edgeTile === BTTile.Empty) {
usableTileQueue.push(edge);
}
else if (edgeTile === tile) {
sameTileQueue.push(edge);
}
visited.set(edge.x, edge.y, 1);
}
}
if (sameCellCount > this.instr.number)
return false;
const ratings = [];
for (const pos of usableTileQueue) {
ratings.push({ pos, score: 1 });
}
// Count usable tile
while (usableTileQueue.length > 0) {
const curPos = usableTileQueue.pop();
usableCellCount += 1;
if (sameCellCount + usableCellCount >= this.instr.number)
return { tilesNeedCheck: null, ratings };
for (const edge of grid.getEdges(curPos)) {
if (visited.get(edge.x, edge.y))
continue;
const edgeTile = grid.getTile(edge.x, edge.y);
if (edgeTile === BTTile.Empty || edgeTile === tile) {
usableTileQueue.push(edge);
visited.set(edge.x, edge.y, 1);
}
}
}
return sameCellCount + usableCellCount >= this.instr.number
? { tilesNeedCheck: null, ratings }
: false;
}
checkLocal(grid, positions) {
// TODO: Also skip checks if color is the same and within the zone but not directly affectin
const thisX = Math.floor(this.instr.x);
const thisY = Math.floor(this.instr.y);
// Skip checks if it is too far to affect the symbol
if (positions.every(pos => Math.abs(pos.x - thisX) + Math.abs(pos.y - thisY) > this.instr.number))
return true;
return this.checkGlobal(grid);
}
}