Day 13 2019
[advent-of-code-2019.git] / day13 / screen.sh
diff --git a/day13/screen.sh b/day13/screen.sh
new file mode 100644 (file)
index 0000000..3bc3956
--- /dev/null
@@ -0,0 +1,140 @@
+__arcade_score=0
+
+clear_screen() {
+    echo -en '\033[2J'
+}
+
+move_cursor() {
+    local x=$1
+    local y=$2
+
+    # program assumes 0 based, we're 1 based, apparently
+    x=$((x+1))
+    y=$((y+1))
+
+    echo -en '\033['$y';'$x'f'
+}
+
+draw_tile() {
+    local tile_type=$1
+
+    case $tile_type in
+        0)
+            # blank
+            echo -n ' '
+            ;;
+        1)
+            # wall
+            echo -n '|'
+            ;;
+        2)
+            # block
+            echo -n '#'
+            ;;
+        3)
+            # horizontal paddle
+            echo -n '='
+            ;;
+        4)
+            # ball
+            echo -n 'o'
+            ;;
+    esac
+}
+
+hide_cursor() {
+    tput civis
+}
+
+show_cursor() {
+    tput cvvis
+}
+
+draw_score_board() {
+    local value=${1:-0}
+    local scoreboard_y=20
+    local scoreboard_width=43
+    move_cursor 0 $scoreboard_y
+    printf "+"
+    printf "%.0s-" {1..42}
+    printf "+\n"
+    printf "|"
+    printf "%.0s " {1..42}
+    printf "|\n"
+    printf "+"
+    printf "%.0s-" {1..42}
+    printf "+\n"
+    update_score_board
+}
+
+update_score_board() {
+    local value=${1:-$__arcade_score}
+    move_cursor 2 21
+    if [ $value -gt 0 ]; then
+        __arcade_score=$value
+    fi
+    printf '% 40d' $value
+}
+
+arcade_screen_init() {
+    clear_screen
+    hide_cursor
+    draw_score_board
+}
+
+arcade_screen_update() {
+    local x=$1
+    local y=$2
+    local tile=$3
+
+    move_cursor $x $y
+    draw_tile $tile
+}
+
+arcade_screen_finish() {
+    move_cursor 0 23
+    show_cursor
+    echo high score: $__arcade_score
+}
+
+arcade_screen() {
+    local max_y=0
+    local max_x=0
+    local -A blocks
+
+    # first, clear the screen and hide the cursor
+    clear_screen
+    hide_cursor
+
+    draw_score_board
+
+    while read x; do
+        read y
+        read tile
+        if [ $x -gt $max_x ]; then
+            max_x=$x
+        fi
+        if [ $y -gt $max_y ]; then
+            max_y=$y
+        fi
+        move_cursor $x $y
+        draw_tile $tile
+
+        case $tile in
+            0)
+                if [ ${blocks[$x,$y]+a} ]; then
+                    unset blocks[$x,$y]
+                fi
+                ;;
+            2)
+                blocks[$x,$y]=1
+                ;;
+        esac
+    done
+
+    move_cursor 0 $((max_y+4))
+    echo "We have ${#blocks[@]} blocks on the screen"
+    echo "The maximum x was $max_x"
+    echo "The maximum y was $max_y"
+    show_cursor
+}