Compare commits
15 commits
f3a9568f70
...
d88e3a7ac8
Author | SHA1 | Date | |
---|---|---|---|
Manuel Thalmann | d88e3a7ac8 | ||
Manuel Thalmann | f0fb5a11fe | ||
Manuel Thalmann | 0794aaf8fb | ||
Manuel Thalmann | fb51f48a02 | ||
Manuel Thalmann | 391edbed72 | ||
Manuel Thalmann | be4956f360 | ||
Manuel Thalmann | 87f078da13 | ||
Manuel Thalmann | 2cf011ed03 | ||
Manuel Thalmann | 7950572ede | ||
Manuel Thalmann | ba28926219 | ||
Manuel Thalmann | 63bfb5375e | ||
Manuel Thalmann | 6faeae8b66 | ||
Manuel Thalmann | f542319b43 | ||
Manuel Thalmann | 5b46328d37 | ||
Manuel Thalmann | 8119440db0 |
|
@ -7,7 +7,10 @@
|
|||
<script type="module" src="./js/main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="board" id="board">
|
||||
<div id="game">
|
||||
</div>
|
||||
<button class="button new-game">
|
||||
New Game
|
||||
</button>
|
||||
</body>
|
||||
</html>
|
||||
|
|
193
src/js/Game.js
Normal file
193
src/js/Game.js
Normal file
|
@ -0,0 +1,193 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,55 @@
|
|||
/**
|
||||
* The state of the board.
|
||||
* Represents the state of a game.
|
||||
*/
|
||||
export const State = {
|
||||
turnCount: 0,
|
||||
export class State
|
||||
{
|
||||
/**
|
||||
* The board of the game.
|
||||
*
|
||||
* @type {Board}
|
||||
*/
|
||||
#board;
|
||||
|
||||
/**
|
||||
* Gets the id of the current player.
|
||||
*
|
||||
* @type {CellOwner}
|
||||
*/
|
||||
get currentPlayer()
|
||||
{
|
||||
return this.turnCount % 2 === 0 ? "r" : "b";
|
||||
},
|
||||
/**
|
||||
* The number of turns that have been played.
|
||||
*/
|
||||
turnCount = 0;
|
||||
|
||||
board: /** @type {Board} */ (
|
||||
Array(6).fill("").map(
|
||||
() => (Array(7).fill(""))))
|
||||
};
|
||||
/**
|
||||
* Initializes a new instance of the {@link State `State`} class.
|
||||
*
|
||||
* @param {number} width
|
||||
* The width of the board.
|
||||
*
|
||||
* @param {number} height
|
||||
* The height of the board.
|
||||
*/
|
||||
constructor(width, height)
|
||||
{
|
||||
this.#board = /** @type {Board} */ (
|
||||
Array(height).fill("").map(
|
||||
() =>
|
||||
{
|
||||
return Array(width).fill(
|
||||
/** @type {CellOwner} */ (""));
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of the current player.
|
||||
*
|
||||
* @type {CellOwner}
|
||||
*/
|
||||
get currentPlayer()
|
||||
{
|
||||
return this.turnCount % 2 === 0 ? "r" : "b";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the board of the game.
|
||||
*/
|
||||
get board()
|
||||
{
|
||||
return this.#board;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
import { Constants } from "./Constants.js";
|
||||
import { elt } from "./elt.js";
|
||||
import { State } from "./State.js";
|
||||
|
||||
/**
|
||||
* Initializes the game board.
|
||||
*
|
||||
* @param {string} id
|
||||
* The id of the element to add the board to.
|
||||
*/
|
||||
export function initializeBoard(id)
|
||||
{
|
||||
let board = document.getElementById(id);
|
||||
board.innerHTML = "";
|
||||
|
||||
for (let i = 0; i < 6; i++)
|
||||
{
|
||||
for (let j = 0; j < 7; j++)
|
||||
{
|
||||
/** @type {Node[]} */
|
||||
let children = [];
|
||||
let playerId = State.board[i][j];
|
||||
|
||||
if (playerId !== "")
|
||||
{
|
||||
children.push(elt(
|
||||
"div",
|
||||
{
|
||||
class: `piece ${Constants.PLAYER_NAMES[playerId]}`
|
||||
}));
|
||||
}
|
||||
|
||||
let field = elt(
|
||||
"div",
|
||||
{
|
||||
class: "field"
|
||||
},
|
||||
...children);
|
||||
|
||||
field.onclick = () =>
|
||||
{
|
||||
State.board[i][j] = State.currentPlayer;
|
||||
State.turnCount++;
|
||||
initializeBoard("board");
|
||||
};
|
||||
|
||||
board.appendChild(field);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,24 @@
|
|||
import { initializeBoard } from "./board.js";
|
||||
import { Game } from "./Game.js";
|
||||
|
||||
/**
|
||||
* The game that is being played.
|
||||
*
|
||||
* @type {Game}
|
||||
*/
|
||||
let game;
|
||||
|
||||
/**
|
||||
* Initializes the board.
|
||||
*/
|
||||
function initialize()
|
||||
{
|
||||
initializeBoard("board");
|
||||
game = new Game("game");
|
||||
game.initialize();
|
||||
|
||||
(/** @type {HTMLElement} */ (document.querySelector(".new-game"))).onclick = () =>
|
||||
{
|
||||
game.reset();
|
||||
};
|
||||
}
|
||||
|
||||
initialize();
|
||||
|
|
11
src/js/types.d.ts
vendored
11
src/js/types.d.ts
vendored
|
@ -6,16 +6,9 @@ type CellOwner = "" | "r" | "b";
|
|||
/**
|
||||
* Represents a row of the game field.
|
||||
*/
|
||||
type Row = [CellOwner, CellOwner, CellOwner, CellOwner, CellOwner, CellOwner, CellOwner];
|
||||
type Row = CellOwner[];
|
||||
|
||||
/**
|
||||
* Represents a game board.
|
||||
*/
|
||||
type Board = [
|
||||
Row,
|
||||
Row,
|
||||
Row,
|
||||
Row,
|
||||
Row,
|
||||
Row
|
||||
];
|
||||
type Board = Row[];
|
||||
|
|
|
@ -4,7 +4,7 @@ div {
|
|||
|
||||
.board {
|
||||
width: 84vw;
|
||||
margin: auto;
|
||||
margin: 10px auto;
|
||||
outline: 1px solid black;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue