Created
September 20, 2020 13:26
-
-
Save athas/9ae5dc6d2bcd4f37540ef094c2d1e670 to your computer and use it in GitHub Desktop.
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
type cell = i32 | |
type dir = #north | #south | #east | #west | |
let dir_to_bit (d: dir) : i32 = | |
match d | |
case #north -> 1 | |
case #south -> 2 | |
case #east -> 4 | |
case #west -> 8 | |
let has_dir (c: cell) (d: dir) : bool = | |
c & dir_to_bit d != 0 | |
let set_dir (c: cell) (d: dir) : cell = | |
c | dir_to_bit d | |
let combine_cells (x: cell) (y: cell) = | |
x | y | |
let empty_cell : cell = | |
0 | |
let cell_to_char (c: cell) : i32 = | |
match {n=has_dir c #north, | |
s=has_dir c #south, | |
e=has_dir c #east, | |
w=has_dir c #west} | |
case {n=false, s=false, e=false, w=false} -> ' ' | |
case {n=false, s=true, e=false, w=false} -> '╷' | |
case {n=true, s=false, e=false, w=false} -> '╵' | |
case {n=true, s=true, e=false, w=false} -> '│' | |
case {n=true, s=true, e=true, w=false} -> '├' | |
case {n=true, s=true, e=false, w=true} -> '┤' | |
case {n=true, s=true, e=true, w=true} -> '┼' | |
case {n=false, s=true, e=true, w=true} -> '┬' | |
case {n=true, s=false, e=true, w=true} -> '┴' | |
case {n=false, s=false, e=true, w=true} -> '─' | |
case {n=false, s=false, e=false, w=true} -> '╴' | |
case {n=false, s=false, e=true, w=false} -> '╶' | |
case {n=false, s=true, e=true, w=false} -> '┌' | |
case {n=true, s=false, e=true, w=false} -> '└' | |
case {n=false, s=true, e=false, w=true} -> '┐' | |
case {n=true, s=false, e=false, w=true} -> '┘' | |
import "lib/github.com/diku-dk/segmented/segmented" | |
type pos = (i32,i32) | |
let line_horiz ((x,y): pos) (w: i32) : [w](pos, cell) = | |
let f i = | |
((x+i, y), | |
if i == 0 then empty_cell `set_dir` #east | |
else if i == w-1 then empty_cell `set_dir` #west | |
else empty_cell `set_dir` #west `set_dir` #east) | |
in tabulate w f | |
let line_vert ((x,y): pos) (h: i32) : [h](pos, cell) = | |
let f i = | |
((x, y+i), | |
if i == 0 then empty_cell `set_dir` #south | |
else if i == h-1 then empty_cell `set_dir` #north | |
else empty_cell `set_dir` #south `set_dir` #north) | |
in tabulate h f | |
let put_cells [h][w][n] (canvas: *[h][w]cell) (draw: [n](pos, cell)) | |
: *[h][w]cell = | |
let flat_idx (x,y) = if x >= 0 && x < w && y >= 0 && y < h | |
then y*w+x | |
else -1 | |
in unflatten h w (reduce_by_index (flatten canvas) | |
combine_cells empty_cell | |
(map ((.0) >-> flat_idx) draw) | |
(map (.1) draw)) | |
let main (h: i32) (w: i32) : [h][w]i32 = | |
let canvas = replicate h (replicate w empty_cell) | |
let draw = [] | |
++ line_horiz (0,10) 20 | |
++ line_vert (10,0) 20 | |
++ line_horiz (5,5) 11 | |
++ line_vert (5,5) 11 | |
++ line_vert (15,5) 11 | |
++ line_horiz (5,15) 11 | |
in map (map cell_to_char) (put_cells canvas draw) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment