--- /dev/null
+__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
+}