From 021a611df2021aef2191b9a4cae0a3ac47286aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Wo=C5=BAniak?= Date: Thu, 3 Oct 2024 10:43:04 +0200 Subject: [PATCH] Working maze --- maze/src/lib.rs | 19 ++++++++++ src/apps/maze_game.rs | 87 +++++++++++++++++++++++++++++-------------- src/epaper.rs | 6 +++ src/main.rs | 1 + 4 files changed, 85 insertions(+), 28 deletions(-) diff --git a/maze/src/lib.rs b/maze/src/lib.rs index 0b2caff..4b983ea 100644 --- a/maze/src/lib.rs +++ b/maze/src/lib.rs @@ -613,6 +613,25 @@ impl BinaryMapVisitor(b: &[MazePart], f: &mut impl Write) { + use MazePart::Passage as P; + use MazePart::Wall as W; + use MazePart::*; + + write!(f, "\n").unwrap(); + for y in 0..Y { + for x in 0..X { + let c = match b[y * X + x] { + P => '.', + W => '#', + Noop => '?', + Player => 'O', + }; + write!(f, "{c}").unwrap(); + } + write!(f, "\n").unwrap(); + } +} #[derive(Debug, Clone, Copy, PartialEq)] pub enum MazePart { diff --git a/src/apps/maze_game.rs b/src/apps/maze_game.rs index bb013ab..11a1c49 100644 --- a/src/apps/maze_game.rs +++ b/src/apps/maze_game.rs @@ -1,15 +1,15 @@ use epd_waveshare::color::Color; -use maze::{AsciiBroad, BinaryMapVisitor, Direction}; +use maze::{binary_to_ascii_broad, BinaryMapVisitor, Direction, MazePart}; use crate::Button; use super::*; -pub const MAZE_WIDTH: usize = 42; -pub const MAZE_HEIGHT: usize = 42; +pub const MAZE_WIDTH: usize = 25; +pub const MAZE_HEIGHT: usize = 25; pub struct MazeGame { - map: maze::BinaryMap, + map: maze::BinaryMap, player: Point, old_player: Option, } @@ -27,6 +27,7 @@ impl MazeGame { impl MazeGame { const X_OFFSET: i32 = 4; const Y_OFFSET: i32 = 4; + const CELL_SIZE: i32 = 6; fn player_pos(&self) -> (u16, u16) { (self.player.x as u16, self.player.y as u16) @@ -34,21 +35,27 @@ impl MazeGame { fn draw_walls(&self, ctx: &mut Context) { let wall_style = PrimitiveStyleBuilder::new() - .stroke_color(Color::Black) - .stroke_width(3) .fill_color(Color::Black) .build(); + let passage_style = PrimitiveStyleBuilder::new() + .fill_color(Color::White) + .build(); - for x in 0..MAZE_WIDTH { - for y in 0..MAZE_HEIGHT { - if self.map.at(x as u16, y as u16) == maze::MazePart::Wall { - Rectangle::new( - Point::new(x as i32 * Self::X_OFFSET, y as i32 * Self::Y_OFFSET), - Size::new(3, 3), - ) - .draw_styled(&wall_style, &mut ctx.epaper.display) - .unwrap(); - } + for y in 0..MAZE_HEIGHT { + for x in 0..MAZE_WIDTH { + let style = match self.map.at(x as u16, y as u16) { + maze::MazePart::Wall => &wall_style, + _ => &passage_style, + }; + Rectangle::new( + Point::new( + (x as i32 * Self::CELL_SIZE) + Self::X_OFFSET, + (y as i32 * Self::CELL_SIZE) + Self::Y_OFFSET, + ), + Size::new(Self::CELL_SIZE as u32, Self::CELL_SIZE as u32), + ) + .draw_styled(style, &mut ctx.epaper.display) + .unwrap(); } } } @@ -62,29 +69,53 @@ impl MazeGame { Rectangle::new( Point::new( - self.player.x * Self::X_OFFSET, - self.player.y * Self::Y_OFFSET, + (self.player.x * Self::CELL_SIZE) + Self::X_OFFSET + 1, + (self.player.y * Self::CELL_SIZE) + Self::Y_OFFSET + 1, ), - Size::new(1, 1), + Size::new(4, 4), ) .draw_styled(&player_style, &mut ctx.epaper.display) .unwrap(); } + + fn generate_map(&mut self, trng: &mut Trng) { + let mut grid = maze::Grid::<12, 12, 144>::new(); + maze::RecursiveDivision.generate(&mut grid, trng); + BinaryMapVisitor.format(&mut grid, &mut self.map.0); + for x in 0..MAZE_WIDTH { + let part = &mut self.map.0[(MAZE_WIDTH + x) as usize]; + if *part != MazePart::Wall { + break; + } + + *part = MazePart::Passage; + } + for x in (0..MAZE_WIDTH).into_iter().rev() { + let part = &mut self.map.0[((MAZE_WIDTH * (MAZE_HEIGHT - 2)) + x) as usize]; + if *part != MazePart::Wall { + break; + } + + *part = MazePart::Passage; + } + + let mut result = heapless::String::<4_000>::new(); + // AsciiBroad.format(&grid, &mut result); + binary_to_ascii_broad::(&self.map.0, &mut result); + println!("{result}"); + } } impl App for MazeGame { fn start(&mut self, trng: &mut Trng) { - let mut grid = maze::Grid::<20, 20, 400>::new(); - maze::RecursiveDivision.generate(&mut grid, trng); - BinaryMapVisitor.format(&mut grid, &mut self.map.0); - - let mut result = heapless::String::<500>::new(); - AsciiBroad.format(&grid, &mut result); - println!("{result}"); + self.generate_map(trng); } fn draw(&self, ctx: &mut Context) { - let Some(old) = &self.old_player else { + self.draw_walls(ctx); + self.draw_player(ctx); + // FIXME: Partial update + /*let Some(old) = &self.old_player else { self.draw_walls(ctx); self.draw_player(ctx); return; @@ -97,7 +128,7 @@ impl App for MazeGame { }, &[Color::White as u8], ); - self.draw_player(ctx); + self.draw_player(ctx);*/ } fn update(&mut self, ctx: &mut Context) -> Option { diff --git a/src/epaper.rs b/src/epaper.rs index 967d7fe..76cb484 100644 --- a/src/epaper.rs +++ b/src/epaper.rs @@ -166,6 +166,12 @@ impl<'d> Epaper<'d> { let _ = self.driver.sleep(&mut self.spi, &mut self.delay); } + pub fn clear_frame(&mut self) { + self.driver + .clear_frame(&mut self.spi, &mut self.delay) + .unwrap(); + } + pub fn partial_update(&mut self, pos: Point, size: Size, buffer: &[u8]) { let _ = self.driver.update_partial_frame( &mut self.spi, diff --git a/src/main.rs b/src/main.rs index d47f79f..399c585 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,6 +94,7 @@ fn main() -> ! { loop { ctx.button_pressed = kbd.pressed(); if ctx.button_pressed.is_some() { + ctx.epaper.clear_frame(); log::info!("Wake up!"); app.update_and_draw(&mut ctx, &mut trng); }