use math::random; use vt; use io; use os; use fmt; type player = struct { x: uint, y: uint, }; type wall = void; type floor = void; type tile = (wall | floor); type room = struct { w: size, h: size, tiles: []tile, }; fn tile_at(r: room, x: size, y: size) tile = { const ix = x+(r.w*y); return r.tiles[ix]; }; fn set_tile_at(r: room, x: size, y: size, t: tile) void = { const ix = x+(r.w*y); r.tiles[ix] = t; }; fn tile_repr(t: tile) str = match(t) { case floor => yield "\x1b[33m."; case wall => yield "\x1b[32m\u2588"; }; fn draw_room(t: *vt::term, r: room) void = { for (let y = 0z; y < r.h; y+=1) { vt::move(t, (y+1):uint, 0)!; for (let x = 0z; x < r.w; x+=1) { fmt::fprint(t, tile_repr(tile_at(r,x,y)))!; }; }; }; fn get_key() u8 = { let b = [0u8]; io::read(os::stdin_file, b)!; return b[0]; }; def W = 50; def H = 40; fn get_room() room = { static const tiles: [W*H]tile = [floor...]; const room = room { w=W, h=H, tiles=tiles }; for (let i = 0z; i < W; i+=1) { set_tile_at(room, i, 0, wall); set_tile_at(room, i, H-1, wall); }; for (let i = 0z; i < H; i+=1) { set_tile_at(room, 0, i, wall); set_tile_at(room, W-1, i, wall); }; let rand = random::init(12345); for (let i = 0; i < 6; i+=1) { const x = (random::u64n(&rand, W-2)+1): size; const y = (random::u64n(&rand, H-2)+1): size; set_tile_at(room, x,y, wall); }; return room; }; fn can_move(r: room, x: size, y: size) bool = tile_at(r,x,y) is floor; fn clear_ent(t: *vt::term, r: room, x:size, y:size) void = { vt::move(t,y:uint+1,x:uint+1)!; vt::print(t,tile_repr(tile_at(r,x,y)))!; }; fn draw_ent(t: *vt::term, r: room, x:size, y:size, s:str) void = { vt::move(t,y:uint+1,x:uint+1)!; vt::print(t,s)!; }; export fn main() void = { const term = vt::open(); defer vt::close(term); vt::enablealt(term)!; vt::disablecur(term)!; let player = player { x=1, y=1 }; const playerstr = "\x1b[31m@"; const room = get_room(); let entities: []entity = []; for (let i = 0u; i < 1; i += 1) { append(entities, entity_new('g',vt::color::BLUE)); entities[i].x=i*2; }; vt::clear(term)!; draw_room(term, room); for (true) { for (let i = 0z; i < len(entities); i +=1) entity_draw(&entities[i], term); vt::move(term, player.y:uint+1, player.x:uint+1)!; vt::print(term, playerstr)!; match (get_input(term)) { case let m: move => { let nx = player.x; let ny = player.y; switch (m) { case move::UP => ny -= 1; case move::DOWN => ny += 1; case move::LEFT => nx -= 1; case move::RIGHT => nx += 1; }; if (can_move(room,nx,ny)) { clear_ent(term,room,player.x,player.y); draw_ent(term,room,nx,ny,playerstr); player.x = nx; player.y = ny; }; }; case quit => break; case => yield; }; for (let i = 0z; i < len(entities); i += 1) { const ent = entities[i]; clear_ent(term,room,ent.x,ent.y); }; for (let i = 0z; i < len(entities); i += 1) entity_tick(&entities[i],&room); }; };