From 4e4ce7c9622f6e4bce3312f0fa6785e17f4d6188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 14 Dec 2019 19:20:09 +0100 Subject: [PATCH] add some comments --- script.js | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/script.js b/script.js index 269f97c..810ac73 100644 --- a/script.js +++ b/script.js @@ -1572,6 +1572,9 @@ class Game { } } +/** + * Base class for orb placer. + */ class BaseOrbPlacer { constructor(game, template) { this.template = template; @@ -1581,6 +1584,12 @@ class BaseOrbPlacer { this.board = game.board; } + /** + * Place an orb. The position must be inside template and free. + * + * @param n - position + * @param symbol - symbol to place + */ placeOrb(n, symbol) { if (!this.templateMap[n]) { throw Error(`Position ${n} not allowed by template`); @@ -1592,6 +1601,11 @@ class BaseOrbPlacer { this.board.grid[n] = symbol; } + /** + * Remove an orb, if any. + * + * @param n - position + */ removeOrb(n) { let old = this.board.grid[n]; this.board.grid[n] = null; @@ -1599,10 +1613,12 @@ class BaseOrbPlacer { return old; } + /** Check if a cell is available for selection - 3 free slots */ isAvailable(n) { return this.board.isAvailable(n); } + /** Get cell info by number */ getCellInfo(n) { return this.board.getCellInfo(n); } @@ -1627,6 +1643,13 @@ class BaseOrbPlacer { this.game.error(...args); } + /** + * Build a list of orbs in the right order. + * They are always grouped in matching pairs, and metals are always in + * the correct reaction order. + * + * @return {string[]} + */ buildPlacementList() { let toPlace = [ ['air', 'air'], @@ -1713,7 +1736,9 @@ class BaseOrbPlacer { }, []); } - + /** + * Run the placement logic. + */ place() { this.board.removeAllOrbs(); this.solution = []; @@ -1747,7 +1772,8 @@ class BaseOrbPlacer { this.placeOrb(60, 'gold'); this.solution.push(['gold', 60]); - let rv = this.doPlace(); + let toPlace = this.buildPlacementList(); + let rv = this.doPlace(toPlace); let solution = this.solution; @@ -1765,12 +1791,42 @@ class BaseOrbPlacer { return rv; } - doPlace() { + /** + * Perform the orbs placement. + * + * Orb symbols to place are given as an argument. + * + * The layout template is in `this.template`, also `this.templateMap` as an array + * with indices 0-121 containing true/false to indicate template membership. + * + * `this.outsideTemplate` is a list of cell indices that are not in the template. + * + * this.solution is an array to populate with orb placements in the format [n, symbol]. + * + * The board is cleared now. When the function ends, the board should contain + * the new layout (as symbol name strings) + * + * After placing each orb, make sure to call `this.solution.push([symbol, index])`; + * in case of backtracking, pop it again. + * + * Return object to return to parent; 'solution' will be added automatically. + */ + doPlace(toPlace) { throw new Error("Not implemented"); } } +/** + * Orb placement algorithm that starts in the center and places orbs in rings, with some + * small jitter allowed. + */ class RadialOrbPlacer extends BaseOrbPlacer { + /** + * Find a candidate cell + * + * @param {number[]|null} except - indices to exclude + * @return {number} + */ findBestCandidate(except = null) { let candidates = []; for (let n of this.template) { @@ -1810,6 +1866,12 @@ class RadialOrbPlacer extends BaseOrbPlacer { return false; } + /** + * Find index for next placement + * + * @param {number[]|null} except - indices to exclude + * @return {number} - index + */ findAvailableIndex(except = null) { const n = this.findBestCandidate(except); if (n !== false) return n; @@ -1846,9 +1908,8 @@ class RadialOrbPlacer extends BaseOrbPlacer { throw Error("Failed to find available board tile."); } - doPlace() { + doPlace(toPlace) { this.tilesAdded = 0; - const toPlace = this.buildPlacementList(); while (toPlace.length > 0) { this.trace('placing a pair.');