Compare commits

..

No commits in common. "c40492c0e312ca0d0b9204897fbe0020eaff8cc0" and "2d0b47f603170522606e4eec99a1863282c16129" have entirely different histories.

4 changed files with 45 additions and 124 deletions

View file

@ -1,6 +1,5 @@
import { Constants } from "./Constants.js"; import { Constants } from "./Constants.js";
import { elt } from "./elt.js"; import { elt } from "./elt.js";
import { render } from "./SJDON.js";
import { State } from "./State.js"; import { State } from "./State.js";
/** /**
@ -146,52 +145,55 @@ export class Game
let board = this.#board; let board = this.#board;
board.innerHTML = ""; board.innerHTML = "";
render( for (let y = 0; y < Game.#height; y++)
[ {
"div", for (let x = 0; x < Game.#width; x++)
...this.board.flatMap( {
(row, y) => /** @type {Node[]} */
{ let children = [];
return row.map( let playerId = this.board[y][x];
(cell, x) =>
if (playerId !== "")
{
children.push(
elt(
"div",
{ {
return /** @type {NodeDescriptor} */ ([ class: `piece ${Constants.PLAYER_NAMES[playerId]}`
"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 = ""; let field = elt(
"div",
{
class: "field"
},
...children);
render( field.onclick = () =>
[ {
if (this.addChip(x, y))
{
this.state.turnCount++;
this.draw();
}
};
board.appendChild(field);
}
}
board.appendChild(
elt(
"div", "div",
{ {
className: this.state.currentPlayer style: "clear: both;"
}, }));
`It's player "${Constants.PLAYER_NAMES[this.state.currentPlayer]}"s turn`
], this.#log.className = "";
this.#log); this.#log.classList.add(this.state.currentPlayer);
this.#log.innerHTML = "";
this.#log.textContent = `It's player "${Constants.PLAYER_NAMES[this.state.currentPlayer]}"s turn`;
} }
/** /**

View file

@ -1,51 +0,0 @@
/**
* Renders the specified {@link data `data`} and appends it to the specified {@link element `element`}.
*
* @param {NodeDescriptor} data
* The node to render written in SJDON notation.
*
* @param {HTMLElement} element
* The element to add the rendered node to.
*/
export function render(data, element)
{
if (Array.isArray(data))
{
let descriptor = data[0];
let args = data.slice(1);
if (typeof descriptor === "function")
{
render(descriptor(...args), element);
}
else if (typeof descriptor === "string")
{
let result = element.ownerDocument.createElement(descriptor);
element.appendChild(result);
for (let arg of args)
{
if (typeof arg === "object" && !Array.isArray(arg))
{
Object.assign(result, arg);
}
else
{
render(arg, result);
}
}
}
else
{
throw new SyntaxError();
}
}
else if (typeof data === "string")
{
element.appendChild(element.ownerDocument.createTextNode(data));
}
else
{
throw new SyntaxError();
}
}

View file

@ -65,9 +65,8 @@ function initialize()
game = new Game("game"); game = new Game("game");
game.initialize(); game.initialize();
(/** @type {HTMLElement} */ (document.querySelector(".new-game"))).onclick = (event) => (/** @type {HTMLElement} */ (document.querySelector(".new-game"))).onclick = () =>
{ {
event.preventDefault();
game.reset(); game.reset();
}; };

View file

@ -28,32 +28,3 @@ interface IState
*/ */
board: Board; board: Board;
} }
/**
* Represents a node in the SJDON notation.
*/
type NodeDescriptor =
TextDescriptor |
ElementDescriptor |
FunctionNode;
/**
* Represents a text-node in the SJDON notation.
*/
type TextDescriptor = string;
/**
* Represents an html-element in the SJDON notation.
*/
type ElementDescriptor = [
tag: string,
// eslint-disable-next-line @typescript-eslint/array-type
...args: (NodeDescriptor | Record<string, unknown>)[]
];
/**
* Represents a component in the SJDON notation.
*/
type FunctionNode = [
fn: (...args: any[]) => NodeDescriptor, ...args: any[]
];