From 0421a580876b0a3bc7a3463ee3070315a64778fd Mon Sep 17 00:00:00 2001 From: LittleGuest <2190975784@qq.com> Date: Tue, 14 May 2024 22:26:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A7=86=E9=87=8E=E6=9B=B4?= =?UTF-8?q?=E6=96=B0bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cube/src/lib.rs | 1 + cube/src/maze.rs | 43 ++++++++++++++++++---- cube/src/sokoban.rs | 90 ++++++++++++++++++++++++++++----------------- 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/cube/src/lib.rs b/cube/src/lib.rs index 5b76920..c3999a7 100755 --- a/cube/src/lib.rs +++ b/cube/src/lib.rs @@ -1,6 +1,7 @@ #![no_std] #![no_main] #![feature(slice_flatten)] +#![feature(extract_if)] #![allow(unused)] use core::{mem::MaybeUninit, ops::RangeBounds}; diff --git a/cube/src/maze.rs b/cube/src/maze.rs index 99cdb0f..81f0199 100755 --- a/cube/src/maze.rs +++ b/cube/src/maze.rs @@ -38,7 +38,7 @@ impl Maze { // 设置一个初始视野坐标 let vpx = { - if player.pos.x - 3 <= 0 { + if player.pos.x - 3 <= 0 || width < 8 { 0 } else if player.pos.x + 5 >= width as i32 { player.pos.x - 8 + width as i32 - player.pos.x @@ -47,7 +47,7 @@ impl Maze { } }; let vpy = { - if player.pos.y - 3 <= 0 { + if player.pos.y - 3 <= 0 || height < 8 { 0 } else if player.pos.y + 5 >= height as i32 { player.pos.y - 8 + height as i32 - player.pos.y @@ -142,9 +142,29 @@ impl Maze { /// 将对应的地图数据复制给视野 fn copy_map_to_vision(&mut self) { let Position { x, y } = self.vision.pos; - for (iy, y) in (y..(y + 8)).enumerate() { - for (ix, x) in (x..(x + 8)).enumerate() { - self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + if self.map.width < 8 && self.map.height < 8 { + for (iy, y) in (y..self.map.height as i32).enumerate() { + for (ix, x) in (x..self.map.width as i32).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } + } + } else if self.map.width < 8 { + for (iy, y) in (y..(y + 8)).enumerate() { + for (ix, x) in (x..self.map.width as i32).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } + } + } else if self.map.height < 8 { + for (iy, y) in (y..self.map.height as i32).enumerate() { + for (ix, x) in (x..(x + 8)).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } + } + } else { + for (iy, y) in (y..(y + 8)).enumerate() { + for (ix, x) in (x..(x + 8)).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } } } } @@ -152,8 +172,17 @@ impl Maze { /// 改变视野位置 fn update_vision(&mut self, app: &mut App) { let Position { x, y } = self.vision.next_pos(app); - let overlapping = - x < 0 || y < 0 || x >= self.map.width as i32 - 7 || y >= self.map.height as i32 - 7; + let overlapping = { + if self.map.width < 8 && self.map.height < 8 { + true + } else if self.map.width < 8 { + x < 0 || y < 0 || x > self.map.width as i32 - 7 || y >= self.map.height as i32 - 7 + } else if self.map.height < 8 { + x < 0 || y < 0 || x >= self.map.width as i32 - 7 || y > self.map.height as i32 - 7 + } else { + x < 0 || y < 0 || x >= self.map.width as i32 - 7 || y >= self.map.height as i32 - 7 + } + }; if overlapping { return; } diff --git a/cube/src/sokoban.rs b/cube/src/sokoban.rs index 0b0192c..765b0ce 100755 --- a/cube/src/sokoban.rs +++ b/cube/src/sokoban.rs @@ -34,24 +34,24 @@ impl Default for Sokoban { impl Sokoban { pub fn new() -> Self { - let xsb = "----#####---------- -----#---#---------- -----#$--#---------- ---###--$##--------- ---#--$-$-#--------- -###-#-##-#---###### -#---#-##-#####--..# -#-$--$----------..# -#####-###-#@##--..# -----#-----######### -----#######-------- + let xsb = " +####### +#--#--# +#-$---# +#--*.*# +#-$@*-# +###$*-# +-#--*-# +-#-#.-# +-#--.-# +-###### "; let map = Map::from_xsb(xsb); let player = Player::new(map.player.1 .0); // 设置一个初始视野坐标 let vpx = { - if player.pos.x - 3 <= 0 { + if player.pos.x - 3 <= 0 || map.width < 8 { 0 } else if player.pos.x + 5 >= map.width as i32 { player.pos.x - 8 + map.width as i32 - player.pos.x @@ -60,7 +60,7 @@ impl Sokoban { } }; let vpy = { - if player.pos.y - 3 <= 0 { + if player.pos.y - 3 <= 0 || map.height < 8 { 0 } else if player.pos.y + 5 >= map.height as i32 { player.pos.y - 8 + map.height as i32 - player.pos.y @@ -130,12 +130,6 @@ impl Sokoban { Gd::Down => boxp.y += 1, Gd::Left => boxp.x -= 1, }; - // let mc = boxs.iter().find(|m| { - // info!("next mc :{m:?}"); - // matches!(m.0, TargetType::Box | TargetType::Wall) - // && m.1 .0.x == boxp.x - // && m.1 .0.y == boxp.y - // }); let is_box = boxs.iter().any(|m| { matches!(m.0, TargetType::Box) && m.1 .0.x == boxp.x && m.1 .0.y == boxp.y }); @@ -225,9 +219,29 @@ impl Sokoban { /// 将对应的地图数据复制给视野 fn copy_map_to_vision(&mut self) { let Point { x, y } = self.vision.pos; - for (iy, y) in (y..(y + 8)).enumerate() { - for (ix, x) in (x..(x + 8)).enumerate() { - self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + if self.map.width < 8 && self.map.height < 8 { + for (iy, y) in (y..self.map.height as i32).enumerate() { + for (ix, x) in (x..self.map.width as i32).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } + } + } else if self.map.width < 8 { + for (iy, y) in (y..(y + 8)).enumerate() { + for (ix, x) in (x..self.map.width as i32).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } + } + } else if self.map.height < 8 { + for (iy, y) in (y..self.map.height as i32).enumerate() { + for (ix, x) in (x..(x + 8)).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } + } + } else { + for (iy, y) in (y..(y + 8)).enumerate() { + for (ix, x) in (x..(x + 8)).enumerate() { + self.vision.data[iy][ix] = self.map.data[y as usize][x as usize]; + } } } } @@ -235,8 +249,17 @@ impl Sokoban { /// 改变视野位置 fn update_vision(&mut self, app: &mut App) { let Point { x, y } = self.vision.next_pos(app); - let overlapping = - x < 0 || y < 0 || x >= self.map.width as i32 - 7 || y >= self.map.height as i32 - 7; + let overlapping = { + if self.map.width < 8 && self.map.height < 8 { + true + } else if self.map.width < 8 { + x < 0 || y < 0 || x > self.map.width as i32 - 7 || y >= self.map.height as i32 - 7 + } else if self.map.height < 8 { + x < 0 || y < 0 || x >= self.map.width as i32 - 7 || y > self.map.height as i32 - 7 + } else { + x < 0 || y < 0 || x >= self.map.width as i32 - 7 || y >= self.map.height as i32 - 7 + } + }; if overlapping { return; } @@ -251,12 +274,8 @@ impl Sokoban { enum TargetType { /// 人 Man, - /// 人在目标点上 - ManOnGoal, /// 箱子 Box, - /// 箱子在目标点上 - BoxOnGoal, /// 墙 Wall, /// 目标点 @@ -294,12 +313,10 @@ impl Map { /// 根据XSB生成地图 fn from_xsb(xsb: &str) -> Self { let mut map = Self::default(); - for (y, line) in xsb.lines().enumerate() { - map.height = y; + for (y, line) in xsb.trim().lines().enumerate() { let y = y as i32; let mut tmp = Vec::)>>::new(); for (x, char) in line.chars().enumerate() { - map.width = x; let x = x as i32; let pos = match char { '@' => { @@ -336,8 +353,15 @@ impl Map { } map.data.push(tmp); } - map.width += 1; - map.height += 1; + + map.data.extract_if(|d| d.iter().all(|c| c.is_none())); + + map.height = map.data.len(); + map.width = if map.height == 0 { + 0 + } else { + map.data[0].len() + }; map }