Day 15
[advent-of-code-2019.git] / day13 / screen.sh
1 __arcade_score=0
2
3 clear_screen() {
4     # first reset then clear
5     echo -en '\033c'
6     echo -en '\033[2J'
7 }
8
9 echo_off() {
10     stty -echo
11 }
12
13 echo_on() {
14     stty echo
15 }
16
17 hide_cursor() {
18     tput civis
19 }
20
21 show_cursor() {
22     tput cvvid
23 }
24
25 move_cursor() {
26     local x=$1
27     local y=$2
28
29     # program assumes 0 based, we're 1 based, apparently
30     x=$((x+1))
31     y=$((y+1))
32
33     echo -en '\033['$y';'$x'f'
34 }
35
36 draw_tile() {
37     local tile_type=$1
38
39     case $tile_type in
40         0)
41             # blank
42             echo -n ' '
43             ;;
44         1)
45             # wall
46             echo -n '|'
47             ;;
48         2)
49             # block
50             echo -n '#'
51             ;;
52         3)
53             # horizontal paddle
54             echo -n '='
55             ;;
56         4)
57             # ball
58             echo -n 'o'
59             ;;
60     esac
61 }
62
63 draw_score_board() {
64     local value=${1:-0}
65     local scoreboard_y=20
66     local scoreboard_width=43
67     move_cursor 0 $scoreboard_y
68     printf "+"
69     printf "%.0s-" {1..42}
70     printf "+\n"
71     printf "|"
72     printf "%.0s " {1..42}
73     printf "|\n"
74     printf "+"
75     printf "%.0s-" {1..42}
76     printf "+\n"
77     update_score_board
78 }
79
80 update_score_board() {
81     local value=${1:-$__arcade_score}
82     move_cursor 2 21
83     if [ $value -gt 0 ]; then
84         __arcade_score=$value
85     fi
86     printf '% 40d' $value
87 }
88
89 arcade_screen_init() {
90     clear_screen
91     echo_off
92     hide_cursor
93     draw_score_board
94 }
95
96 arcade_screen_update() {
97     local x=$1
98     local y=$2
99     local tile=$3
100
101     move_cursor $x $y
102     draw_tile $tile
103 }
104
105 arcade_screen_finish() {
106     move_cursor 0 23
107     show_cursor
108     echo_on
109 }
110
111 arcade_screen() {
112     local max_y=0
113     local max_x=0
114     local -A blocks
115
116     # first, clear the screen and hide the cursor
117     arcade_screen_init
118
119     while read x; do
120         read y
121         read tile
122         if [ $x -gt $max_x ]; then
123             max_x=$x
124         fi
125         if [ $y -gt $max_y ]; then
126             max_y=$y
127         fi
128         move_cursor $x $y
129         draw_tile $tile
130
131         case $tile in
132             0)
133                 if [ ${blocks[$x,$y]+a} ]; then
134                     unset blocks[$x,$y]
135                 fi
136                 ;;
137             2)
138                 blocks[$x,$y]=1
139                 ;;
140         esac
141     done
142
143     move_cursor 0 $((max_y+4))
144     echo "We have ${#blocks[@]} blocks on the screen"
145     echo "The maximum x was $max_x"
146     echo "The maximum y was $max_y"
147     show_cursor
148 }