ConnectForce/src/js/Game.js

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;
}
}