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>
|
<script type="module" src="./js/main.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="board" id="board">
|
<div id="game">
|
||||||
</div>
|
</div>
|
||||||
|
<button class="button new-game">
|
||||||
|
New Game
|
||||||
|
</button>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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,8 +1,39 @@
|
||||||
/**
|
/**
|
||||||
* The state of the board.
|
* Represents the state of a game.
|
||||||
*/
|
*/
|
||||||
export const State = {
|
export class State
|
||||||
turnCount: 0,
|
{
|
||||||
|
/**
|
||||||
|
* The board of the game.
|
||||||
|
*
|
||||||
|
* @type {Board}
|
||||||
|
*/
|
||||||
|
#board;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of turns that have been played.
|
||||||
|
*/
|
||||||
|
turnCount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Gets the id of the current player.
|
||||||
|
@ -12,9 +43,13 @@ export const State = {
|
||||||
get currentPlayer()
|
get currentPlayer()
|
||||||
{
|
{
|
||||||
return this.turnCount % 2 === 0 ? "r" : "b";
|
return this.turnCount % 2 === 0 ? "r" : "b";
|
||||||
},
|
}
|
||||||
|
|
||||||
board: /** @type {Board} */ (
|
/**
|
||||||
Array(6).fill("").map(
|
* Gets the board of the game.
|
||||||
() => (Array(7).fill(""))))
|
*/
|
||||||
};
|
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.
|
* Initializes the board.
|
||||||
*/
|
*/
|
||||||
function initialize()
|
function initialize()
|
||||||
{
|
{
|
||||||
initializeBoard("board");
|
game = new Game("game");
|
||||||
|
game.initialize();
|
||||||
|
|
||||||
|
(/** @type {HTMLElement} */ (document.querySelector(".new-game"))).onclick = () =>
|
||||||
|
{
|
||||||
|
game.reset();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize();
|
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.
|
* Represents a row of the game field.
|
||||||
*/
|
*/
|
||||||
type Row = [CellOwner, CellOwner, CellOwner, CellOwner, CellOwner, CellOwner, CellOwner];
|
type Row = CellOwner[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a game board.
|
* Represents a game board.
|
||||||
*/
|
*/
|
||||||
type Board = [
|
type Board = Row[];
|
||||||
Row,
|
|
||||||
Row,
|
|
||||||
Row,
|
|
||||||
Row,
|
|
||||||
Row,
|
|
||||||
Row
|
|
||||||
];
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ div {
|
||||||
|
|
||||||
.board {
|
.board {
|
||||||
width: 84vw;
|
width: 84vw;
|
||||||
margin: auto;
|
margin: 10px auto;
|
||||||
outline: 1px solid black;
|
outline: 1px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue