summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2022-09-21 21:36:48 +0200
committerTor Andersson <tor@ccxvii.net>2023-02-18 11:54:52 +0100
commitf6f01f7536b21bdea793de78238f4deebc48572c (patch)
tree69a566a30b67ac8851a983b869d1151c059546cc /rules.js
parent4d7494341aaf970e599d1eb6f058bf9a077ac972 (diff)
downloadwilderness-war-f6f01f7536b21bdea793de78238f4deebc48572c.tar.gz
Update common library.
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js178
1 files changed, 97 insertions, 81 deletions
diff --git a/rules.js b/rules.js
index 13aae8b..482855c 100644
--- a/rules.js
+++ b/rules.js
@@ -260,62 +260,10 @@ function clamp(x, min, max) {
return Math.min(Math.max(x, min), max)
}
-// Sorted array treated as Set (for JSON)
-function set_index(set, item) {
- let a = 0
- let b = set.length - 1
- while (a <= b) {
- let m = (a + b) >> 1
- let x = set[m]
- if (item < x)
- b = m - 1
- else if (item > x)
- a = m + 1
- else
- return m
- }
- return -1
-}
-
-function validate_set(set) {
- for (let i = 1; i < set.length; ++i)
- if (set[i] < set[i-1])
- throw new Error("unsorted set: " + set)
-}
-
-function set_has(set, item) {
- validate_set(set)
- return set_index(set, item) >= 0
-}
-
-function set_add(set, item) {
- validate_set(set)
- let a = 0
- let b = set.length - 1
- while (a <= b) {
- let m = (a + b) >> 1
- let x = set[m]
- if (item < x)
- b = m - 1
- else if (item > x)
- a = m + 1
- else
- return
- }
- set.splice(a, 0, item)
-}
-
-function set_delete(set, item) {
- validate_set(set)
- let i = set_index(set, item)
- if (i >= 0)
- set.splice(i, 1)
-}
-
function remove_from_array(array, item) {
let i = array.indexOf(item)
if (i >= 0)
- array.splice(i, 1)
+ array_remove(array, i)
}
function logbr() {
@@ -2984,7 +2932,7 @@ function resume_move() {
if (game.move.used < 0) {
if (is_enemy_card_available(FOUL_WEATHER) && !enemy_player.pass_fw) {
if (game.options.retroactive) {
- game.retro_foul_weather = deep_copy(game)
+ game.retro_foul_weather = object_copy(game)
} else {
set_active_enemy()
game.state = 'foul_weather'
@@ -3487,7 +3435,7 @@ function goto_retroactive_foul_weather() {
let state_start = game.retro_foul_weather
delete game.retro_foul_weather
- let state_next = deep_copy(game)
+ let state_next = object_copy(game)
load_game_state(state_start)
set_active_enemy()
@@ -9557,31 +9505,6 @@ function clear_undo() {
game.undo.length = 0
}
-function deep_copy(original) {
- if (Array.isArray(original)) {
- let n = original.length
- let copy = new Array(n)
- for (let i = 0; i < n; ++i) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = deep_copy(v)
- else
- copy[i] = v
- }
- return copy
- } else {
- let copy = {}
- for (let i in original) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = deep_copy(v)
- else
- copy[i] = v
- }
- return copy
- }
-}
-
function push_undo() {
let copy = {}
for (let k in game) {
@@ -9589,7 +9512,7 @@ function push_undo() {
if (k === "undo") continue
else if (k === "log") v = v.length
else if (k === "retro_foul_weather") v = 1
- else if (typeof v === "object" && v !== null) v = deep_copy(v)
+ else if (typeof v === "object" && v !== null) v = object_copy(v)
copy[k] = v
}
game.undo.push(copy)
@@ -9792,3 +9715,96 @@ exports.view = function(state, current) {
return view
}
+
+// === COMMON LIBRARY ===
+
+// remove item at index (faster than splice)
+function array_remove(array, index) {
+ let n = array.length
+ for (let i = index + 1; i < n; ++i)
+ array[i - 1] = array[i]
+ array.length = n - 1
+ return array
+}
+
+// insert item at index (faster than splice)
+function array_insert(array, index, item) {
+ for (let i = array.length; i > index; --i)
+ array[i] = array[i - 1]
+ array[index] = item
+ return array
+}
+
+function set_has(set, item) {
+ let a = 0
+ let b = set.length - 1
+ while (a <= b) {
+ let m = (a + b) >> 1
+ let x = set[m]
+ if (item < x)
+ b = m - 1
+ else if (item > x)
+ a = m + 1
+ else
+ return true
+ }
+ return false
+}
+
+function set_add(set, item) {
+ let a = 0
+ let b = set.length - 1
+ while (a <= b) {
+ let m = (a + b) >> 1
+ let x = set[m]
+ if (item < x)
+ b = m - 1
+ else if (item > x)
+ a = m + 1
+ else
+ return set
+ }
+ return array_insert(set, a, item)
+}
+
+function set_delete(set, item) {
+ let a = 0
+ let b = set.length - 1
+ while (a <= b) {
+ let m = (a + b) >> 1
+ let x = set[m]
+ if (item < x)
+ b = m - 1
+ else if (item > x)
+ a = m + 1
+ else
+ return array_remove(set, m)
+ }
+ return set
+}
+
+// Fast deep copy for objects without cycles
+function object_copy(original) {
+ if (Array.isArray(original)) {
+ let n = original.length
+ let copy = new Array(n)
+ for (let i = 0; i < n; ++i) {
+ let v = original[i]
+ if (typeof v === "object" && v !== null)
+ copy[i] = object_copy(v)
+ else
+ copy[i] = v
+ }
+ return copy
+ } else {
+ let copy = {}
+ for (let i in original) {
+ let v = original[i]
+ if (typeof v === "object" && v !== null)
+ copy[i] = object_copy(v)
+ else
+ copy[i] = v
+ }
+ return copy
+ }
+}