refactor: move debug related code into debug.rs

This commit is contained in:
2025-07-23 16:31:09 -05:00
parent 66b6cdf01b
commit de1a89b9b0
3 changed files with 101 additions and 81 deletions

80
src/debug.rs Normal file
View File

@@ -0,0 +1,80 @@
//! Debug rendering utilities for Pac-Man.
use crate::{
constants::{MapTile, BOARD_HEIGHT, BOARD_WIDTH},
direction::Direction,
ghosts::blinky::Blinky,
map::Map,
};
use sdl2::{pixels::Color, render::Canvas, video::Window};
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum DebugMode {
None,
Grid,
Pathfinding,
ValidPositions,
}
pub struct DebugRenderer;
impl DebugRenderer {
pub fn draw_cell(canvas: &mut Canvas<Window>, map: &Map, cell: (u32, u32), color: Color) {
let position = Map::cell_to_pixel(cell);
canvas.set_draw_color(color);
canvas
.draw_rect(sdl2::rect::Rect::new(
position.0 as i32,
position.1 as i32,
24,
24,
))
.expect("Could not draw rectangle");
}
pub fn draw_debug_grid(canvas: &mut Canvas<Window>, map: &Map, pacman_cell: (u32, u32)) {
for x in 0..BOARD_WIDTH {
for y in 0..BOARD_HEIGHT {
let tile = map.get_tile((x as i32, y as i32)).unwrap_or(MapTile::Empty);
let mut color = None;
if (x, y) == pacman_cell {
Self::draw_cell(canvas, map, (x, y), Color::CYAN);
} else {
color = match tile {
MapTile::Empty => None,
MapTile::Wall => Some(Color::BLUE),
MapTile::Pellet => Some(Color::RED),
MapTile::PowerPellet => Some(Color::MAGENTA),
MapTile::StartingPosition(_) => Some(Color::GREEN),
MapTile::Tunnel => Some(Color::CYAN),
};
}
if let Some(color) = color {
Self::draw_cell(canvas, map, (x, y), color);
}
}
}
}
pub fn draw_next_cell(canvas: &mut Canvas<Window>, map: &Map, next_cell: (u32, u32)) {
Self::draw_cell(canvas, map, next_cell, Color::YELLOW);
}
pub fn draw_valid_positions(canvas: &mut Canvas<Window>, map: &mut Map) {
let valid_positions_vec = map.get_valid_playable_positions().clone();
for &pos in &valid_positions_vec {
Self::draw_cell(canvas, map, (pos.x, pos.y), Color::RGB(255, 140, 0));
// ORANGE
}
}
pub fn draw_pathfinding(canvas: &mut Canvas<Window>, blinky: &Blinky, map: &Map) {
if let Some((path, _)) = blinky.get_path_to_target({
let (tx, ty) = blinky.get_target_tile();
(tx as u32, ty as u32)
}) {
for &(x, y) in &path {
Self::draw_cell(canvas, map, (x, y), Color::YELLOW);
}
}
}
}

View File

