From e919c1d92f2c2c1a312843a9fc371e3a20a34411 Mon Sep 17 00:00:00 2001 From: bouzuya Date: Sat, 24 Feb 2024 08:24:46 +0900 Subject: [PATCH] roguelike-tdd: Add MapGenerator::write and MapUtil::parse --- roguelike-tdd/src/dungeon.rs | 1 + roguelike-tdd/src/dungeon/map_generator.rs | 86 +++++++++++++++++++++- roguelike-tdd/src/dungeon/map_util.rs | 23 ++++++ roguelike-tdd/src/dungeon/passage.rs | 21 ++---- roguelike-tdd/src/dungeon/room.rs | 2 +- roguelike-tdd/src/dungeon/stairs.rs | 26 ++----- 6 files changed, 120 insertions(+), 39 deletions(-) create mode 100644 roguelike-tdd/src/dungeon/map_util.rs diff --git a/roguelike-tdd/src/dungeon.rs b/roguelike-tdd/src/dungeon.rs index 857a4656..3d9532e8 100644 --- a/roguelike-tdd/src/dungeon.rs +++ b/roguelike-tdd/src/dungeon.rs @@ -1,6 +1,7 @@ mod door; mod map_chips; mod map_generator; +mod map_util; mod passage; mod room; mod stairs; diff --git a/roguelike-tdd/src/dungeon/map_generator.rs b/roguelike-tdd/src/dungeon/map_generator.rs index 81ac65be..2ba10569 100644 --- a/roguelike-tdd/src/dungeon/map_generator.rs +++ b/roguelike-tdd/src/dungeon/map_generator.rs @@ -1,4 +1,4 @@ -use super::map_chips::MapChip; +use super::{door::Door, map_chips::MapChip, passage::Passage, room::Room, stairs::Stairs}; pub struct MapGenerator { pub map: Vec>, @@ -10,11 +10,35 @@ impl MapGenerator { map: vec![vec![MapChip::Wall; width]; height], } } + + pub fn write( + &mut self, + rooms: &[Room], + passages: &[Passage], + doors: &[Door], + stairs: &[Stairs], + ) { + for passage in passages { + passage.write_to_map(&mut self.map); + } + for room in rooms { + room.write_to_map(&mut self.map); + } + for door in doors { + door.write_to_map(&mut self.map); + } + for stair in stairs { + stair.write_to_map(&mut self.map); + } + } } #[cfg(test)] mod tests { - use crate::dungeon::map_chips::MapChip; + use crate::dungeon::{ + door::Door, map_chips::MapChip, map_util::MapUtil, passage::Passage, room::Room, + stairs::Stairs, + }; use super::*; @@ -35,4 +59,62 @@ mod tests { assert_eq!(sut.map, vec![vec![MapChip::Wall; width]; height]); } + + #[test] + fn test_write_マップを構成する要素をマップ配列に書き込めること() { + let mut sut = MapGenerator::new(10, 9); + let rooms = vec![ + Room { + x: 1, + y: 1, + width: 3, + height: 3, + }, + Room { + x: 5, + y: 5, + width: 4, + height: 3, + }, + ]; + let passages = vec![Passage::new(rooms[0].clone(), rooms[1].clone())]; + let mut doors = Door::create_doors(rooms[0].clone(), passages.clone()); + doors.extend(Door::create_doors(rooms[1].clone(), passages.clone())); + let stairs = vec![ + Stairs::new( + vec![Room { + x: 1, + y: 1, + width: 1, + height: 1, + }], + MapChip::UpStairs, + ), + Stairs::new( + vec![Room { + x: 6, + y: 6, + width: 1, + height: 1, + }], + MapChip::DownStairs, + ), + ]; + let expected = MapUtil::parse( + r#" +WWWWWWWWWW +WURRWWWWWW +WRRRDPPPWW +WRRRWWWPWW +WWWWWWWDWW +WWWWWRRRRW +WWWWWRSRRW +WWWWWRRRRW +WWWWWWWWWW +"# + .trim(), + ); + sut.write(&rooms, &passages, &doors, &stairs); + assert_eq!(sut.map, expected); + } } diff --git a/roguelike-tdd/src/dungeon/map_util.rs b/roguelike-tdd/src/dungeon/map_util.rs new file mode 100644 index 00000000..04b2db9f --- /dev/null +++ b/roguelike-tdd/src/dungeon/map_util.rs @@ -0,0 +1,23 @@ +use super::map_chips::MapChip; + +pub struct MapUtil; + +impl MapUtil { + pub fn parse(s: &str) -> Vec> { + s.lines() + .map(|line| { + line.chars() + .map(|c| match c { + 'D' => MapChip::Door, + 'P' => MapChip::Passage, + 'R' => MapChip::Room, + 'S' => MapChip::DownStairs, + 'U' => MapChip::UpStairs, + 'W' => MapChip::Wall, + _ => unreachable!(), + }) + .collect::>() + }) + .collect::>>() + } +} diff --git a/roguelike-tdd/src/dungeon/passage.rs b/roguelike-tdd/src/dungeon/passage.rs index 9517bfa9..d328a041 100644 --- a/roguelike-tdd/src/dungeon/passage.rs +++ b/roguelike-tdd/src/dungeon/passage.rs @@ -1,5 +1,6 @@ use super::{map_chips::MapChip, room::Room}; +#[derive(Clone, Debug)] pub struct Passage { pub steps: Vec<(usize, usize)>, } @@ -65,7 +66,9 @@ impl Passage { #[cfg(test)] mod tests { - use crate::dungeon::{map_chips::MapChip, map_generator::MapGenerator, room::Room}; + use crate::dungeon::{ + map_chips::MapChip, map_generator::MapGenerator, map_util::MapUtil, room::Room, + }; use super::*; @@ -113,7 +116,7 @@ mod tests { height: 4, }; let mut map = MapGenerator::new(8, 6); - let expected = map_util_parse( + let expected = MapUtil::parse( r#" WWWWWWWW WPPPPPPW @@ -215,18 +218,4 @@ WWWWWWWW }) .collect::>() } - - fn map_util_parse(s: &str) -> Vec> { - s.lines() - .map(|line| { - line.chars() - .map(|c| match c { - 'P' => MapChip::Passage, - 'W' => MapChip::Wall, - _ => unreachable!(), - }) - .collect::>() - }) - .collect::>>() - } } diff --git a/roguelike-tdd/src/dungeon/room.rs b/roguelike-tdd/src/dungeon/room.rs index c2a3deaf..84c56f42 100644 --- a/roguelike-tdd/src/dungeon/room.rs +++ b/roguelike-tdd/src/dungeon/room.rs @@ -94,7 +94,7 @@ impl Room { self.x + self.width - 1 } - fn write_to_map(&self, map: &mut [Vec]) { + pub fn write_to_map(&self, map: &mut [Vec]) { for y in self.y..=self.bottom() { for x in self.x..=self.right() { map[y][x] = crate::dungeon::map_chips::MapChip::Room; diff --git a/roguelike-tdd/src/dungeon/stairs.rs b/roguelike-tdd/src/dungeon/stairs.rs index 77734c9b..68a045bd 100644 --- a/roguelike-tdd/src/dungeon/stairs.rs +++ b/roguelike-tdd/src/dungeon/stairs.rs @@ -39,7 +39,9 @@ impl Stairs { mod tests { use std::collections::HashSet; - use crate::dungeon::{map_chips::MapChip, map_generator::MapGenerator, room::Room}; + use crate::dungeon::{ + map_chips::MapChip, map_generator::MapGenerator, map_util::MapUtil, room::Room, + }; use super::*; @@ -166,7 +168,7 @@ mod tests { let stairs_type = MapChip::UpStairs; let stairs = Stairs::new(vec![room], stairs_type); let mut map = MapGenerator::new(2, 2); - let expected = map_util_parse( + let expected = MapUtil::parse( r#" WW WU @@ -188,30 +190,14 @@ WU let stairs_type = MapChip::DownStairs; let stairs = Stairs::new(vec![room], stairs_type); let mut map = MapGenerator::new(2, 2); - let expected = map_util_parse( + let expected = MapUtil::parse( r#" WW -WD +WS "# .trim(), ); stairs.write_to_map(&mut map.map); assert_eq!(map.map, expected); } - - fn map_util_parse(s: &str) -> Vec> { - s.lines() - .map(|line| { - line.chars() - .map(|c| match c { - 'P' => MapChip::Passage, - 'W' => MapChip::Wall, - 'U' => MapChip::UpStairs, - 'D' => MapChip::DownStairs, - _ => unreachable!("invalid map chip: {}", c), - }) - .collect::>() - }) - .collect::>>() - } }