From f6f01f7536b21bdea793de78238f4deebc48572c Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 21 Sep 2022 21:36:48 +0200 Subject: Update common library. --- rules.js | 178 ++++++++++++++++++++++++++++++++++----------------------------- 1 file 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 + } +} -- cgit v1.2.3