Add comprehensive test suite for game mechanics and level handling
- Introduced `test_final_level_flow.py` to validate final level transitions and game end scenarios. - Created `test_game_over_flow.py` to ensure game over conditions trigger correctly based on rat counts. - Implemented `test_keybindings.py` to verify keybinding configurations and their context-specific actions. - Developed `test_level_editor.py` to assess level editor functionalities and layout computations. - Added `test_level_io.py` for testing level data serialization and deserialization. - Established `test_loop_logic_parity.py` to ensure consistent game state across multiple simulation runs. - Created `test_non_regression.py` to simulate game behavior and capture states for future verification. - Implemented `test_verify.py` to compare current game states against a golden master for regression detection.
This commit is contained in:
+26
-8
@@ -199,6 +199,26 @@ class KeyBindings:
|
||||
def __init__(self, game):
|
||||
self.game = game
|
||||
self.bindings = {}
|
||||
|
||||
# Explicit action mapping for static-friendly dispatch (Nim-ready)
|
||||
self.action_dispatcher = {
|
||||
"spawn_rat": self.spawn_rat,
|
||||
"spawn_new_bomb": self.spawn_new_bomb,
|
||||
"spawn_new_mine": self.spawn_new_mine,
|
||||
"spawn_new_nuclear_bomb": self.spawn_new_nuclear_bomb,
|
||||
"spawn_new_gas": self.spawn_new_gas,
|
||||
"toggle_audio": self.toggle_audio,
|
||||
"toggle_pause": self.toggle_pause,
|
||||
"toggle_full_screen": self.toggle_full_screen,
|
||||
"quit_game": self.quit_game,
|
||||
"menu_up": self.game.menu_up,
|
||||
"menu_down": self.game.menu_down,
|
||||
"menu_left": self.game.menu_left,
|
||||
"menu_right": self.game.menu_right,
|
||||
"reset_game": self.game.reset_game,
|
||||
"start_scrolling": self.start_scrolling,
|
||||
"stop_scrolling": self.stop_scrolling,
|
||||
}
|
||||
|
||||
def _binding_sections_for_action(self):
|
||||
game_end_active, game_end_reason = getattr(self.game, "game_end", (False, None))
|
||||
@@ -259,16 +279,14 @@ class KeyBindings:
|
||||
continue
|
||||
|
||||
method_name = value.split("|", 1)[0]
|
||||
# Check both self (KeyBindings) and self.game (MiceMaze)
|
||||
method = getattr(self, method_name, getattr(self.game, method_name, None))
|
||||
if callable(method):
|
||||
if method_name in self.action_dispatcher:
|
||||
validated[section_name][action] = value
|
||||
continue
|
||||
|
||||
invalid_bindings += 1
|
||||
print(
|
||||
f"[input] ignoring binding {section_name}.{action} -> {value}: "
|
||||
f"missing method {method_name}"
|
||||
f"missing method {method_name} in dispatcher"
|
||||
)
|
||||
|
||||
if invalid_bindings:
|
||||
@@ -291,13 +309,13 @@ class KeyBindings:
|
||||
|
||||
if "|" in value:
|
||||
method_name, *args = value.split("|")
|
||||
method = getattr(self, method_name, getattr(self.game, method_name, None))
|
||||
if callable(method):
|
||||
method = self.action_dispatcher.get(method_name)
|
||||
if method:
|
||||
method(*args)
|
||||
return None
|
||||
|
||||
method = getattr(self, value, getattr(self.game, value, None))
|
||||
if callable(method):
|
||||
method = self.action_dispatcher.get(value)
|
||||
if method:
|
||||
method()
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user