diff options
author | ubq323 <ubq323@ubq323.website> | 2023-11-12 01:00:48 +0000 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2023-11-12 01:00:48 +0000 |
commit | 7a8a1464b3144e765f4430245e161bea39832673 (patch) | |
tree | 46122c55e4b9f6169017e0d0b76c76a07df0f0e2 |
initial
-rw-r--r-- | main.ha | 91 | ||||
-rw-r--r-- | ui.ha | 39 |
2 files changed, 130 insertions, 0 deletions
@@ -0,0 +1,91 @@ +use math::random; + +type player = struct { + x: int, + y: int, +}; + +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 wall => yield "\x1b[90m\u2588"; + case floor => yield "\x1b[37m."; +}; + +fn draw_room(r: room) void = { + assert(r.w < 20); + assert(r.h < 20); + for (let x = 0z; x < r.w; x+=1) + for (let y = 0z; y < r.h; y+=1) + put_at(x:int,y:int, tile_repr(tile_at(r,x,y))); +}; + + +export fn main() void = { + const term = setup_term(); + + const tiles: [100]tile = [floor...]; + const room = room { w=10, h=10, tiles=tiles }; + + for (let i = 0z; i < 10; i+=1) { + set_tile_at(room, 0, i, wall); + set_tile_at(room, 9, i, wall); + set_tile_at(room, i, 0, wall); + set_tile_at(room, i, 9, wall); + }; + + let rand = random::init(12345); + for (let i = 0; i < 6; i+=1) { + const x = (random::u64n(&rand, 9)+1): size; + const y = (random::u64n(&rand, 9)+1): size; + set_tile_at(room, x,y, wall); + }; + + + + + let player = player { x=1, y=1 }; + for (true) { + clear(); + draw_room(room); + put_at(player.x, player.y, "@"); + const c = get_key(): rune; + let nx = player.x; + let ny = player.y; + switch (c) { + case 'h' => nx -= 1; + case 'l' => nx += 1; + case 'j' => ny += 1; + case 'k' => ny -= 1; + case 'q' => break; + case => yield; + }; + if (tile_at(room, nx:size, ny:size) is floor) { + player.x = nx; + player.y = ny; + }; + }; + + finish_term(&term); +}; + + @@ -0,0 +1,39 @@ +use fmt; +use io; +use os; +use unix::tty; + +fn clear() void = { + fmt::fprint(os::stdout_file, "\x1b[H\x1b[2J\x1b[3J")!; +}; + +fn put_at(x: int, y: int, s: str) void = { + // 0 indexed! + fmt::fprintf(os::stdout_file, "\x1b[{};{}H{}", y+1,x+1, s)!; +}; + +fn get_key() u8 = { + // bad + let b = [0u8]; + io::read(os::stdin_file, b)!; + return b[0]; +}; + +fn setup_term() tty::termios = { + const term = tty::termios_query(os::stdin_file)!; + tty::makeraw(&term)!; + + // alternate screen, hide cursor + fmt::fprint(os::stdout_file, "\x1b[?1049h\x1b[?25l")!; + + clear(); + + return term; +}; + +fn finish_term(term: *tty::termios) void = { + // normal screen, show cursor + fmt::fprint(os::stdout_file, "\x1b[?1049l\x1b[?25h")!; + + tty::termios_restore(term); +}; |