summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-11-12 01:00:48 +0000
committerubq323 <ubq323@ubq323.website>2023-11-12 01:00:48 +0000
commit7a8a1464b3144e765f4430245e161bea39832673 (patch)
tree46122c55e4b9f6169017e0d0b76c76a07df0f0e2
initial
-rw-r--r--main.ha91
-rw-r--r--ui.ha39
2 files changed, 130 insertions, 0 deletions
diff --git a/main.ha b/main.ha
new file mode 100644
index 0000000..9009947
--- /dev/null
+++ b/main.ha
@@ -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);
+};
+
+
diff --git a/ui.ha b/ui.ha
new file mode 100644
index 0000000..31a1865
--- /dev/null
+++ b/ui.ha
@@ -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);
+};