From 98fc39027a4a156defc1320e411116e9112e9406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 15 Dec 2019 00:52:44 +0100 Subject: [PATCH] added new placement rules to make games more challenging --- script.js | 70 ++++++++++++++++++++++++++++++++++--------------------- style.css | 20 ++++++++++++++++ 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/script.js b/script.js index ea8297c..9e98f96 100644 --- a/script.js +++ b/script.js @@ -737,6 +737,7 @@ class Board { this.buttons.randomize = addButton(x0, y0, 'Randomize'); this.buttons.restart = addButton(x0, y0 + ysp, 'Try Again', 'disabled'); this.buttons.undo = addButton(x0, y0 + ysp*2, 'Undo', 'disabled'); + this.buttons.working = addButton(x0, y0 + ysp*3, 'Working…', 'working'); const cfgy0 = 10; @@ -844,6 +845,29 @@ class Rng { arrayChoose(array) { return array[Math.floor(this.next() * array.length)]; } + + /** + * Sneak items in the given order into another array + * + * @param array - the modified array + * @param startKeepout - how many leading lements to leave untouched + * @param endKeepout - how many trailing elements to leave untouched + * @param items - items to sneak in + * @return the modified array + */ + arraySneak(array, startKeepout, endKeepout, items) { + let positions = []; + for (let i = 0; i < items.length; i++) { + positions.push(startKeepout + this.nextInt(array.length - startKeepout - endKeepout)) + } + positions.sort((a, b) => a - b); + // inject them into the array + items.forEach((pair, i) => { + array.splice(positions[i] + i, 0, pair); + }); + + return array; + } } class SettingsStorage { @@ -1044,7 +1068,7 @@ class Game { // Defer start to give browser time to render the background setTimeout(() => { - this.newGame(args.seed) + this.newGameWithLoader(args.seed) }, 50); } @@ -1407,12 +1431,12 @@ class Game { installButtonHandlers() { this.board.buttons.restart.addEventListener('click', () => { this.info("New Game with the same seed"); - this.newGame(this.rng.seed); + this.newGameWithLoader(this.rng.seed); }); this.board.buttons.randomize.addEventListener('click', () => { this.info("New Game with a random seed"); - this.newGame(+new Date); + this.newGameWithLoader(+new Date); }); this.board.buttons.btnAbout.addEventListener('click', () => { @@ -1488,6 +1512,15 @@ class Game { } } + newGameWithLoader(seed) { + this.board.buttons.working.classList.add('show'); + + setTimeout(() => { + this.newGame(seed); + this.board.buttons.working.classList.remove('show'); + }, 20); + } + newGame(seed) { if (seed !== null) { this.rng.setSeed(seed); @@ -1693,40 +1726,23 @@ class BaseOrbPlacer { toPlace.push(['salt', 'salt']); } - // these are always paired like this, and don't support salt - toPlace = toPlace.concat([ + // shuffle the pairs that have random order (i.e. not metals) + this.rng.arrayShuffle(toPlace); + + this.rng.arraySneak(toPlace, 3, 0, [ ['mors', 'vitae'], ['mors', 'vitae'], ['mors', 'vitae'], ['mors', 'vitae'], ]); - // shuffle the pairs that have random order (i.e. not metals) - this.rng.arrayShuffle(toPlace); - - // the order here is actually significant, so let's pay attention... - const metals = [ + this.rng.arraySneak(toPlace, 4, 0, [ ['lead', 'mercury'], ['tin', 'mercury'], ['iron', 'mercury'], ['copper', 'mercury'], ['silver', 'mercury'], - ]; - let mPos = []; - for (let i = 0; i < metals.length; i++) { - let x; - // find a unique position - do { - x = this.rng.nextInt(toPlace.length + i); - } while (mPos.includes(x)); - mPos.push(x) - } - mPos.sort((a, b) => a - b); - this.trace('Metal positions ', mPos); - // inject them into the array - metals.forEach((pair, i) => { - toPlace.splice(mPos[i] + i, 0, pair); - }); + ]); this.debug('Placement order (last first):', toPlace); @@ -1973,7 +1989,7 @@ class RecursiveOrbPlacer extends BaseOrbPlacer { placeOne() { this.recDepth++; - if (this.recDepth > 2000) { + if (this.recDepth > 1000) { throw new Error("Too many backtracks"); } diff --git a/style.css b/style.css index 1d2e6c4..705e8bb 100644 --- a/style.css +++ b/style.css @@ -122,6 +122,24 @@ text { stroke-width: 2px; cursor: pointer; } +.button-text.working, +.button-text.working:hover { + fill: #8d7761; + font-size: 26px; + opacity: 0; +} + +.button-text.working { + transition: opacity linear 0.2s; +} + +.cfg-no-anim .button-text.working { + transition: none; +} + +.button-text.working.show { + opacity: 1; +} .you-win { font-size: 80px; @@ -160,6 +178,8 @@ text { transform: translateY(1px); } + + .button-text.disabled, .button-text.disabled:hover, .button-text.disabled:active {