Created
August 26, 2013 14:42
-
-
Save logicchains/6342156 to your computer and use it in GitHub Desktop.
Buggy Rust level generation code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{os, vec,comm}; | |
static TILE_DIM: uint = 50; | |
static MIN_WID: uint = 2; | |
static MAX_WID: uint = 8; | |
static NUM_LEVS: uint = 1000; | |
static NUM_CORES: uint = 4; | |
static NUM_TRIES: uint = 50_000; | |
#[deriving(Clone)] | |
struct Tile { x: uint, y: uint, t: bool } | |
#[deriving(Clone)] | |
struct Room { x: uint, y: uint, w: uint, h: uint, n: uint } | |
#[deriving(Clone)] | |
struct Level { tiles: ~[Tile], rooms: ~[Room] } | |
fn main() { | |
let prng:u32 = match os::args() { | |
[_, seed, .._] => FromStr::from_str(seed).unwrap_or_default(18), | |
_ => 18 | |
}; | |
printf!("The random seed is: %?", prng); | |
let (port, chan): (Port<~[Level]>, Chan<~[Level]>) = stream(); | |
let chan = comm::SharedChan::new(chan); | |
for val in range(0,NUM_CORES){ | |
let child_chan = chan.clone(); | |
do spawn { | |
let thisnum = (val+1) as u32; | |
let mut newprng = prng.clone()*thisnum*thisnum; | |
printf!("The seed for this thread is: %? \n", newprng); | |
child_chan.send(MakeLevs(NUM_LEVS/NUM_CORES,&mut newprng)); | |
} | |
} | |
let mut ls: ~[Level] = ~[]; | |
for _ in range(0,NUM_CORES){ | |
let newlev = port.recv(); | |
ls = ls + newlev; | |
} | |
let biggest_level = do ls.iter().max_by |level| { | |
level.rooms.len() | |
}.expect("No levels found!"); | |
print_level(biggest_level); | |
} | |
fn MakeLevs(n: uint, gen:&mut u32) -> ~[Level] { | |
let ls: ~[Level] = do vec::from_fn(n) |_| { | |
let rs = make_rooms(99, gen); | |
let mut ts: ~[Tile] = do vec::from_fn(TILE_DIM * TILE_DIM) |ii| { | |
Tile { x: ii % TILE_DIM, y: ii / TILE_DIM, t: false } | |
}; | |
for r in rs.iter() { | |
room_to_tiles(r, &mut ts); | |
} | |
Level { tiles: ts, rooms: rs } | |
}; | |
ls | |
} | |
fn make_rooms(max_rooms: uint, prng: &mut u32) -> ~[Room] { | |
let mut rooms = vec::with_capacity(max_rooms); | |
for _ in range(0, NUM_TRIES) { | |
let r1 = rand_uint(prng); | |
let r2 = rand_uint(prng); | |
let x = r1 % TILE_DIM; | |
let y = r2 % TILE_DIM; | |
let w = r1 % MAX_WID + MIN_WID; | |
let h = r2 % MAX_WID + MIN_WID; | |
if x + w < TILE_DIM && y + h < TILE_DIM && | |
x != 0 && y != 0 && | |
no_overlap(x, y, w, h, rooms) { | |
let r = Room { x: x, y: y, w: w, h: h, n: rooms.len() }; | |
rooms.push(r); | |
if rooms.len() == max_rooms { break } | |
} | |
} | |
rooms | |
} | |
fn no_overlap(new_x: uint, new_y: uint, new_w: uint, new_h: uint, rs: &[Room]) -> bool { | |
do rs.iter().all |r| { | |
let Room { x, y, w, h, _ } = *r; | |
((x + w + 1) < new_x || x > (new_x + new_w + 1) || | |
(y + h + 1) < new_y || y > (new_y + new_h + 1)) | |
} | |
} | |
fn room_to_tiles(r: &Room, ts: &mut ~[Tile]) { | |
let Room { x, y, w, h, _ } = *r; | |
for yi in range(y, y+h+1) { | |
for xi in range(x, x+w+1) { | |
let address = yi * TILE_DIM + xi; | |
ts[address].t = true; | |
} | |
} | |
} | |
fn print_level(l: &Level) { | |
for (i, tile) in l.tiles.iter().enumerate() { | |
print(if tile.t {"1"} else {"0"}); | |
if i % TILE_DIM == 49 { | |
print("\n"); | |
} | |
} | |
} | |
fn rand_uint(prng: &mut u32) -> uint { | |
*prng += *prng; | |
*prng ^= 1; | |
if (*prng as i32) < 0 { | |
*prng ^= 0x88888eef; | |
} | |
*prng as uint | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment