Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 16917f1

Browse files
more cleanup
1 parent ec5d448 commit 16917f1

File tree

2 files changed

+139
-118
lines changed

2 files changed

+139
-118
lines changed

src/binary_space_partition.rs

Lines changed: 105 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,103 @@
1-
use std::{fmt, cmp};
2-
use rand::distributions::WeightedIndex;
1+
use crate::error::Result;
32
use rand::prelude::*;
43
use rand::rngs::StdRng;
54
use rand::Rng;
65
use serde::Serialize;
7-
use crate::error::Result;
6+
use std::{cmp, fmt};
87

98
struct BspLevel {
109
level: Level,
11-
map_subsection_min_size: i32,
12-
map_subsection_min_room_width: i32,
13-
map_subsection_min_room_height: i32,
10+
map_subsection_min_size: usize,
11+
map_subsection_min_room_width: usize,
12+
map_subsection_min_room_height: usize,
1413
}
1514

16-
1715
byond_fn!(fn bsp_generate(width, height, hash, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height) {
1816
bsp_gen(width, height, hash, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height).ok()
1917
});
2018

21-
fn bsp_gen(width_as_str: &str,
19+
fn bsp_gen(
20+
width_as_str: &str,
2221
height_as_str: &str,
2322
hash_as_str: &str,
2423
map_subsection_min_size_as_str: &str,
2524
map_subsection_min_room_width_as_str: &str,
26-
map_subsection_min_room_height_as_str: &str)
27-
-> Result<String>{
25+
map_subsection_min_room_height_as_str: &str,
26+
) -> Result<String> {
2827
let default_hash: u64 = rand::thread_rng().gen();
29-
let width = width_as_str.parse::<i32>()?;
30-
let height = height_as_str.parse::<i32>()?;
31-
let map_subsection_min_room_width = map_subsection_min_room_width_as_str.parse::<i32>()?;
32-
let map_subsection_min_room_height = map_subsection_min_room_height_as_str.parse::<i32>()?;
28+
let width = width_as_str.parse::<usize>()?;
29+
let height = height_as_str.parse::<usize>()?;
30+
let map_subsection_min_room_width = map_subsection_min_room_width_as_str.parse::<usize>()?;
31+
let map_subsection_min_room_height = map_subsection_min_room_height_as_str.parse::<usize>()?;
3332

33+
//map subsections that the BSP algorithm creates should never be smaller than the minimum desired room size they will contain. This will crash the server
3434
let map_subsection_min_size = cmp::max(
35-
map_subsection_min_size_as_str.parse::<i32>()?,
36-
cmp::max(map_subsection_min_room_width, map_subsection_min_room_height) + 1
35+
map_subsection_min_size_as_str.parse::<usize>()?,
36+
cmp::max(
37+
map_subsection_min_room_width,
38+
map_subsection_min_room_height,
39+
) + 1,
3740
);
3841

39-
//let seed: &str = Alphanumeric.sample_string(&mut rand::thread_rng(), 32).as_str();
40-
41-
let mut rng: StdRng = SeedableRng::seed_from_u64(hash_as_str.parse::<usize>()?.try_into().unwrap_or(default_hash));
42-
42+
let mut rng: StdRng = SeedableRng::seed_from_u64(
43+
hash_as_str
44+
.parse::<usize>()?
45+
.try_into()
46+
.unwrap_or(default_hash),
47+
);
4348

44-
let level = BspLevel::new(width, height, &mut rng, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height);
49+
let level = BspLevel::new(
50+
width,
51+
height,
52+
&mut rng,
53+
map_subsection_min_size,
54+
map_subsection_min_room_width,
55+
map_subsection_min_room_height,
56+
);
4557

46-
Ok(serde_json::to_string(&level.all_rooms)?)
58+
Ok(serde_json::to_string(&level.rooms)?)
4759
}
4860

4961
impl BspLevel {
5062
fn new(
51-
width: i32,
52-
height: i32,
63+
width: usize,
64+
height: usize,
5365
rng: &mut StdRng,
54-
map_subsection_min_size: i32,
55-
map_subsection_min_room_width: i32,
56-
map_subsection_min_room_height: i32,
66+
map_subsection_min_size: usize,
67+
map_subsection_min_room_width: usize,
68+
map_subsection_min_room_height: usize,
5769
) -> Level {
5870
let level = Level::new(width, height);
5971

60-
let mut map = BspLevel { level, map_subsection_min_size, map_subsection_min_room_width, map_subsection_min_room_height };
72+
let mut map = BspLevel {
73+
level,
74+
map_subsection_min_size,
75+
map_subsection_min_room_width,
76+
map_subsection_min_room_height,
77+
};
6178

6279
map.place_rooms(rng);
6380

6481
map.level
6582
}
6683

6784
fn place_rooms(&mut self, rng: &mut StdRng) {
68-
let mut root = Leaf::new(0, 0, self.level.width, self.level.height, self.map_subsection_min_size, self.map_subsection_min_room_width,self.map_subsection_min_room_height);
85+
let mut root = Leaf::new(
86+
0,
87+
0,
88+
self.level.width,
89+
self.level.height,
90+
self.map_subsection_min_size,
91+
self.map_subsection_min_room_width,
92+
self.map_subsection_min_room_height,
93+
);
6994
root.generate(rng);
7095

7196
root.create_rooms(rng);
7297

7398
for leaf in root.iter() {
7499
if leaf.is_leaf() {
75100
if let Some(room) = leaf.get_room() {
76-
77101
self.level.add_room(&room);
78102
}
79103
}
@@ -82,26 +106,33 @@ impl BspLevel {
82106
self.level.add_room(&corridor);
83107
}
84108
}
85-
86109
}
87110
}
88111

89112
struct Leaf {
90-
min_size: i32,
91-
x: i32,
92-
y: i32,
93-
width: i32,
94-
height: i32,
95-
min_room_width: i32,
96-
min_room_height: i32,
113+
min_size: usize,
114+
x: usize,
115+
y: usize,
116+
width: usize,
117+
height: usize,
118+
min_room_width: usize,
119+
min_room_height: usize,
97120
left_child: Option<Box<Leaf>>,
98121
right_child: Option<Box<Leaf>>,
99122
room: Option<Room>,
100123
corridors: Vec<Room>,
101124
}
102125

103126
impl Leaf {
104-
fn new(x: i32, y: i32, width: i32, height: i32, min_size: i32, min_room_width: i32, min_room_height: i32,) -> Self {
127+
fn new(
128+
x: usize,
129+
y: usize,
130+
width: usize,
131+
height: usize,
132+
min_size: usize,
133+
min_room_width: usize,
134+
min_room_height: usize,
135+
) -> Self {
105136
Leaf {
106137
min_size,
107138
x,
@@ -223,22 +254,15 @@ impl Leaf {
223254
let height = rng.gen_range(self.min_room_height..=self.height);
224255
let x = rng.gen_range(0..=self.width - width);
225256
let y = rng.gen_range(0..=self.height - height);
226-
let choices = [0, 4];
227-
let weights = [1, 4];
228-
let dist = WeightedIndex::new(&weights).unwrap();
229-
let mut rng = thread_rng();
230-
let room_layout = choices[dist.sample(&mut rng)];
231257

232258
self.room = Some(Room::new(
233-
format!("extra room"),
259+
format!("bsp room"),
234260
x + self.x,
235261
y + self.y,
236262
width,
237263
height,
238-
room_layout,
239264
));
240265
}
241-
242266
}
243267

244268
fn get_room(&self) -> Option<Room> {
@@ -315,70 +339,67 @@ impl<'a> Iterator for LeafIterator<'a> {
315339
}
316340
}
317341

342+
#[derive(Debug, Clone, Copy)]
343+
pub enum TileType {
344+
Space = 0,
345+
Floor = 1,
346+
Wall = 2,
347+
}
318348
pub struct Level {
319-
width: i32,
320-
height: i32,
321-
board: Vec<Vec<i32>>,
322-
all_rooms: Vec<Room>,
323-
increment: i32,
324-
//hash: String,
349+
width: usize,
350+
height: usize,
351+
board: Vec<Vec<usize>>,
352+
rooms: Vec<Room>,
353+
increment: usize,
325354
}
326355

327356
impl Level {
328-
fn new(
329-
width: i32,
330-
height: i32,
331-
) -> Self {
357+
fn new(width: usize, height: usize) -> Self {
332358
let mut new_level = Level {
333359
width,
334360
height,
335361
board: Vec::new(),
336-
all_rooms: Vec::new(),
362+
rooms: Vec::new(),
337363
increment: 0,
338364
};
339365
new_level.update_board();
340366
new_level
341367
}
342368

343-
fn update_board(&mut self) -> Vec<Vec<i32>> {
369+
fn update_board(&mut self) -> Vec<Vec<usize>> {
344370
let mut new_board = Vec::new();
345-
self.increment+=1;
371+
self.increment += 1;
346372
for _ in 0..self.height {
347-
let space_tile = 0;
348-
//let wall_tile = 1;
349-
let floor_tile = 5;
350373
let gen_floor_first = true;
351374

352-
let mut row = vec![floor_tile; self.width as usize];
375+
let mut row = vec![TileType::Floor as usize; self.width as usize];
353376
if !gen_floor_first {
354-
row = vec![space_tile; self.width as usize];
377+
row = vec![TileType::Space as usize; self.width as usize];
355378
}
356379

357380
new_board.push(row);
358381
}
359-
for room in &self.all_rooms {
382+
for room in &self.rooms {
360383
for row in 0..room.height {
361384
for col in 0..room.width {
362385
let y = (room.y + row) as usize;
363386
let x = (room.x + col) as usize;
364387
if row == 0 || col == 0 || row == room.height - 1 || col == room.width - 1 {
365388
// might just let byond handle the walls
366-
new_board[y][x] = 1;
389+
new_board[y][x] = TileType::Wall as usize;
367390
} else {
368-
new_board[y][x] = room.room_type;
391+
new_board[y][x] = TileType::Floor as usize;
369392
}
370393
}
371394
}
372395
}
373396
self.board = new_board.clone();
374-
//draw(self, "increments", &self.increment.to_string()).unwrap();
375397
new_board
376398
}
377399

378400
fn add_room(&mut self, room: &Room) {
379-
self.all_rooms.push(room.clone());
401+
self.rooms.push(room.clone());
380402
self.update_board();
381-
382403
}
383404
}
384405

@@ -388,7 +409,7 @@ impl fmt::Display for Level {
388409
for col in 0..self.width as usize {
389410
write!(f, "{}", self.board[row][col])?
390411
}
391-
// write!(f, "\n")?
412+
write!(f, "\n")?
392413
}
393414

394415
Ok(())
@@ -397,25 +418,24 @@ impl fmt::Display for Level {
397418

398419
#[derive(Debug, Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Serialize)]
399420
pub struct Point {
400-
x: i32,
401-
y: i32,
421+
x: usize,
422+
y: usize,
402423
}
403424

404425
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
405426
pub struct Room {
406427
id: String,
407-
x: i32,
408-
y: i32,
409-
x2: i32,
410-
y2: i32,
411-
width: i32,
412-
height: i32,
428+
x: usize,
429+
y: usize,
430+
x2: usize,
431+
y2: usize,
432+
width: usize,
433+
height: usize,
413434
center: Point,
414-
room_type: i32,
415435
}
416436

417437
impl Room {
418-
pub fn new(id: String, x: i32, y: i32, width: i32, height: i32, room_type: i32) -> Self {
438+
pub fn new(id: String, x: usize, y: usize, width: usize, height: usize) -> Self {
419439
Room {
420440
id,
421441
x,
@@ -428,14 +448,14 @@ impl Room {
428448
x: x + (width / 2),
429449
y: y + (height / 2),
430450
},
431-
room_type,
432451
}
433452
}
434453

435454
pub fn intersects(&self, other: &Self) -> bool {
436455
self.x <= other.x2 && self.x2 >= other.x && self.y <= other.y2 && self.y2 >= other.y
437456
}
438-
pub fn get_distance_to(&self, other: &Point) -> i32 {
439-
(((other.x - self.center.x).pow(2) + (other.y - self.center.y).pow(2)) as f64).sqrt() as i32
457+
pub fn get_distance_to(&self, other: &Point) -> usize {
458+
(((other.x - self.center.x).pow(2) + (other.y - self.center.y).pow(2)) as f64).sqrt()
459+
as usize
440460
}
441461
}

0 commit comments

Comments
 (0)