193 lines
4 KiB
JavaScript
193 lines
4 KiB
JavaScript
import { Constants } from "./Constants.js";
|
|
import { elt } from "./elt.js";
|
|
import { State } from "./State.js";
|
|
|
|
/**
|
|
* Represents a game.
|
|
*/
|
|
export class Game
|
|
{
|
|
/**
|
|
* The width of the board.
|
|
*/
|
|
static #width = 7;
|
|
|
|
/**
|
|
* The height of the board.
|
|
*/
|
|
static #height = 6;
|
|
|
|
/**
|
|
* The state of the game.
|
|
*
|
|
* @type {State}
|
|
*/
|
|
#state;
|
|
|
|
/**
|
|
* The actual board.
|
|
*
|
|
* @type {HTMLElement}
|
|
*/
|
|
#board;
|
|
|
|
/**
|
|
* The element containing a log message.
|
|
*
|
|
* @type {HTMLElement}
|
|
*/
|
|
#log;
|
|
|
|
/**
|
|
* The id of the element to add the board to.
|
|
*
|
|
* @type {string}
|
|
*/
|
|
id;
|
|
|
|
/**
|
|
* Initializes a new instance of the {@link Game `Game`} class.
|
|
*
|
|
* @param {string} id
|
|
* The id of the element to add the board to.
|
|
*/
|
|
constructor(id)
|
|
{
|
|
this.id = id;
|
|
this.#state = new State(Game.#width, Game.#height);
|
|
}
|
|
|
|
/**
|
|
* Gets the state of the game.
|
|
*/
|
|
get state()
|
|
{
|
|
return this.#state;
|
|
}
|
|
|
|
/**
|
|
* Gets the board of the game.
|
|
*/
|
|
get board()
|
|
{
|
|
return this.state.board;
|
|
}
|
|
|
|
/**
|
|
* Initializes the game.
|
|
*/
|
|
initialize()
|
|
{
|
|
let container = document.getElementById(this.id);
|
|
|
|
this.#board = elt(
|
|
"div",
|
|
{
|
|
class: "board"
|
|
});
|
|
|
|
this.#log = elt(
|
|
"div",
|
|
{
|
|
class: "log"
|
|
});
|
|
|
|
container.appendChild(this.#board);
|
|
container.appendChild(this.#log);
|
|
this.draw();
|
|
}
|
|
|
|
/**
|
|
* Resets the game.
|
|
*/
|
|
reset()
|
|
{
|
|
this.#state = new State(Game.#width, Game.#height);
|
|
this.draw();
|
|
}
|
|
|
|
/**
|
|
* Replaces the content of the board with the current state.
|
|
*/
|
|
draw()
|
|
{
|
|
let board = this.#board;
|
|
board.innerHTML = "";
|
|
|
|
for (let y = 0; y < Game.#height; y++)
|
|
{
|
|
for (let x = 0; x < Game.#width; x++)
|
|
{
|
|
/** @type {Node[]} */
|
|
let children = [];
|
|
let playerId = this.board[y][x];
|
|
|
|
if (playerId !== "")
|
|
{
|
|
children.push(
|
|
elt(
|
|
"div",
|
|
{
|
|
class: `piece ${Constants.PLAYER_NAMES[playerId]}`
|
|
}));
|
|
}
|
|
|
|
let field = elt(
|
|
"div",
|
|
{
|
|
class: "field"
|
|
},
|
|
...children);
|
|
|
|
field.onclick = () =>
|
|
{
|
|
if (this.addChip(x, y))
|
|
{
|
|
this.state.turnCount++;
|
|
this.draw();
|
|
}
|
|
};
|
|
|
|
board.appendChild(field);
|
|
}
|
|
}
|
|
|
|
board.appendChild(
|
|
elt(
|
|
"div",
|
|
{
|
|
style: "clear: both;"
|
|
}));
|
|
|
|
this.#log.className = "";
|
|
this.#log.classList.add(this.state.currentPlayer);
|
|
this.#log.innerHTML = "";
|
|
this.#log.textContent = `It's player "${Constants.PLAYER_NAMES[this.state.currentPlayer]}"s turn`;
|
|
}
|
|
|
|
/**
|
|
* Adds a chip to the board indicated by the {@link x `x`} and the {@link y `y`} coordinate.
|
|
*
|
|
* @param {number} x
|
|
* The x coordinate to add the chip to.
|
|
*
|
|
* @param {number} y
|
|
* The y coordinate to add the chip to.
|
|
*
|
|
* @returns {boolean}
|
|
* A value indicating whether the chip could be added.
|
|
*/
|
|
addChip(x, y)
|
|
{
|
|
for (let i = Game.#height - 1; i >= 0; i--)
|
|
{
|
|
if (this.board[i][x] === "")
|
|
{
|
|
this.board[i][x] = this.state.currentPlayer;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|