From 6beda8d14f4884c6a29d54fa31fd889e5f1fd525 Mon Sep 17 00:00:00 2001 From: Manuel Thalmann Date: Thu, 15 Dec 2022 10:06:49 +0100 Subject: [PATCH] Render game using SJDON --- src/js/Components.js | 80 ++++++++++++++++++++++++++++++++++++++++ src/js/Game.js | 87 ++------------------------------------------ 2 files changed, 84 insertions(+), 83 deletions(-) create mode 100644 src/js/Components.js diff --git a/src/js/Components.js b/src/js/Components.js new file mode 100644 index 0000000..e9dd6a8 --- /dev/null +++ b/src/js/Components.js @@ -0,0 +1,80 @@ +import { Constants } from "./Constants.js"; + +/** + * Gets a component which represents the specified {@link game `game`}. + * + * @param {import("./Game.js").Game} game + * The game represented in this app. + * + * @returns {NodeDescriptor} + * The rendered node. + */ +export function App(game) +{ + return [ + "div", + [ + Board, + game.board + ], + [ + "div", + { className: "log" }, + game.winner ? + `Player ${Constants.PLAYER_NAMES[game.winner]} wins!` : + `It's player "${Constants.PLAYER_NAMES[game.currentPlayer]}"s turn` + ] + ]; +} + +/** + * Renders an element which represents the specified {@link board `board`}. + * + * @param {Board} board + * The board represented in this element. + * + * @returns {NodeDescriptor} + * The rendered element. + */ +export function Board(board) +{ + let fields = board.flatMap((row) => row); + + return [ + "div", + { className: "board" }, + ...fields.map( + (field) => + { + return /** @type {NodeDescriptor} */([Field, field]); + }), + ["div", { style: "clear: both;" }] + ]; +} + +/** + * Renders an element which represents the specified {@link field `field`}. + * + * @param {CellOwner} field + * The field to represent. + * + * @returns {NodeDescriptor} + * The rendered element. + */ +export function Field(field) +{ + return [ + "div", + { className: "field" }, + ...( + field !== "" ? + [ + /** @type {NodeDescriptor} */ + ([ + "div", + { className: `piece ${Constants.PLAYER_NAMES[field]}` } + ]) + ] : + []) + ]; +} diff --git a/src/js/Game.js b/src/js/Game.js index 71a5e2c..a19db25 100644 --- a/src/js/Game.js +++ b/src/js/Game.js @@ -1,5 +1,4 @@ -import { Constants } from "./Constants.js"; -import { elt } from "./elt.js"; +import { App } from "./Components.js"; import { render } from "./SJDON.js"; import { State } from "./State.js"; @@ -30,20 +29,6 @@ export class Game */ #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. * @@ -167,22 +152,6 @@ export class 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(); } @@ -200,57 +169,9 @@ export class Game */ draw() { - let board = this.#board; - board.innerHTML = ""; - - render( - [ - "div", - ...this.board.flatMap( - (row, y) => - { - return row.map( - (cell, x) => - { - return /** @type {NodeDescriptor} */ ([ - "div", - { - className: "field", - onclick: () => - { - if (this.addChip(x, y)) - { - this.state.turnCount++; - this.draw(); - } - } - }, - ...( - cell !== "" ? - [ - /** @type {NodeDescriptor} */ (["div", { className: `piece ${Constants.PLAYER_NAMES[cell]}` }]) - ] : - []) - ]); - }); - }), - ["div", { style: "clear: both;" }] - ], - board); - - this.#log.innerHTML = ""; - - render( - [ - "div", - { - className: this.state.currentPlayer - }, - this.winner ? - `Player ${Constants.PLAYER_NAMES[this.winner]} wins!` : - `It's player "${Constants.PLAYER_NAMES[this.state.currentPlayer]}"s turn` - ], - this.#log); + let container = document.getElementById(this.id); + container.innerHTML = ""; + render([App, this], container); } /**