@logic-pad/core
Version:
272 lines (271 loc) • 10 kB
JavaScript
import { ConfigType } from '../config.js';
import { array } from '../dataHelper.js';
import GridData from '../grid.js';
import { Color, MajorRule, Orientation, State, Wrapping, orientationToggle, } from '../primitives.js';
import LetterSymbol from '../symbols/letterSymbol.js';
import MyopiaSymbol from '../symbols/myopiaSymbol.js';
import Rule from './rule.js';
class WrapAroundRule extends Rule {
/**
* **The left and right edges are connected (in reverse)**
*
* @param horizontal - The horizontal wrapping.
* @param vertical - The vertical wrapping.
*/
constructor(horizontal, vertical) {
super();
Object.defineProperty(this, "horizontal", {
enumerable: true,
configurable: true,
writable: true,
value: horizontal
});
Object.defineProperty(this, "vertical", {
enumerable: true,
configurable: true,
writable: true,
value: vertical
});
this.horizontal = horizontal;
this.vertical = vertical;
}
onGetTile(x, y, grid) {
if (grid.width === 0 || grid.height === 0) {
return { x, y };
}
if (this.horizontal !== Wrapping.None) {
const idx = Math.abs(Math.floor(x / grid.width));
x = ((x % grid.width) + grid.width) % grid.width;
if ((this.horizontal === Wrapping.WrapReverse ||
this.horizontal === Wrapping.ReflectReverse) &&
idx % 2 === 1) {
y = grid.height - 1 - y;
}
if (this.horizontal === Wrapping.ReflectReverse && idx % 2 === 1) {
x = grid.width - 1 - x;
}
}
if (this.vertical !== Wrapping.None) {
const idx = Math.abs(Math.floor(y / grid.height));
y = ((y % grid.height) + grid.height) % grid.height;
if ((this.vertical === Wrapping.WrapReverse ||
this.vertical === Wrapping.ReflectReverse) &&
idx % 2 === 1) {
x = grid.width - 1 - x;
}
if (this.vertical === Wrapping.ReflectReverse && idx % 2 === 1) {
y = grid.height - 1 - y;
}
}
return { x, y };
}
get id() {
return MajorRule.WrapAround;
}
get explanation() {
if (this.horizontal === Wrapping.None && this.vertical === Wrapping.None) {
return `No edges are connected.`;
}
const horizontal = this.horizontal === Wrapping.None
? null
: this.horizontal === Wrapping.Wrap ||
this.horizontal === Wrapping.WrapReverse
? 'connected'
: 'reflective';
const vertical = this.vertical === Wrapping.None
? null
: this.vertical === Wrapping.Wrap ||
this.vertical === Wrapping.WrapReverse
? 'connected'
: 'reflective';
const horizontalReverse = this.horizontal === Wrapping.WrapReverse ||
this.horizontal === Wrapping.ReflectReverse
? ' in reverse'
: '';
const verticalReverse = this.vertical === Wrapping.WrapReverse ||
this.vertical === Wrapping.ReflectReverse
? ' in reverse'
: '';
if (this.horizontal === this.vertical) {
return `All four edges are ${horizontal}${horizontalReverse}.`;
}
if (this.horizontal === Wrapping.None) {
return `The top and bottom edges are ${vertical}${verticalReverse}.`;
}
if (this.vertical === Wrapping.None) {
return `The left and right edges are ${horizontal}${horizontalReverse}.`;
}
if (horizontal === vertical) {
if (horizontalReverse !== '') {
return `All four edges are ${horizontal}, with the left and right edges${horizontalReverse}.`;
}
else {
return `All four edges are ${horizontal}, with the top and bottom edges${verticalReverse}.`;
}
}
return `The left and right edges are ${horizontal}${horizontalReverse}. The top and bottom edges are ${vertical}${verticalReverse}.`;
}
createExampleGrid() {
const horizontal = WrapAroundRule.EXAMPLE_GRID_HORIZONTAL[this.horizontal];
const vertical = WrapAroundRule.EXAMPLE_GRID_VERTICAL[this.vertical];
if (horizontal === WrapAroundRule.EXAMPLE_GRID_NONE) {
return vertical;
}
else if (vertical === WrapAroundRule.EXAMPLE_GRID_NONE) {
return horizontal;
}
else {
const tiles = array(5, 5, (x, y) => {
const hTile = horizontal.getTile(x, y);
const vTile = vertical.getTile(x, y);
return hTile.withColor(hTile.color === Color.Dark || vTile.color === Color.Dark
? Color.Dark
: Color.Light);
});
const symbols = [];
horizontal.symbols.forEach(list => symbols.push(...list));
vertical.symbols.forEach(list => symbols.push(...list));
return horizontal.withTiles(tiles).withSymbols(symbols);
}
}
get configs() {
return WrapAroundRule.CONFIGS;
}
get searchVariants() {
return WrapAroundRule.SEARCH_VARIANTS;
}
validateGrid(grid) {
if (grid.getTileCount(true, false, Color.Gray) > 0) {
return { state: State.Incomplete };
}
else {
return { state: State.Satisfied };
}
}
copyWith({ horizontal, vertical, }) {
return new WrapAroundRule(horizontal ?? this.horizontal, vertical ?? this.vertical);
}
get isSingleton() {
return true;
}
}
Object.defineProperty(WrapAroundRule, "EXAMPLE_GRID_NONE", {
enumerable: true,
configurable: true,
writable: true,
value: Object.freeze(GridData.create(['wwwww', 'wwwww', 'wwwww', 'wwwww', 'wwwww']))
});
Object.defineProperty(WrapAroundRule, "EXAMPLE_GRID_HORIZONTAL", {
enumerable: true,
configurable: true,
writable: true,
value: Object.freeze({
[Wrapping.None]: WrapAroundRule.EXAMPLE_GRID_NONE,
[Wrapping.Wrap]: GridData.create([
'wwwww',
'bwwwb',
'wwwww',
'bwwwb',
'wwwww',
])
.addSymbol(new LetterSymbol(0, 1, 'A'))
.addSymbol(new LetterSymbol(4, 1, 'A'))
.addSymbol(new LetterSymbol(0, 3, 'B'))
.addSymbol(new LetterSymbol(4, 3, 'B')),
[Wrapping.WrapReverse]: GridData.create([
'wwwww',
'bwwwb',
'wwwww',
'bwwwb',
'wwwww',
])
.addSymbol(new LetterSymbol(0, 1, 'A'))
.addSymbol(new LetterSymbol(4, 1, 'B'))
.addSymbol(new LetterSymbol(0, 3, 'B'))
.addSymbol(new LetterSymbol(4, 3, 'A')),
[Wrapping.ReflectReverse]: GridData.create([
'wwwww',
'bwwww',
'wwwww',
'wwwwb',
'wwwww',
])
.addSymbol(new MyopiaSymbol(0, 3, false, orientationToggle(Orientation.Left)))
.addSymbol(new MyopiaSymbol(4, 1, false, orientationToggle(Orientation.Right))),
})
});
Object.defineProperty(WrapAroundRule, "EXAMPLE_GRID_VERTICAL", {
enumerable: true,
configurable: true,
writable: true,
value: Object.freeze({
[Wrapping.None]: WrapAroundRule.EXAMPLE_GRID_NONE,
[Wrapping.Wrap]: GridData.create([
'wbwbw',
'wwwww',
'wwwww',
'wwwww',
'wbwbw',
])
.addSymbol(new LetterSymbol(1, 0, 'C'))
.addSymbol(new LetterSymbol(3, 0, 'D'))
.addSymbol(new LetterSymbol(1, 4, 'C'))
.addSymbol(new LetterSymbol(3, 4, 'D')),
[Wrapping.WrapReverse]: GridData.create([
'wbwbw',
'wwwww',
'wwwww',
'wwwww',
'wbwbw',
])
.addSymbol(new LetterSymbol(1, 0, 'C'))
.addSymbol(new LetterSymbol(3, 0, 'D'))
.addSymbol(new LetterSymbol(1, 4, 'D'))
.addSymbol(new LetterSymbol(3, 4, 'C')),
[Wrapping.ReflectReverse]: GridData.create([
'wbwww',
'wwwww',
'wwwww',
'wwwww',
'wwwbw',
])
.addSymbol(new MyopiaSymbol(3, 0, false, orientationToggle(Orientation.Up)))
.addSymbol(new MyopiaSymbol(1, 4, false, orientationToggle(Orientation.Down))),
})
});
Object.defineProperty(WrapAroundRule, "SEARCH_VARIANTS", {
enumerable: true,
configurable: true,
writable: true,
value: [
new WrapAroundRule(Wrapping.Wrap, Wrapping.None).searchVariant(),
new WrapAroundRule(Wrapping.None, Wrapping.Wrap).searchVariant(),
new WrapAroundRule(Wrapping.Wrap, Wrapping.Wrap).searchVariant(),
new WrapAroundRule(Wrapping.ReflectReverse, Wrapping.None).searchVariant(),
new WrapAroundRule(Wrapping.None, Wrapping.ReflectReverse).searchVariant(),
new WrapAroundRule(Wrapping.ReflectReverse, Wrapping.ReflectReverse).searchVariant(),
]
});
Object.defineProperty(WrapAroundRule, "CONFIGS", {
enumerable: true,
configurable: true,
writable: true,
value: Object.freeze([
{
type: ConfigType.Wrapping,
default: Wrapping.Wrap,
field: 'horizontal',
description: 'Horizontal wrap',
configurable: true,
},
{
type: ConfigType.Wrapping,
default: Wrapping.Wrap,
field: 'vertical',
description: 'Vertical wrap',
configurable: true,
},
])
});
export default WrapAroundRule;
export const instance = new WrapAroundRule(Wrapping.Wrap, Wrapping.Wrap);