Adds GameBoard class.
This commit is contained in:
488
main.js
488
main.js
@@ -6,141 +6,63 @@ const Direction = Object.freeze({
|
||||
get values() { return Object.values(Direction); },
|
||||
fromName(name) { return this.values.filter(i=>i.name == name)[0] || null; },
|
||||
});
|
||||
const globals = {
|
||||
grid: null,
|
||||
};
|
||||
|
||||
let gameBoard;
|
||||
|
||||
const btnStart_onClick = () => {
|
||||
globals.grid = new Grid(4, 4, new Tile(0, false));
|
||||
addRandomTile();
|
||||
// globals.grid = makeDevGrid([ // can't slide down or left
|
||||
// [2,1,3,4],
|
||||
// [3,5,7,9],
|
||||
// [1,2,1,2],
|
||||
// [3,4,5,0],
|
||||
// ]);
|
||||
redraw(globals.grid);
|
||||
gameBoard = new GameBoard(new Grid(4, 4));
|
||||
// gameBoard = new GameBoard(
|
||||
// makeDevGrid([ // can't slide down or left
|
||||
// [2,1,3,4],
|
||||
// [3,5,7,9],
|
||||
// [1,2,1,2],
|
||||
// [3,4,5,0],
|
||||
// ])
|
||||
// );
|
||||
gameBoard.addRandomTile();
|
||||
redraw(gameBoard);
|
||||
}
|
||||
|
||||
const btnRedraw_onClick = () => {
|
||||
redraw(globals.grid);
|
||||
redraw(gameBoard);
|
||||
}
|
||||
|
||||
const getSettingsForDirection = (direction) => {
|
||||
let settings = {
|
||||
merge: (from, to) => {
|
||||
to.value++;
|
||||
from.value = 0;
|
||||
from.isVisible = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (direction === Direction.Up || direction === Direction.Left) {
|
||||
settings = {
|
||||
...settings,
|
||||
advance: i => i + 1,
|
||||
testForDone: (fromIndex, length) => fromIndex >= length,
|
||||
getInitialFromIndex: () => 1,
|
||||
getInitialToIndex: () => 0
|
||||
};
|
||||
} else if (direction === Direction.Down || direction === Direction.Right) {
|
||||
settings = {
|
||||
...settings,
|
||||
advance: i => i - 1,
|
||||
testForDone: fromIndex => fromIndex < 0,
|
||||
getInitialFromIndex: (length) => length - 2,
|
||||
getInitialToIndex: (length) => length - 1
|
||||
};
|
||||
}
|
||||
|
||||
if (direction === Direction.Up || direction === Direction.Down) {
|
||||
settings = {
|
||||
...settings,
|
||||
getVector: (grid, index) => grid.getColumn(index),
|
||||
swap: (grid, vector, columnIndex, from, to) => {
|
||||
grid.swapTiles(from, columnIndex, to, columnIndex);
|
||||
const tempTile = vector[to];
|
||||
vector[to] = vector[from];
|
||||
vector[from] = tempTile;
|
||||
},
|
||||
getLength: (grid) => grid.numColumns
|
||||
}
|
||||
} else if (direction === Direction.Left || direction === Direction.Right) {
|
||||
settings = {
|
||||
...settings,
|
||||
getVector: (grid, index) => grid.getRow(index),
|
||||
swap: (grid, vector, rowIndex, from, to) => {
|
||||
grid.swapTiles(rowIndex, from, rowIndex, to);
|
||||
const tempTile = vector[to];
|
||||
vector[to] = vector[from];
|
||||
vector[from] = tempTile;
|
||||
},
|
||||
getLength: (grid) => grid.numRows
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
const slideInDirection = (grid, direction) => {
|
||||
const settings = getSettingsForDirection(direction);
|
||||
const length = settings.getLength(grid);
|
||||
let didChange = false;
|
||||
|
||||
for (let index = 0; index < length; index++) {
|
||||
const vector = settings.getVector(grid, index);
|
||||
const swap = settings.swap.bind(this, grid, vector, index);
|
||||
const initialFromIndex = settings.getInitialFromIndex(vector.length);
|
||||
const initialToIndex = settings.getInitialToIndex(vector.length);
|
||||
const didChangeThisPass = slide(
|
||||
initialFromIndex,
|
||||
initialToIndex,
|
||||
vector,
|
||||
settings.advance,
|
||||
swap,
|
||||
settings.merge,
|
||||
settings.testForDone
|
||||
);
|
||||
didChange = didChange || didChangeThisPass;
|
||||
}
|
||||
return didChange;
|
||||
}
|
||||
|
||||
const playMove = (grid, direction) => {
|
||||
if (slideInDirection(grid, direction)) {
|
||||
addRandomTile();
|
||||
redraw(grid)
|
||||
// TODO(tom): This should take GameBoard instead of Grid or be moved into GameBoard.
|
||||
const playMove = (gameBoard, direction) => {
|
||||
if (gameBoard.slideInDirection(direction)) {
|
||||
gameBoard.addRandomTile();
|
||||
redraw(gameBoard)
|
||||
} else {
|
||||
alert(`Unable to slide ${direction.name}.`);
|
||||
// alert(`Unable to slide ${direction.name}.`);
|
||||
}
|
||||
checkForEnd(grid);
|
||||
checkForEnd(gameBoard);
|
||||
}
|
||||
|
||||
const btnUp_onClick = () => {
|
||||
playMove(globals.grid, Direction.Up);
|
||||
playMove(gameBoard, Direction.Up);
|
||||
}
|
||||
|
||||
const btnDown_onClick = () => {
|
||||
playMove(globals.grid, Direction.Down);
|
||||
playMove(gameBoard, Direction.Down);
|
||||
}
|
||||
|
||||
const btnLeft_onClick = () => {
|
||||
playMove(globals.grid, Direction.Left);
|
||||
playMove(gameBoard, Direction.Left);
|
||||
}
|
||||
|
||||
const btnRight_onClick = () => {
|
||||
playMove(globals.grid, Direction.Right);
|
||||
playMove(gameBoard, Direction.Right);
|
||||
}
|
||||
|
||||
const drawGrid = (grid, element) => {
|
||||
// grid is our grid
|
||||
// element is our div
|
||||
const redraw = (gameBoard) => {
|
||||
const element = document.getElementById('output');
|
||||
|
||||
let text = "<table cellspacing=\"0\">\n";
|
||||
for (let rowIndex = 0; rowIndex < grid.numRows; rowIndex++) {
|
||||
for (let rowIndex = 0; rowIndex < gameBoard.numRows; rowIndex++) {
|
||||
text += " <tr>\n";
|
||||
for (let columnIndex = 0; columnIndex < grid.numColumns; columnIndex++) {
|
||||
const tile = grid.getTile(rowIndex, columnIndex);
|
||||
text += " <td title=\"(" + tile.originalPosition.row + ", " + tile.originalPosition.column + ")\"class=\"" + (tile.isVisible ? "visible " : "hidden ") + "\">" + tile.value + "</td>\n";
|
||||
for (let columnIndex = 0; columnIndex < gameBoard.numColumns; columnIndex++) {
|
||||
const tile = gameBoard.getTile(rowIndex, columnIndex);
|
||||
text += " <td class=\"" + (tile.isVisible ? "visible " : "hidden ") + "\">" + tile.value + "</td>\n";
|
||||
}
|
||||
text += " </tr>\n";
|
||||
}
|
||||
@@ -148,92 +70,8 @@ const drawGrid = (grid, element) => {
|
||||
element.innerHTML = text;
|
||||
}
|
||||
|
||||
const addRandomTile = () => {
|
||||
const hiddenTiles = globals.grid.tiles.filter(tile => !tile.isVisible);
|
||||
if (hiddenTiles.length <=0) return;
|
||||
const index = Math.floor(Math.random() * hiddenTiles.length);
|
||||
const tile = hiddenTiles[index];
|
||||
tile.value = 1;
|
||||
tile.isVisible = true;
|
||||
}
|
||||
|
||||
const redraw = (grid) => {
|
||||
const element = document.getElementById('output');
|
||||
drawGrid(grid, element);
|
||||
}
|
||||
|
||||
const slide = (fromIndex, toIndex, vector, advance, swap, merge, testForDone) => {
|
||||
let didIDoIt = false;
|
||||
let hasMergedPrevious = false;
|
||||
while(!testForDone(fromIndex, vector.length)) {
|
||||
const fromTile = vector[fromIndex];
|
||||
const toTile = toIndex < vector.length && toIndex >= 0 ? vector[toIndex] : null;
|
||||
if (toTile == null) {
|
||||
// Advance toIndex
|
||||
toIndex = advance(toIndex);
|
||||
hasMergedPrevious = false;
|
||||
continue;
|
||||
}
|
||||
if (fromIndex == toIndex) {
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
hasMergedPrevious = false;
|
||||
continue;
|
||||
}
|
||||
if (!toTile.isVisible) {
|
||||
if (fromTile.isVisible) {
|
||||
swap(fromIndex, toIndex);
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
hasMergedPrevious = false;
|
||||
didIDoIt = true;
|
||||
} else {
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
}
|
||||
} else {
|
||||
if (fromTile.isVisible) {
|
||||
if (fromTile.value == toTile.value) {
|
||||
if (hasMergedPrevious) {
|
||||
// Advance toIndex
|
||||
toIndex = advance(toIndex);
|
||||
hasMergedPrevious = false;
|
||||
didIDoIt = true;
|
||||
} else {
|
||||
// Merge tiles
|
||||
merge(fromTile, toTile);
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
hasMergedPrevious = true;
|
||||
didIDoIt = true;
|
||||
}
|
||||
} else {
|
||||
// Advance toIndex
|
||||
toIndex = advance(toIndex);
|
||||
hasMergedPrevious = false;
|
||||
}
|
||||
} else {
|
||||
fromIndex = advance(fromIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return didIDoIt;
|
||||
}
|
||||
|
||||
const canSlideInDirection = (grid, direction) => {
|
||||
const clonedGrid = grid.clone();
|
||||
return slideInDirection(clonedGrid, direction);
|
||||
}
|
||||
|
||||
const gameIsLost = (grid) => {
|
||||
return !canSlideInDirection(grid, Direction.Up)
|
||||
&& !canSlideInDirection(grid, Direction.Right)
|
||||
&& !canSlideInDirection(grid, Direction.Down)
|
||||
&& !canSlideInDirection(grid, Direction.Left);
|
||||
}
|
||||
|
||||
const checkForEnd = (grid) => {
|
||||
if (gameIsLost(grid)) {
|
||||
const checkForEnd = (gameBoard) => {
|
||||
if (gameBoard.gameIsLost()) {
|
||||
alert('A loser is you!');
|
||||
}
|
||||
}
|
||||
@@ -241,8 +79,7 @@ const checkForEnd = (grid) => {
|
||||
const makeDevGrid = (matrix) => {
|
||||
const numRows = matrix.length;
|
||||
const numColumns = matrix[0].length;
|
||||
const initialValue = new Tile(0, false, new GridPosition(0, 0));
|
||||
const grid = new Grid(numRows, numColumns, initialValue);
|
||||
const grid = new Grid(numRows, numColumns);
|
||||
for (let rowIndex = 0; rowIndex < numRows; rowIndex++) {
|
||||
const row = matrix[rowIndex];
|
||||
for (let colIndex = 0; colIndex < numColumns; colIndex++) {
|
||||
@@ -275,45 +112,204 @@ up()
|
||||
*/
|
||||
|
||||
class GameBoard {
|
||||
#grid_;
|
||||
#grid;
|
||||
|
||||
constructor() {
|
||||
|
||||
get numColumns() {
|
||||
return this.#grid.numColumns;
|
||||
}
|
||||
|
||||
get numRows() {
|
||||
return this.#grid.numRows;
|
||||
}
|
||||
|
||||
constructor(grid) {
|
||||
this.#grid = grid;
|
||||
}
|
||||
|
||||
getTile(row, column) {
|
||||
return this.#grid.getTile(row, column);
|
||||
}
|
||||
|
||||
addRandomTile() {
|
||||
const hiddenTiles = this.#grid.tiles.filter(tile => !tile.isVisible);
|
||||
if (hiddenTiles.length <= 0) { return; }
|
||||
const randomIndex = Math.floor(Math.random() * hiddenTiles.length);
|
||||
const tile = hiddenTiles[randomIndex];
|
||||
// TODO(tom): Make this random of either 1 or 2 and heavily weight 1.
|
||||
tile.value = 1;
|
||||
tile.isVisible = true;
|
||||
}
|
||||
|
||||
slideInDirection (direction) {
|
||||
return GameBoard.#slideInDirection_impl(direction, this.#grid);
|
||||
}
|
||||
|
||||
gameIsLost() {
|
||||
return !this.#canSlideInDirection(Direction.Up)
|
||||
&& !this.#canSlideInDirection(Direction.Right)
|
||||
&& !this.#canSlideInDirection(Direction.Down)
|
||||
&& !this.#canSlideInDirection(Direction.Left);
|
||||
}
|
||||
|
||||
#canSlideInDirection(direction) {
|
||||
const clonedGrid = this.#grid.clone();
|
||||
return GameBoard.#slideInDirection_impl(direction, clonedGrid);
|
||||
}
|
||||
|
||||
static #slideInDirection_impl (direction, grid) {
|
||||
const settings = GameBoard.#getSettingsForDirection(direction);
|
||||
const length = settings.getLength(grid);
|
||||
let didChange = false;
|
||||
|
||||
for (let index = 0; index < length; index++) {
|
||||
const vector = settings.getVector(grid, index);
|
||||
const swap = settings.swap.bind(this, grid, vector, index);
|
||||
const initialFromIndex = settings.getInitialFromIndex(vector.length);
|
||||
const initialToIndex = settings.getInitialToIndex(vector.length);
|
||||
const didChangeThisPass = GameBoard.#slide(
|
||||
initialFromIndex,
|
||||
initialToIndex,
|
||||
vector,
|
||||
settings.advance,
|
||||
swap,
|
||||
settings.merge,
|
||||
settings.testForDone
|
||||
);
|
||||
didChange = didChange || didChangeThisPass;
|
||||
}
|
||||
return didChange;
|
||||
}
|
||||
|
||||
static #getSettingsForDirection(direction) {
|
||||
const settings = new Settings();
|
||||
settings.merge = (from, to) => {
|
||||
to.value++;
|
||||
from.value = 0;
|
||||
from.isVisible = false;
|
||||
};
|
||||
|
||||
if (direction === Direction.Up || direction === Direction.Left) {
|
||||
settings.advance = i => i + 1;
|
||||
settings.testForDone = (fromIndex, length) => fromIndex >= length;
|
||||
settings.getInitialFromIndex = () => 1;
|
||||
settings.getInitialToIndex = () => 0;
|
||||
} else if (direction === Direction.Down || direction === Direction.Right) {
|
||||
settings.advance = i => i - 1;
|
||||
settings.testForDone = fromIndex => fromIndex < 0;
|
||||
settings.getInitialFromIndex = (length) => length - 2;
|
||||
settings.getInitialToIndex = (length) => length - 1;
|
||||
}
|
||||
|
||||
if (direction === Direction.Up || direction === Direction.Down) {
|
||||
settings.getVector = (grid, index) => grid.getColumn(index);
|
||||
settings.swap = (grid, vector, columnIndex, from, to) => {
|
||||
grid.swapTiles(from, columnIndex, to, columnIndex);
|
||||
const tempTile = vector[to];
|
||||
vector[to] = vector[from];
|
||||
vector[from] = tempTile;
|
||||
}
|
||||
settings.getLength = grid => grid.numColumns;
|
||||
} else if (direction === Direction.Left || direction === Direction.Right) {
|
||||
settings.getVector = (grid, index) => grid.getRow(index);
|
||||
settings.swap = (grid, vector, rowIndex, from, to) => {
|
||||
grid.swapTiles(rowIndex, from, rowIndex, to);
|
||||
const tempTile = vector[to];
|
||||
vector[to] = vector[from];
|
||||
vector[from] = tempTile;
|
||||
};
|
||||
settings.getLength = grid => grid.numRows;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
static #slide(fromIndex, toIndex, vector, advance, swap, merge, testForDone) {
|
||||
let didChange = false;
|
||||
let hasMergedPrevious = false;
|
||||
while(!testForDone(fromIndex, vector.length)) {
|
||||
const fromTile = vector[fromIndex];
|
||||
const toTile = toIndex < vector.length && toIndex >= 0 ? vector[toIndex] : null;
|
||||
if (toTile == null) {
|
||||
// Advance toIndex
|
||||
toIndex = advance(toIndex);
|
||||
hasMergedPrevious = false;
|
||||
continue;
|
||||
}
|
||||
if (fromIndex == toIndex) {
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
hasMergedPrevious = false;
|
||||
continue;
|
||||
}
|
||||
if (!toTile.isVisible) {
|
||||
if (fromTile.isVisible) {
|
||||
swap(fromIndex, toIndex);
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
hasMergedPrevious = false;
|
||||
didChange = true;
|
||||
} else {
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
}
|
||||
} else {
|
||||
if (fromTile.isVisible) {
|
||||
if (fromTile.value == toTile.value) {
|
||||
if (hasMergedPrevious) {
|
||||
// Advance toIndex
|
||||
toIndex = advance(toIndex);
|
||||
hasMergedPrevious = false;
|
||||
didChange = true;
|
||||
} else {
|
||||
// Merge tiles
|
||||
merge(fromTile, toTile);
|
||||
// Advance fromIndex
|
||||
fromIndex = advance(fromIndex);
|
||||
hasMergedPrevious = true;
|
||||
didChange = true;
|
||||
}
|
||||
} else {
|
||||
// Advance toIndex
|
||||
toIndex = advance(toIndex);
|
||||
hasMergedPrevious = false;
|
||||
}
|
||||
} else {
|
||||
fromIndex = advance(fromIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return didChange;
|
||||
}
|
||||
};
|
||||
|
||||
class Grid {
|
||||
#tiles_ = [];
|
||||
#rows_ = [];
|
||||
#numRows_;
|
||||
#numColumns_;
|
||||
get tiles() { return [...this.#tiles_]; }
|
||||
get numRows() { return this.#numRows_; }
|
||||
get numColumns() { return this.#numColumns_; }
|
||||
#tiles = [];
|
||||
#rows = [];
|
||||
#numRows;
|
||||
#numColumns;
|
||||
get tiles() { return [...this.#tiles]; }
|
||||
get numRows() { return this.#numRows; }
|
||||
get numColumns() { return this.#numColumns; }
|
||||
|
||||
constructor(numRows, numColumns, initialValue) {
|
||||
this.#numRows_ = numRows;
|
||||
this.#numColumns_ = numColumns;
|
||||
constructor(numRows, numColumns) {
|
||||
this.#numRows = numRows;
|
||||
this.#numColumns = numColumns;
|
||||
for (let rowIndex = 0; rowIndex < numRows; rowIndex++) {
|
||||
const row = [];
|
||||
for (let columnIndex = 0; columnIndex < this.numColumns; columnIndex++) {
|
||||
const position = new GridPosition(rowIndex, columnIndex);
|
||||
const tile = new Tile(initialValue.value, initialValue.isVisible, position);
|
||||
this.#tiles_.push(tile);
|
||||
const tile = new Tile();
|
||||
this.#tiles.push(tile);
|
||||
row.push(tile);
|
||||
}
|
||||
this.#rows_.push(row);
|
||||
this.#rows.push(row);
|
||||
}
|
||||
}
|
||||
|
||||
clone() {
|
||||
const newGrid = new Grid(this.numRows, this.numColumns, new Tile(0, false, new GridPosition(0, 0)));
|
||||
const newGrid = new Grid(this.numRows, this.numColumns);
|
||||
for (let rowIndex = 0; rowIndex < this.numRows; rowIndex++) {
|
||||
for (let columnIndex = 0; columnIndex < this.numColumns; columnIndex++) {
|
||||
const newTile = newGrid.getTile(rowIndex, columnIndex);
|
||||
const oldTile = this.getTile(rowIndex, columnIndex);
|
||||
// TODO(tom): Set the originalPosition of newTile to be the same as oldTile.
|
||||
newTile.value = oldTile.value;
|
||||
newTile.isVisible = oldTile.isVisible;
|
||||
}
|
||||
@@ -340,7 +336,7 @@ class Grid {
|
||||
getTile (row, column) {
|
||||
if (row >= 0 && row < this.numRows && column >= 0 && column < this.numColumns) {
|
||||
// TODO(tom): Check that this is the right order.
|
||||
return this.#rows_[column][row]
|
||||
return this.#rows[column][row]
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -348,7 +344,7 @@ class Grid {
|
||||
setTile (row, column, tile) {
|
||||
if (row >= 0 && row < this.numRows && column >= 0 && column < this.numColumns) {
|
||||
// TODO(tom): Check that this is the right order.
|
||||
this.#rows_[column][row] = tile;
|
||||
this.#rows[column][row] = tile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,52 +362,56 @@ class Grid {
|
||||
}
|
||||
|
||||
toString (format = t => t.value) {
|
||||
return `[[${t(this.getTile(0, 0))},${t(this.getTile(0, 1))},${t(this.getTile(0, 2))},${t(this.getTile(0, 3))}],
|
||||
[${t(this.getTile(1, 0))},${t(this.getTile(1, 1))},${t(this.getTile(1, 2))},${t(this.getTile(1, 3))}],
|
||||
[${t(this.getTile(2, 0))},${t(this.getTile(2, 1))},${t(this.getTile(2, 2))},${t(this.getTile(2, 3))}],
|
||||
[${t(this.getTile(3, 0))},${t(this.getTile(3, 1))},${t(this.getTile(3, 2))},${t(this.getTile(3, 3))}]]`;
|
||||
return `[[${format(this.getTile(0, 0))},${format(this.getTile(0, 1))},${format(this.getTile(0, 2))},${format(this.getTile(0, 3))}],
|
||||
[${format(this.getTile(1, 0))},${format(this.getTile(1, 1))},${format(this.getTile(1, 2))},${format(this.getTile(1, 3))}],
|
||||
[${format(this.getTile(2, 0))},${format(this.getTile(2, 1))},${format(this.getTile(2, 2))},${format(this.getTile(2, 3))}],
|
||||
[${format(this.getTile(3, 0))},${format(this.getTile(3, 1))},${format(this.getTile(3, 2))},${format(this.getTile(3, 3))}]]`;
|
||||
}
|
||||
};
|
||||
|
||||
class GridPosition {
|
||||
#row_;
|
||||
#column_;
|
||||
#row;
|
||||
#column;
|
||||
constructor (row, column) {
|
||||
this.#row_ = row || 0;
|
||||
this.#column_ = column || 0;
|
||||
this.#row = row || 0;
|
||||
this.#column = column || 0;
|
||||
}
|
||||
get row() { return this.#row_; }
|
||||
get column() { return this.#column_; }
|
||||
get row() { return this.#row; }
|
||||
get column() { return this.#column; }
|
||||
equals (other) {
|
||||
return other !== null && other !== undefined
|
||||
&& this.#row_ === other.#row_
|
||||
&& this.#column_ === other.#column_;
|
||||
&& this.#row === other.#row
|
||||
&& this.#column === other.#column;
|
||||
}
|
||||
toString() {
|
||||
return `{ row: ${this.#row_}, column: ${this.#column_} }`;
|
||||
return `{ row: ${this.#row}, column: ${this.#column} }`;
|
||||
}
|
||||
}
|
||||
|
||||
class Tile {
|
||||
#originalPosition_;
|
||||
value;
|
||||
isVisible;
|
||||
get originalPosition() {
|
||||
return {...this.#originalPosition_};
|
||||
}
|
||||
constructor (value, isVisible, originalPosition = new GridPosition(0, 0)) {
|
||||
this.value = value;
|
||||
this.isVisible = isVisible;
|
||||
this.originalPosition_ = {...originalPosition};
|
||||
constructor () {
|
||||
this.value = 0;
|
||||
this.isVisible = false;
|
||||
}
|
||||
equals (other) {
|
||||
return other !== null && other !== undefined
|
||||
&& this.value === other.value
|
||||
&& this.isVisible === other.isVisible
|
||||
&& this.#originalPosition_.row === other.#originalPosition_.row
|
||||
&& this.#originalPosition_.column === other.#originalPosition_.column;
|
||||
&& this.isVisible === other.isVisible;
|
||||
}
|
||||
toString() {
|
||||
return `{ value: ${this.value}, originalPosition: { row: ${this.#originalPosition_.row}, column: ${this.#originalPosition_.column} }, isVisible: ${this.isVisible ? "true" : "false"} }`;
|
||||
return `{ value: ${this.value}, isVisible: ${this.isVisible ? "true" : "false"} }`;
|
||||
}
|
||||
};
|
||||
|
||||
class Settings {
|
||||
merge;
|
||||
advance;
|
||||
testForDone;
|
||||
getInitialFromIndex;
|
||||
getInitialToIndex;
|
||||
getVector;
|
||||
getLength;
|
||||
swap;
|
||||
};
|
||||
Reference in New Issue
Block a user