@logic-pad/core
Version:
138 lines (137 loc) • 4.62 kB
JavaScript
import { ConfigType } from '../config.js';
import GridData from '../grid.js';
import { array } from '../dataHelper.js';
import { Color, State } from '../primitives.js';
import Symbol from './symbol.js';
class LetterSymbol extends Symbol {
/**
* **Letters must be sorted into one type per area**
*
* @param x - The x-coordinate of the symbol.
* @param y - The y-coordinate of the symbol.
* @param letter - The letter of the symbol.
*/
constructor(x, y, letter) {
super(x, y);
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: x
});
Object.defineProperty(this, "y", {
enumerable: true,
configurable: true,
writable: true,
value: y
});
Object.defineProperty(this, "letter", {
enumerable: true,
configurable: true,
writable: true,
value: letter
});
this.letter = letter;
}
get id() {
return `letter`;
}
get explanation() {
return '*Letters* must be sorted into one type per area';
}
get configs() {
return LetterSymbol.CONFIGS;
}
createExampleGrid() {
return LetterSymbol.EXAMPLE_GRID;
}
validateSymbol(grid) {
const thisX = Math.floor(this.x);
const thisY = Math.floor(this.y);
let complete = true;
const visited = array(grid.width, grid.height, () => false);
const connected = array(grid.width, grid.height, () => false);
const color = grid.getTile(thisX, thisY).color;
if (color !== Color.Gray) {
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === Color.Gray || tile.color === color, (tile, x, y) => {
visited[y][x] = true;
if (tile.color === Color.Gray)
complete = false;
});
grid.iterateArea({ x: thisX, y: thisY }, tile => tile.color === color, (_, x, y) => {
connected[y][x] = true;
});
}
else {
complete = false;
}
for (const symbol of grid.symbols.get(this.id) ?? []) {
if (symbol !== this && symbol instanceof LetterSymbol) {
const symbolX = Math.floor(symbol.x);
const symbolY = Math.floor(symbol.y);
if (symbol.letter === this.letter) {
const theirColor = grid.getTile(symbolX, symbolY).color;
if ((color !== Color.Gray && !visited[symbolY][symbolX]) ||
(color !== Color.Gray &&
theirColor !== Color.Gray &&
theirColor !== color)) {
return State.Error;
}
}
else if (color !== Color.Gray && connected[symbolY][symbolX]) {
return State.Error;
}
}
}
return complete ? State.Satisfied : State.Incomplete;
}
copyWith({ x, y, letter, }) {
return new LetterSymbol(x ?? this.x, y ?? this.y, letter ?? this.letter);
}
withLetter(letter) {
return this.copyWith({ letter });
}
}
Object.defineProperty(LetterSymbol, "CONFIGS", {
enumerable: true,
configurable: true,
writable: true,
value: Object.freeze([
{
type: ConfigType.Number,
default: 0,
field: 'x',
description: 'X',
configurable: false,
},
{
type: ConfigType.Number,
default: 0,
field: 'y',
description: 'Y',
configurable: false,
},
{
type: ConfigType.String,
default: 'A',
field: 'letter',
description: 'Letter',
configurable: true,
},
])
});
Object.defineProperty(LetterSymbol, "EXAMPLE_GRID", {
enumerable: true,
configurable: true,
writable: true,
value: Object.freeze(GridData.create(['bbbww', 'wwbbw', 'wwbbb', 'bwwww'])
.addSymbol(new LetterSymbol(0, 0, 'B'))
.addSymbol(new LetterSymbol(3, 0, 'A'))
.addSymbol(new LetterSymbol(4, 1, 'A'))
.addSymbol(new LetterSymbol(3, 2, 'B'))
.addSymbol(new LetterSymbol(1, 1, 'C'))
.addSymbol(new LetterSymbol(0, 2, 'C'))
.addSymbol(new LetterSymbol(4, 3, 'C')))
});
export default LetterSymbol;
export const instance = new LetterSymbol(0, 0, 'A');