fork download
  1. #!/bin/bash
  2. max_x=40
  3. max_y=40
  4. hx=20 hy=20
  5. tx=20 ty=20
  6. len=1
  7. cur_len=0
  8. need_food=1
  9. level0=0.1
  10. level1=0.05
  11. level2=0.025
  12.  
  13. direct=u
  14. input(){
  15. echo -ne "\033[?25l"
  16. local aKey=(0 0 0 0)
  17. local cESC=`echo -ne "\033"`
  18. local index
  19. while :
  20. do
  21. read -s -n 1 key
  22. aKey=( "${aKey[@]:1}" "$key")
  23. if [[ $key${aKey[2]} = $cESC$cESC ]] ; then kill -29 $1; break
  24. elif [[ "${aKey[@]:1:2}$key" = "${cESC} [A" ]] ; then kill -25 $1 ## direct=u
  25. elif [[ "${aKey[@]:1:2}$key" = "${cESC} [B" ]] ; then kill -26 $1 ## direct=d
  26. elif [[ "${aKey[@]:1:2}$key" = "${cESC} [C" ]] ; then kill -27 $1 ## direct=r
  27. elif [[ "${aKey[@]:1:2}$key" = "${cESC} [D" ]] ; then kill -28 $1 ## direct=l
  28. else continue
  29. fi
  30. done
  31. echo -ne "\033[?25h"
  32. }
  33. draw_head(){
  34. tput cup $2 $(( $1<<1 ))
  35. echo -ne "\033[1;47m \033[m"
  36. }
  37. draw_tail(){
  38. tput cup $2 $(( $1<<1 ))
  39. echo -ne "\033[1;40m \033[m"
  40. }
  41. run(){
  42. trap '[[ $direct != d ]] && direct=u' 25
  43. trap '[[ $direct != u ]] && direct=d' 26
  44. trap '[[ $direct != l ]] && direct=r' 27
  45. trap '[[ $direct != r ]] && direct=l' 28
  46. trap 'exit' 29
  47.  
  48. while :
  49. do
  50. eval "[[ \"\$m${hx}_${hy}\" = f ]] && (( ++len )) && need_food=1"
  51. draw_head $hx $hy
  52. eval m${hx}_${hy}=$direct
  53. case $direct in
  54. u) (( --hy )); (( hy < 0 )) && break ;;
  55. d) (( ++hy )); (( hy > max_y )) && break ;;
  56. r) (( ++hx )); (( hx > max_x )) && break ;;
  57. l) (( --hx )); (( hx < 0 )) && break ;;
  58. esac
  59. eval "[ -n \"\${m${hx}_${hy}}\" -a ! \"\${m${hx}_${hy}}\" = f ] && break"
  60. (( ++cur_len ))
  61. if (( len < cur_len )) ; then
  62. (( --cur_len ))
  63. eval local d=\$m${tx}_${ty}
  64. draw_tail $tx $ty
  65. unset m${tx}_${ty}
  66. case $d in
  67. u) (( --ty ));;
  68. d) (( ++ty ));;
  69. r) (( ++tx ));;
  70. l) (( --tx ));;
  71. esac
  72. fi
  73. if [ $need_food = 1 ] ; then
  74. draw_food && need_food=0
  75. fi
  76. sleep $level1
  77. done
  78. kill $1
  79. }
  80. draw_food(){
  81. local fx=$(( $RANDOM % max_x + 1 ))
  82. local fy=$(( $RANDOM % max_y + 1 ))
  83. eval local f=\$m${fx}_${fy}
  84. if [[ -z $f ]] ; then
  85. tput cup $fy $(( $fx<<1 ))
  86. eval m${fx}_${fy}=f
  87. echo -ne "\033[1;45m \033[m"
  88. return 0
  89. fi
  90. return 1
  91. }
  92. draw_wall(){
  93. for (( i=0; i<=max_x; i++ ))
  94. do
  95. tput cup 0 $(( $i<<1 ))
  96. eval m${i}_0=w
  97. echo -ne "\033[1;46m \033[m"
  98. done
  99.  
  100. for (( i=0; i<=max_x; i++ ))
  101. do
  102. eval m${i}_$max_y=w
  103. tput cup $max_y $(( $i<<1 ))
  104. echo -ne "\033[1;46m \033[m"
  105. done
  106.  
  107. for (( j=0; j<=max_y; j++ ))
  108. do
  109. tput cup $j 0
  110. echo -ne "\033[1;46m \033[m"
  111. tput cup $j $(( max_x<<1 ))
  112. echo -ne "\033[1;46m \033[m"
  113. eval m0_$j=w m${max_x}_$j=w
  114. done
  115. }
  116. clear
  117. draw_wall
  118. run $$&
  119. input $!
  120.  
  121.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty