extends "res://tests/test_case.gd" # Task 6.5. "The server cycles arenas" has to be an assertable claim rather # than an observation about luck, which is why sequential rotation is a pure # function of the completed-match count. func test_sequential_rotation_visits_every_arena_before_repeating() -> void: var paths := ArenaRegistry.rotation_paths() assert_true(paths.size() >= 2, "rotation needs at least two arenas to mean anything") var seen := {} for i in paths.size(): seen[ArenaRegistry.path_for_match(i, "sequential")] = true assert_eq(seen.size(), paths.size(), "every rotation arena appears in the first cycle") func test_sequential_rotation_wraps_rather_than_running_out() -> void: var paths := ArenaRegistry.rotation_paths() var first: String = ArenaRegistry.path_for_match(0, "sequential") var wrapped: String = ArenaRegistry.path_for_match(paths.size(), "sequential") assert_eq(wrapped, first, "match N wraps back to the first arena") # And a long-running server must not drift or fault at large counts. assert_eq(ArenaRegistry.path_for_match(paths.size() * 1000, "sequential"), first, "still correct after a thousand cycles") func test_consecutive_matches_are_never_the_same_arena_in_sequential_mode() -> void: # The point of rotation is that players do not play the same arena twice in # a row; wrapping must not produce a repeat at the seam either. var paths := ArenaRegistry.rotation_paths() for i in paths.size() * 2: var current: String = ArenaRegistry.path_for_match(i, "sequential") var next: String = ArenaRegistry.path_for_match(i + 1, "sequential") assert_true(current != next, "match %d and %d differ" % [i, i + 1]) func test_rotation_never_offers_an_arena_bots_cannot_score_in() -> void: # Elevated-goal variants are Free-Play-only until a checkpoint trained on # them is promoted. A server rotating onto one would hand every bot-filled # slot an arena it cannot score in. var rotation := ArenaRegistry.rotation_paths() for arena in ArenaRegistry.ARENAS: if not arena["random"]: assert_true(not (arena["path"] in rotation), "%s is excluded from rotation" % arena["name"]) assert_true(rotation.size() > 0, "and something is left to rotate through") func test_random_mode_stays_inside_the_rotation_set() -> void: for i in 50: var path: String = ArenaRegistry.path_for_match(i, "random") assert_true(path in ArenaRegistry.rotation_paths(), "random picks are still rotation-eligible") func test_an_unknown_mode_falls_back_to_sequential_rather_than_faulting() -> void: # The CLI already rejects an undeclared mode, so this is the belt to that's # braces — but a server must not crash between matches over a string. assert_eq( ArenaRegistry.path_for_match(1, "spiral"), ArenaRegistry.path_for_match(1, "sequential"), "an unrecognised mode behaves as sequential" )