44 lines
1.1 KiB
JavaScript
44 lines
1.1 KiB
JavaScript
// @ts-check
|
|
|
|
/**
|
|
* Neighbor STRATEGIES — the extraction seam. A game injects the topology it
|
|
* wants; the grid layer never assumes one. Minesweeper uses `eightWay`; a future
|
|
* Sudoku would inject its row/col/box `peers`. Each returns in-bounds [r, c]
|
|
* coordinate pairs.
|
|
*
|
|
* @typedef {{ inBounds: (r: number, c: number) => boolean }} Boundable
|
|
*/
|
|
|
|
/**
|
|
* All 8 surrounding cells (orthogonal + diagonal).
|
|
* @param {Boundable} grid
|
|
* @returns {Array<[number, number]>}
|
|
*/
|
|
export function eightWay(grid, r, c) {
|
|
const out = []
|
|
for (let dr = -1; dr <= 1; dr++) {
|
|
for (let dc = -1; dc <= 1; dc++) {
|
|
if (dr === 0 && dc === 0) continue
|
|
const nr = r + dr
|
|
const nc = c + dc
|
|
if (grid.inBounds(nr, nc)) out.push([nr, nc])
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
/**
|
|
* The 4 orthogonal cells (N/E/S/W).
|
|
* @param {Boundable} grid
|
|
* @returns {Array<[number, number]>}
|
|
*/
|
|
export function orthogonal(grid, r, c) {
|
|
const out = []
|
|
const deltas = [[-1, 0], [1, 0], [0, -1], [0, 1]]
|
|
for (const [dr, dc] of deltas) {
|
|
const nr = r + dr
|
|
const nc = c + dc
|
|
if (grid.inBounds(nr, nc)) out.push([nr, nc])
|
|
}
|
|
return out
|
|
}
|