I am building a gameboard in JS for a battleship game and here's its current structure:
export default class Gameboard {
constructor(size) {
this.grid = this.#createMatrix(size);
}
#createMatrix(size) {
const mat = new Array(size);
for (let i = 0; i < size; i++) {
// ship - for ship object if it exists, attacked - isAttacked?,
// index - relative placement of ship tile wrt whole ship, if it exists
mat[i] = new Array(size).fill({ ship: null, attacked: false, index: -1 });
}
return mat;
}
/**
* @param {Ship} ship to be placed
* @param {int} x starting x coordinate of ship placement
* @param {int} y starting y coordinate of ship placement
*/
placeShip(ship, x, y) {
for (let i = 0; i < ship.length; i++) {
this.grid[x][y]["ship"] = ship;
this.grid[x][y]["index"] = i;
console.log(this.grid[x][y]);
y++; //move to next column for next tile placement
}
}
}
I can't understand why the following test to place a ship horizontally on it fails:
it("places ships", () => {
const gameboard = new Gameboard(2);
const ship = new Ship(2);
gameboard.placeShip(ship, 0, 0);
expect(gameboard.grid).toEqual([
[
{ ship: ship, index: 0, attacked: false },
{ ship: ship, index: 1, attacked: false },
],
[defaultObj, defaultObj],
]);
});
Error message:
It appears that while looping, both columns' objects get updated but I want only one column's to be updated.
The problem is here:
new Array(size).fill({ ship: null, attacked: false, index: -1 })
There, you're creating one "ship" object, and you're filling the array with references to that one object.
You can do it like this instead, to create a new ship for every entry:
new Array(size).fill().map(() => ({ ship: null, attacked: false, index: -1 }));