@@ -23,6 +23,8 @@ use crate::{
pacman::Pacman, pacman::Pacman,
}; };
use crate::debug::{DebugMode, DebugRenderer};
// Embed texture data directly into the executable // Embed texture data directly into the executable
static PACMAN_TEXTURE_DATA: &[u8] = include_bytes!("../assets/32/pacman.png"); static PACMAN_TEXTURE_DATA: &[u8] = include_bytes!("../assets/32/pacman.png");
static PELLET_TEXTURE_DATA: &[u8] = include_bytes!("../assets/24/pellet.png"); static PELLET_TEXTURE_DATA: &[u8] = include_bytes!("../assets/24/pellet.png");
@@ -38,14 +40,6 @@ static GHOST_EYES_TEXTURE_DATA: &[u8] = include_bytes!("../assets/32/ghost_eyes.
/// ///
/// This struct contains all the information necessary to run the game, including /// This struct contains all the information necessary to run the game, including
/// the canvas, textures, fonts, game objects, and the current score. /// the canvas, textures, fonts, game objects, and the current score.
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum DebugMode {
None,
Grid,
Pathfinding,
ValidPositions,
}
pub struct Game<'a> { pub struct Game<'a> {
canvas: &'a mut Canvas<Window>, canvas: &'a mut Canvas<Window>,
map_texture: Texture<'a>, map_texture: Texture<'a>,
@@ -322,88 +316,33 @@ impl Game<'_> {
self.render_ui(); self.render_ui();
// Draw the debug grid // Draw the debug grid
if self.debug_mode == DebugMode::Grid { match self.debug_mode {
for x in 0..BOARD_WIDTH { DebugMode::Grid => {
for y in 0..BOARD_HEIGHT { DebugRenderer::draw_debug_grid(
let tile = self self.canvas,
.map &self.map.borrow(),
.borrow() self.pacman.borrow().base.cell_position,
.get_tile((x as i32, y as i32)) );
.unwrap_or(MapTile::Empty); let next_cell = self.pacman.borrow().base.next_cell(None);
let mut color = None; DebugRenderer::draw_next_cell(
self.canvas,
if (x, y) == self.pacman.borrow().base.cell_position { &self.map.borrow(),
self.draw_cell((x, y), Color::CYAN); (next_cell.0 as u32, next_cell.1 as u32),
} else { );
color = match tile {
MapTile::Empty => None,
MapTile::Wall => Some(Color::BLUE),
MapTile::Pellet => Some(Color::RED),
MapTile::PowerPellet => Some(Color::MAGENTA),
MapTile::StartingPosition(_) => Some(Color::GREEN),
MapTile::Tunnel => Some(Color::CYAN),
};
}
if let Some(color) = color {
self.draw_cell((x, y), color);
}
}
} }
DebugMode::ValidPositions => {
// Draw the next cell DebugRenderer::draw_valid_positions(self.canvas, &mut self.map.borrow_mut());
let next_cell = self.pacman.borrow().base.next_cell(None);
self.draw_cell((next_cell.0 as u32, next_cell.1 as u32), Color::YELLOW);
}
// Show valid playable positions
if self.debug_mode == DebugMode::ValidPositions {
let valid_positions_vec = {
let mut map = self.map.borrow_mut();
map.get_valid_playable_positions().clone()
};
for &pos in &valid_positions_vec {
self.draw_cell((pos.x, pos.y), Color::RGB(255, 140, 0)); // ORANGE
} }
} DebugMode::Pathfinding => {
DebugRenderer::draw_pathfinding(self.canvas, &self.blinky, &self.map.borrow());
// Pathfinding debug mode
if self.debug_mode == DebugMode::Pathfinding {
// Show the current path for Blinky
if let Some((path, _)) = self.blinky.get_path_to_target({
let (tx, ty) = self.blinky.get_target_tile();
(tx as u32, ty as u32)
}) {
for &(x, y) in &path {
self.draw_cell((x, y), Color::YELLOW);
}
} }
DebugMode::None => {}
} }
// Present the canvas // Present the canvas
self.canvas.present(); self.canvas.present();
} }
/// Draws a single cell to the canvas with the given color.
///
/// # Arguments
///
/// * `cell` - The cell to draw, in grid coordinates.
/// * `color` - The color to draw the cell with.
fn draw_cell(&mut self, cell: (u32, u32), color: Color) {
let position = Map::cell_to_pixel(cell);
self.canvas.set_draw_color(color);
self.canvas
.draw_rect(sdl2::rect::Rect::new(
position.0 as i32,
position.1 as i32,
24,
24,
))
.expect("Could not draw rectangle");
}
/// Renders the user interface, including the score and lives. /// Renders the user interface, including the score and lives.
fn render_ui(&mut self) { fn render_ui(&mut self) {
let lives = 3; let lives = 3;

View File

@@ -64,6 +64,7 @@ mod helper;
mod map; mod map;
mod modulation; mod modulation;
mod pacman; mod pacman;
mod debug;
/// The main entry point of the application. /// The main entry point of the application.
/// ///