diff --git a/src/global/rng_utils.gd b/src/global/rng_utils.gd index 8e33ab3..5f758cd 100644 --- a/src/global/rng_utils.gd +++ b/src/global/rng_utils.gd @@ -1,11 +1,28 @@ ## Random number generator static utility class. class_name RngUtils +static var global_rng + + +static func get_global_rng() -> RandomNumberGenerator: + if global_rng == null: + set_global_rng() + return global_rng + + +static func set_global_rng() -> void: + global_rng = RandomNumberGenerator.new() + global_rng.randomize() + ## Returns bool [code]true[/code] if [param c] is greater than a random value ## between 0.0 and 1.0, bool [code]false[/code] otherwise. static func chancef(c: float) -> bool: - return c > randf() + return chancef_rng(c, get_global_rng()) + + +static func chancef_rng(c: float, rng: RandomNumberGenerator) -> bool: + return c > rng.randf() ## Returns [code]true[/code] if [param c] divided by 100 is greater than a @@ -16,15 +33,23 @@ static func chancef(c: float) -> bool: ## print("25% chance to hit") ## [/codeblock] static func chance100(c: float) -> bool: - return chancef(c / 100.0) + return chance100_rng(c, get_global_rng()) + + +static func chance100_rng(c: float, rng: RandomNumberGenerator) -> bool: + return chancef_rng(c / 100.0, rng) ## Returns [code]true[/code] if [param c] divided by 100 is greater than a ## random value between 0.0 and 1.0 at least once within [param n] number of ## tries, [code]false[/code] otherwise. static func chance100_or(c: float, n: int) -> bool: + return chance100_or_rng(c, n, get_global_rng()) + + +static func chance100_or_rng(c: float, n: int, rng: RandomNumberGenerator) -> bool: for i in n: - if chance100(c): + if chance100_rng(c, rng): return true return false @@ -32,53 +57,27 @@ static func chance100_or(c: float, n: int) -> bool: ## Returns the number of consecutive times [param c] divided by 100 is ## greater than a new random value between 0.0 and 1.0 each time. The value of ## [param c] must be less than 100. -static func chance100_seq(c: float) -> int: +static func chance100_seq(c: float) -> bool: + return chance100_seq_rng(c, get_global_rng()) + + +static func chance100_seq_rng(c: float, rng: RandomNumberGenerator) -> int: assert(c < 100) var ctr: int = 0 - while chance100(c): + while chance100_rng(c, rng): ctr += 1 return ctr -## Returns [code]true[/code] if [param c] is greater than a random value -## between 0.0 and 1.0 using the [RandomNumberGenerator] [param rng], -## [code]false[/code] otherwise. -static func chancef_rng(c: float, rng: RandomNumberGenerator) -> bool: - return c > rng.randf() - - -## Returns [code]true[/code] if [param c] divided by 100 is greater than a -## random value between 0.0 and 1.0, [code]false[/code] otherwise.[br] -## For example:[br] -## [codeblock] -## if chance100_rng(25, rng): -## print("25% chance to hit") -## [/codeblock] -static func chance100_rng(c: float, rng: RandomNumberGenerator) -> bool: - return chancef_rng(c / 100.0, rng) - - ## Returns the number of consecutive times [param c] is greater than a new random ## value between 0.0 and 100.0 when reducing [param c] by that random value ## upon each iteration. Also known as [i]meaningful chances > 100%[/i]. -static func multi_chance100(c: float) -> int: - var ctr := 0 - var total_chance: float = c - while true: - var r: float = randf() * 100 - if r < total_chance: - ctr += 1 - total_chance -= r - else: - break - return ctr + +static func multi_chance100(c: float) -> int: + return multi_chance100_rng(c, get_global_rng()) -## Returns the number of consecutive times [param c] is greater than a new random -## value between 0.0 and 100.0 when reducing [param c] by that random value -## upon each iteration, using the [RandomNumberGenerator] [param rng]. Also known -## as [i]meaningful chances > 100%[/i]. static func multi_chance100_rng(c: float, rng: RandomNumberGenerator) -> int: var ctr := 0 var total_chance: float = c diff --git a/src/tests/unit/test_debug_popup.gd b/src/tests/unit/test_debug_popup.gd new file mode 100644 index 0000000..8eb0cd6 --- /dev/null +++ b/src/tests/unit/test_debug_popup.gd @@ -0,0 +1,39 @@ +extends "res://addons/gut/test.gd" + +var called_times: int + + +func _fake_button_func(): + called_times += 1 + + +func test_debug_popup() -> void: + var debug_popup = load("res://component/debug/debug_popup.tscn").instantiate() + debug_popup.default_debug_buttons = DebugButtonCollection.new() + var fake_debug_button = DebugButton.new() + fake_debug_button.func_or_path = "_fake_button_func" + fake_debug_button.hotkey = "7" + debug_popup.default_debug_buttons.collection.append(fake_debug_button) + var sender = InputSender.new(debug_popup) + add_child_autofree(debug_popup) + + sender.action_down("toggle_debug_popup") + + await wait_seconds(0.1) + assert_eq(debug_popup.visible, true, "Visible on start busted") + + sender.key_down("7") + await wait_seconds(0.1) + assert_eq(called_times, 1, "Shortcut not registered") + + var tree: Tree = debug_popup.get_child(0) + var navigation_column: TreeItem = tree.get_root().get_next_in_tree() + assert_eq(navigation_column.get_text(0), "Navigation and functions") + var fake_debug_button_node: TreeItem = navigation_column.get_next_in_tree() + assert_eq(fake_debug_button_node.get_text(0), "[7] _fake_button_func()") + tree.set_selected(fake_debug_button_node, 0) + + await wait_seconds(0.1) + assert_eq(called_times, 2, "Button not found") + + debug_popup.queue_free() diff --git a/src/tests/unit/test_debug_popup.gd.uid b/src/tests/unit/test_debug_popup.gd.uid new file mode 100644 index 0000000..de0acd0 --- /dev/null +++ b/src/tests/unit/test_debug_popup.gd.uid @@ -0,0 +1 @@ +uid://c1cahfdh8ub41 diff --git a/src/tests/unit/test_rng_utils.gd b/src/tests/unit/test_rng_utils.gd new file mode 100644 index 0000000..31544c9 --- /dev/null +++ b/src/tests/unit/test_rng_utils.gd @@ -0,0 +1,38 @@ +extends "res://addons/gut/test.gd" + +var test_rng: RandomNumberGenerator + + +func before_each() -> void: + RngUtils.global_rng = RandomNumberGenerator.new() + RngUtils.global_rng.seed = 1234 + test_rng = RandomNumberGenerator.new() + test_rng.seed = 1234 + + +func test_chancef() -> void: + assert_eq(RngUtils.chancef(0.1), false) + + +func test_chance100() -> void: + assert_eq(RngUtils.chance100(60), true) + + +func test_chancef_rng() -> void: + assert_eq(RngUtils.chancef_rng(0.1, test_rng), false) + + +func test_chance100_rng() -> void: + assert_eq(RngUtils.chance100_rng(60, test_rng), true) + + +func test_chance100_or_rng() -> void: + assert_eq(RngUtils.chance100_or_rng(10, 5, test_rng), true) + + +func test_chance100_seq_rng() -> void: + assert_eq(RngUtils.chance100_seq_rng(80, test_rng), 5) + + +func test_multi_chance100_rng() -> void: + assert_eq(RngUtils.multi_chance100_rng(80, test_rng), 3) diff --git a/src/tests/unit/test_rng_utils.gd.uid b/src/tests/unit/test_rng_utils.gd.uid new file mode 100644 index 0000000..7024bb0 --- /dev/null +++ b/src/tests/unit/test_rng_utils.gd.uid @@ -0,0 +1 @@ +uid://d18o6a8nneg3a