From 5b7be9c3b28701e3f62d56547345c226b5d64390 Mon Sep 17 00:00:00 2001 From: Nicolas Paul Date: Mon, 18 Mar 2024 08:55:45 +0100 Subject: Add stats calculation within the game loop This patch changes the behavior of the calculation loop of a board (nextState) to keep track of the changes that happened during the round (number of cells that died or were born in a given team). These stats may be accessed by called the getStats() method on a World instance, which returns a !Stats object: const world = Life2.World(...); // ... const stats = world.getStats(); displayStats(stats); Close: https://github.com/nc0fr/life2/issues/8 Signed-off-by: Nicolas Paul --- life2/game/index.js | 2 +- life2/game/world.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/life2/game/index.js b/life2/game/index.js index b8e8f9c..5d9277e 100644 --- a/life2/game/index.js +++ b/life2/game/index.js @@ -25,4 +25,4 @@ export {Board, Grid} from './board'; export {Cell} from './cell'; export {Rule, RuleFunction} from './rule'; export {RulesManager} from './rules_manager'; -export {World} from './world'; +export {Stats, World} from './world'; diff --git a/life2/game/world.js b/life2/game/world.js index b9c52e0..d6981dc 100644 --- a/life2/game/world.js +++ b/life2/game/world.js @@ -29,6 +29,17 @@ import {Cell} from './cell'; import {Rule} from './rule'; import {RulesManager} from './rules_manager'; +/** + * Stats about a board in general, and a state in particular. + * @typedef {Object} Stats + * @property {number} birthACount The number of cells that became TEAM_A. + * @property {number} deathACount The number of cells from TEAM_A that died. + * @property {number} birthBCount The number of cells that became TEAM_B. + * @property {number} deathBCount The number of cells from TEAM_B that died. + * @const + */ +export let Stats; + /** * The World class is the main interface to interact with the game state in * real-time without coupling the game's internal state to external @@ -52,6 +63,28 @@ export class World { * @type {!RulesManager} */ this.rules = new RulesManager(rules); + + // Stats + /** + * The amount of cells from TEAM_A that died in the last game iteration. + * @type {number} + */ + this.deathACount_ = 0; + /** + * The amount of cells from TEAM_B that died in the last game iteration. + * @type {number} + */ + this.deathBCount_ = 0; + /** + * The amount of cells that became from TEAM_A in the last game iteration. + * @type {number} + */ + this.birthACount_ = 0; + /** + * The amount of cells that became TEAM_A in the last game iteration. + * @type {number} + */ + this.birthBCount_ = 0; } /** @@ -99,10 +132,35 @@ export class World { const states = rules.map((rule) => rule.execute(cell, neighbors)) .filter((state) => state != null); - newGrid[x][y] = this.reduceStates_(states); + const newCell = this.reduceStates_(states); + + if (newCell === Cell.EMPTY && cell === Cell.TEAM_A) { + this.deathACount_ += 1; + } else if (newCell === Cell.EMPTY && cell === Cell.TEAM_B) { + this.deathBCount_ += 1; + } else if (newCell === Cell.TEAM_A && cell !== Cell.TEAM_A) { + this.birthACount_ += 1; + } else if (newCell === Cell.TEAM_B && cell !== Cell.TEAM_B) { + this.birthBCount_ += 1; + } + + newGrid[x][y] = newCell; } } this.board.setGrid(newGrid); } + + /** + * Returns the stats of the world and of the last nextState(). + * @return {!Stats} + */ + getStats() { + return { + birthACount: this.birthACount_, + deathACount: this.deathACount_, + birthBCount: this.birthBCount_, + deathBCount: this.deathBCount_, + }; + } } -- cgit v1.2.3