DynamicAbstractionSystem/core/simulation_engine.py
Sam 8c8d8f7925
Some checks failed
Build Simulation and Test / Run All Tests (push) Failing after 40s
Add cell count display to sprint debug info and adjust energy cost calculation
2025-06-18 18:37:11 -05:00

156 lines
5.8 KiB
Python

import pygame
import time
import random
import sys
from world.base.brain import CellBrain, FlexibleNeuralNetwork
from world.world import World, Position, Rotation
from world.objects import FoodObject, DefaultCell
from world.simulation_interface import Camera
from config.constants import *
from core.input_handler import InputHandler
from core.renderer import Renderer
from ui.hud import HUD
class SimulationEngine:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), vsync=1)
pygame.display.set_caption("Dynamic Abstraction System Testing")
self.clock = pygame.time.Clock()
self.camera = Camera(SCREEN_WIDTH, SCREEN_HEIGHT, RENDER_BUFFER)
self.last_tick_time = time.perf_counter()
self.last_tps_time = time.perf_counter()
self.tick_counter = 0
self.actual_tps = 0
self.total_ticks = 0
self.world = self._setup_world()
self.input_handler = InputHandler(self.camera, self.world)
self.renderer = Renderer(self.screen)
self.hud = HUD()
self.running = True
@staticmethod
def _setup_world():
world = World(CELL_SIZE, (CELL_SIZE * GRID_WIDTH, CELL_SIZE * GRID_HEIGHT))
random.seed(RANDOM_SEED)
half_width = GRID_WIDTH * CELL_SIZE // 2
half_height = GRID_HEIGHT * CELL_SIZE // 2
if FOOD_SPAWNING:
for _ in range(FOOD_OBJECTS_COUNT):
x = random.randint(-half_width, half_width)
y = random.randint(-half_height, half_height)
world.add_object(FoodObject(Position(x=x, y=y)))
for _ in range(300):
new_cell = DefaultCell(Position(x=random.randint(-half_width, half_width), y=random.randint(-half_height, half_height)), Rotation(angle=0))
new_cell.behavioral_model = new_cell.behavioral_model.mutate(3)
world.add_object(new_cell)
return world
def _count_cells(self):
count = 0
for entity in self.world.get_objects():
if isinstance(entity, DefaultCell):
count += 1
return count
def run(self):
while self.running:
self._handle_frame()
pygame.quit()
sys.exit()
def _handle_frame(self):
deltatime = self.clock.get_time() / 1000.0
tick_interval = 1.0 / self.input_handler.tps
# Handle events
events = pygame.event.get()
self.running = self.input_handler.handle_events(events, self.hud.manager)
if self.input_handler.sprint_mode:
# Sprint mode: run as many ticks as possible, skip rendering
current_time = time.perf_counter()
while True:
self.input_handler.update_selected_objects()
self.world.tick_all()
self.tick_counter += 1
self.total_ticks += 1
# Optionally break after some time to allow event processing
if time.perf_counter() - current_time > 0.05: # ~50ms per batch
break
# Update TPS every second
if time.perf_counter() - self.last_tps_time >= 1.0:
self.actual_tps = self.tick_counter
self.tick_counter = 0
self.last_tps_time = time.perf_counter()
# No rendering or camera update
self.renderer.clear_screen()
cell_count = self._count_cells()
self.hud.render_sprint_debug(self.screen, self.actual_tps, self.total_ticks, cell_count)
pygame.display.flip()
self.clock.tick(MAX_FPS)
return
if not self.input_handler.is_paused:
current_time = time.perf_counter()
while current_time - self.last_tick_time >= tick_interval:
self.last_tick_time += tick_interval
self.tick_counter += 1
self.total_ticks += 1
self.input_handler.update_selected_objects()
self.world.tick_all()
self.hud.manager.update(deltatime)
if current_time - self.last_tps_time >= 1.0:
self.actual_tps = self.tick_counter
self.tick_counter = 0
self.last_tps_time += 1.0
else:
self.last_tick_time = time.perf_counter()
self.last_tps_time = time.perf_counter()
self.hud.manager.draw_ui(self.screen)
self._update(deltatime)
self._render()
def _update(self, deltatime):
keys = pygame.key.get_pressed()
self.input_handler.update_camera(keys, deltatime)
def _render(self):
self.renderer.clear_screen()
self.renderer.draw_grid(self.camera, self.input_handler.show_grid)
self.renderer.render_world(self.world, self.camera)
self.renderer.render_interaction_radius(self.world, self.camera, self.input_handler.selected_objects, self.input_handler.show_interaction_radius)
self.renderer.render_selection_rectangle(self.input_handler.get_selection_rect())
self.renderer.render_selected_objects_outline(self.input_handler.selected_objects, self.camera)
self.hud.render_mouse_position(self.screen, self.camera)
self.hud.render_fps(self.screen, self.clock)
self.hud.render_tps(self.screen, self.actual_tps)
self.hud.render_tick_count(self.screen, self.total_ticks)
self.hud.render_selected_objects_info(self.screen, self.input_handler.selected_objects)
self.hud.render_legend(self.screen, self.input_handler.show_legend)
self.hud.render_pause_indicator(self.screen, self.input_handler.is_paused)
if self.input_handler.selected_objects:
self.hud.render_neural_network_visualization(self.screen, self.input_handler.selected_objects[0])
pygame.display.flip()
self.clock.tick(MAX_FPS)