#!/bin/zsh _STTY=$(stty -g) # Save current terminal setup printf "\e[2J" # clear screen, set cursos at beginning stty -echo -icanon # Turn off line buffering printf '\e[?25h' # Turn on the cursor # VARIABLES typeset -A IMAGE X=0 Y=24 height=0 width=0 snake='═' vertical=false forward=true upward=true pen_down=true function get_size() { # Get terminal size ('stty' is POSIX and always available). read -r LINES COLUMNS < <(stty size) height=$((LINES-1)) width=$((COLUMNS-1)) } function start_the_snake() { rm thesnake for i in {0..$height} do for j in {0..$width} do IMAGE["${i};${j}"]=' ' ; printf ${IMAGE["${i};${j}"]} done done printf '\e[2J\e[H' ; printf '\e[0;24H' } function save_the_snake() { for i in {0..$height} do for j in {0..$width} do printf ${IMAGE["${i};${j}"]} done done >> thesnake #sed -e "s/.\{$((width-1))\}/&\n/g" < thesnake > snake80 } function show_the_snake() { printf '\e[2J\e[H' for i in {0..$height} do for j in {0..$width} do printf ${IMAGE["${i};${j}"]} done done printf '\e[%s;%sH' "$((Y+1))" "$((X+1))" } function at_exit() { printf "\e[?9l" # Turn off mouse reading printf "\e[?12l\e[?25h" # Turn on cursor stty "$_STTY" # reinitialize terminal settings clear exit } #═ ║╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟ #╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ function move_snake_up() { if [ "$vertical" = false ] ; then if [ "$forward" = true ] ; then snake='╝' else snake='╚' fi else snake='║' fi #draw nothing it the pen is not down if [ "$pen_down" = false ] ; then snake=' ' fi IMAGE["${Y};${X}"]=$snake ; Y=$((Y-1)) ; vertical=true ; upward=true } function move_snake_down() { if [ "$vertical" = false ] ; then if [ "$forward" = true ] ; then snake='╗' else snake='╔' fi else snake='║' fi #draw nothing it the pen is not down if [ "$pen_down" = false ] ; then snake=' ' fi IMAGE["${Y};${X}"]=$snake ; Y=$((Y+1)) ; vertical=true ; upward=false } function move_snake_forward() { if [ "$vertical" = true ] ; then if [ "$upward" = true ] ; then snake='╔' else snake='╚' fi else snake='═' fi #draw nothing it the pen is not down if [ "$pen_down" = false ] ; then snake=' ' fi IMAGE["${Y};${X}"]=$snake ; X=$((X+1)) ; vertical=false ; forward=true } function move_snake_backward() { if [ "$vertical" = true ] ; then if [ "$upward" = true ] ; then snake='╗' else snake='╝' fi else snake='═' fi #draw nothing it the pen is not down if [ "$pen_down" = false ] ; then snake=' ' fi IMAGE["${Y};${X}"]=$snake ; X=$((X-1)) ; vertical=false ; forward=false } # Main # get_size start_the_snake echo while read -s -k 1 cr; do case "$cr" in w) move_snake_up ; show_the_snake ;; s) move_snake_down ; show_the_snake ;; a) move_snake_backward ; show_the_snake ;; d) move_snake_forward ; show_the_snake ;; t) pen_down=true ;; y) pen_down=false ;; q) save_the_snake && at_exit ;; esac done