summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Paul <n@nc0.fr>2024-03-04 10:47:07 +0100
committerNicolas Paul <n@nc0.fr>2024-03-04 10:47:07 +0100
commit986536880091d3952fd5d153f04afde0a10f06a0 (patch)
treea5584a5e782c632f87ef35285f64a20a4e49c102
parent716bebd16b96cfa3c7a0623729ea20794794a4ed (diff)
Add World entry point
The World class is the entrypoint of the simulation program, where all cells lives and states are calculated. Signed-off-by: Nicolas Paul <n@nc0.fr>
-rw-r--r--life2/simulator/src/game/world.js121
-rw-r--r--life2/simulator/src/index.js7
-rw-r--r--life2/simulator/src/style.css0
3 files changed, 121 insertions, 7 deletions
diff --git a/life2/simulator/src/game/world.js b/life2/simulator/src/game/world.js
new file mode 100644
index 0000000..c22cb49
--- /dev/null
+++ b/life2/simulator/src/game/world.js
@@ -0,0 +1,121 @@
+// Copyright (c) 2024 The Life 2 Authors. All rights reserved.
+
+/**
+ * The possible states of a cell in the world.
+ * @readonly
+ * @enum {string}
+ */
+export const CELL_STATES = {
+ /** The cell is empty, possible because it never was filled or it died. */
+ EMPTY: ".",
+ /** The cell is occupied by a member of team A. */
+ TEAM_A: "a",
+ /** The cell is occupied by a member of team B. */
+ TEAM_B: "b",
+ /** The cell is a barrier, and it cannot be occupied by any entity,
+ * nor can it be modified by rules. */
+ BARRIER: "#",
+};
+
+/**
+ * A board is an array of strings, where each string represents a row of the
+ * board, and each character in the string represents a cell in the row.
+ * @typedef {Array<CELL_STATES>} Board
+ */
+
+/**
+ * The representation of the world, where all the entities live, and where the
+ * simulation takes place.
+ */
+export class World {
+ /**
+ * Create a new world with the given width and height.
+ * @constructor
+ * @param {number} width - The width of the world.
+ * @param {number} height - The height of the world.
+ */
+ constructor(width, height) {
+ // TODO(nc0) Support different types of boards, not just 2D
+
+ /**
+ * The width of the world board.
+ * @type {number}
+ * @readonly
+ */
+ this.width = width;
+ /**
+ * The height of the world board.
+ * @type {number}
+ * @readonly
+ */
+ this.height = height;
+ /**
+ * The board of the world, where all the entities live.
+ * @type {Board}
+ * @private
+ */
+ this.board = this.newBoard(width, height);
+ }
+
+ /**
+ * Create a new board with the given width and height, initializing all
+ * the cells to be empty.
+ * @param {number} width - The width of the board.
+ * @param {number} height - The height of the board.
+ * @returns {Board} The new board.
+ */
+ newBoard(width, height) {
+ return new Array(width).fill(CELL_STATES.EMPTY.repeat(height));
+ }
+
+ /**
+ * Returns the cell at the given coordinates.
+ * @param {number} x - The x coordinate of the cell.
+ * @param {number} y - The y coordinate of the cell.
+ * @returns {CELL_STATES | null} The cell at the given coordinates,
+ * or null if the coordinates are out of bounds.
+ */
+ getCell(x, y) {
+ if (x < 0 || x > this.width ||
+ y < 0 || y > this.height) return null;
+
+ return this.board[x][y];
+ }
+
+ /**
+ * Returns the cells that are adjacent to the given coordinates.
+ * @param {number} x - The x coordinate of the cell.
+ * @param {number} y - The y coordinate of the cell.
+ * @returns {Array<(number, number)>} The cells that are adjacent to the given
+ * coordinates.
+ */
+ getNeighbors(x, y) {
+ // TODO(nc0): Avoid hardcoding the 8 neighbors, check the bounds, ...
+ return [(x - 1, y - 1), (x, y - 1), (x + 1, y - 1),
+ (x - 1, y), /* (x, y) */ (x + 1, y),
+ (x - 1, y + 1), (x, y + 1), (x + 1, y + 1)]
+ .filter((x, y) => this.getCell(x, y) !== null);
+ }
+
+ /**
+ *
+ */
+ nextState() {
+ // TODO(nc0): Implement various rules for the next state
+ const newBoard = this.newBoard(this.width, this.height);
+
+ for (let x = 0; x < this.width; x++) {
+ for (let y = 0; y < this.height; y++) {
+ const cell = this.getCell(x, y);
+ const neighbors = this.getNeighbors(x, y);
+ neighbors;
+
+ // Apply the rules to the cell and its neighbors
+ // and update the new board
+ newBoard[x][y] = cell;
+ }
+ }
+
+ this.board = newBoard;
+ }
+}
diff --git a/life2/simulator/src/index.js b/life2/simulator/src/index.js
deleted file mode 100644
index 07b6a60..0000000
--- a/life2/simulator/src/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<title>Life 2 Simulator</title>
-<script src="./life2.js"></script>
-<header></header>
-<main></main>
-<aside></aside>
-<footer></footer>
diff --git a/life2/simulator/src/style.css b/life2/simulator/src/style.css
deleted file mode 100644
index e69de29..0000000
--- a/life2/simulator/src/style.css
+++ /dev/null