extends SceneTree const E = preload("res://world/owniverse/math/exact.gd") const Math = preload("res://world/owniverse/quantity_math.gd") var checks: int = 0 var failures: int = 0 func _initialize() -> void: call_deferred("run") func check(condition: bool, message: String) -> void: checks = E.add(checks, 1) if (not condition): failures = E.add(failures, 1) push_error(message) func run() -> void: var Catalog = load("res://world/owniverse/entity_catalog.gd") check(E.eq(Math.allocate_whole({}, 10), {}), "Empty allocation") check(E.eq(Math.allocate_whole({"b": 1, "a": 1}, 1), {"a": 1, "b": 0}), "Stable lexical tie") for limit in range(30): var requests: Dictionary = {"a": E.of("3.9"), "b": E.of("9.1"), "c": E.neg(2), "d": 7} var result: Dictionary = Math.allocate_whole(requests, limit) check(E.eq(Math.sum(result), E.minimum(limit, 19)), "Conserve bounded allocation") for id in result: check(((E.eq(result[id], E.floor_value(result[id])) and E.ge(result[id], 0)) and E.le(result[id], E.floor_value(E.maximum(0, requests[id])))), "Whole bounded branch") check(E.eq(Math.normalize_distribution({"a": E.neg(1), "b": 0}), {}), "Nonpositive weights") check(E.eq(Math.normalize_distribution({"a": 2, "b": 6}), {"a": E.of("0.25"), "b": E.of("0.75")}), "Normalize weights") check(E.eq(Math.production_step([E.of("0.25"), E.of("0.1"), 2]), 20), "Common whole production step") check(E.eq(Math.production_step([]), 1), "Free production step") var target: Dictionary = {} var produced: Variant = 0 for i in 10: produced = E.add(produced, Math.accumulate_whole(target, "remainders", "a", E.of("0.1"))) check(E.eq(produced, 1), "Fractional production carries") var remainders: Dictionary = {} var totals: Dictionary = {"a": 0, "b": 0, "c": 0} for i in 30: var result: Dictionary = Math.split(remainders, "split", 1, {"a": 1, "b": 1, "c": 1}) check(E.eq(Math.sum(result), 1), "Split conserves count") for id in result: totals[id] = E.add(totals[id], result[id]) check(E.eq(totals, {"a": 10, "b": 10, "c": 10}), "Rounding debt distributes over time") produced = 0 for i in 10: produced = E.add(produced, Math.accumulate_rate(remainders, "rate", 1, E.of("0.1"))) check(E.eq(produced, 1), "Rate carries") var catalog = Catalog.new() var rows: Dictionary = root.get_node("Global").OwniverseEntities catalog.load_definitions(rows) check(E.eq(catalog.entities.size(), rows.size()), "Catalog loads all definitions") for id in catalog.entities: var entity = catalog.entities[id] check(E.eq(catalog.automatic_producers.has(entity), (E.ne(entity.product_per_year_type, ""))), "Producer index") check(E.eq(catalog.unlockable_entities.has(entity), ((not entity.unlock.is_empty()))), "Unlock index") if E.ne(entity.group_as, ""): check((catalog.groups[entity.group_as].has(id) and catalog.members(entity.group_as).has(id)), "Group index") if E.ne(entity.event_group, ""): check(catalog.event_groups[entity.event_group].has(id), "Event index") var members: Array = catalog.members("Star") members.clear() check((not catalog.members("Star").is_empty()), "Group results are independent") check(Catalog.new().entities.is_empty(), "Catalog instances are independent") for entity in catalog.entities.values(): entity.free() print(("Quantity and catalog: %d checks, %d failures" % [checks, failures])) quit((1 if failures else 0))