Advertisement
juanka1uno

Snak3

Oct 30th, 2014
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 4.42 KB | None | 0 0
  1. Create by juanka1uno game SNAK3
  2. #!/bin/bash
  3. IFS=''
  4. declare -i height=30 width=60
  5. # row and column number of head
  6. declare -i head_r head_c tail_r tail_c
  7. declare -i alive
  8. declare -i length
  9. declare body
  10. declare -i direction delta_dir
  11. declare -i score=0
  12. border_color="\E[30;43m"
  13. snake_color="\E[32;42m"
  14. food_color="\E[34;44m"
  15. text_color="\E[31;43m"
  16. no_color="\E[0m"
  17. # signals
  18. SIG_UP=35
  19. SIG_RIGHT=36
  20. SIG_DOWN=37
  21. SIG_LEFT=38
  22. SIG_QUIT=39
  23. SIG_DEAD=40
  24. # direction arrays: 0=up, 1=right, 2=down, 3=left
  25. move_r=([0]=-1 [1]=0 [2]=1 [3]=0)
  26. move_c=([0]=0 [1]=1 [2]=0 [3]=-1)
  27. init_game() {
  28. clear
  29. echo -ne "\033[?25l"
  30. stty -echo
  31. for ((i=0; i<height; i++)); do
  32. for ((j=0; j<width; j++)); do
  33. eval "arr$i[$j]=' '"
  34. done
  35. done
  36. }
  37. move_and_draw() {
  38. echo -ne "\E[${1};${2}H$3"
  39. }
  40. # print everything in the buffer
  41. draw_board() {
  42. move_and_draw 1 1 "$border_color+$no_color"
  43. for ((i=2; i<=width+1; i++)); do
  44. move_and_draw 1 $i "$border_color-$no_color"
  45. done
  46. move_and_draw 1 $((width + 2)) "$border_color+$no_color"
  47. echo
  48. for ((i=0; i<height; i++)); do
  49. move_and_draw $((i+2)) 1 "$border_color|$no_color"
  50. eval echo -en "\"\${arr$i[*]}\""
  51. echo -e "$border_color|$no_color"
  52. done
  53. move_and_draw $((height+2)) 1 "$border_color+$no_color"
  54. for ((i=2; i<=width+1; i++)); do
  55. move_and_draw $((height+2)) $i "$border_color-$no_color"
  56. done
  57. move_and_draw $((height+2)) $((width + 2)) "$border_color+$no_color"
  58. echo
  59. }
  60. # set the snake's initial state
  61. init_snake() {
  62. alive=0
  63. length=10
  64. direction=0
  65. delta_dir=-1
  66. head_r=$((height/2-2))
  67. head_c=$((width/2))
  68. body=''
  69. for ((i=0; i<length-1; i++)); do
  70. body="1$body"
  71. done
  72. local p=$((${move_r[1]} * (length-1)))
  73. local q=$((${move_c[1]} * (length-1)))
  74. tail_r=$((head_r+p))
  75. tail_c=$((head_c+q))
  76. eval "arr$head_r[$head_c]=\"${snake_color}o$no_color\""
  77. prev_r=$head_r
  78. prev_c=$head_c
  79. b=$body
  80. while [ -n "$b" ]; do
  81. # change in each direction
  82. local p=${move_r[$(echo $b | grep -o '^[0-3]')]}
  83. local q=${move_c[$(echo $b | grep -o '^[0-3]')]}
  84. new_r=$((prev_r+p))
  85. new_c=$((prev_c+q))
  86. eval "arr$new_r[$new_c]=\"${snake_color}o$no_color\""
  87. prev_r=$new_r
  88. prev_c=$new_c
  89. b=${b#[0-3]}
  90. done
  91. }
  92. is_dead() {
  93. if [ "$1" -lt 0 ] || [ "$1" -ge "$height" ] || \
  94. [ "$2" -lt 0 ] || [ "$2" -ge "$width" ]; then
  95. return 0
  96. fi
  97. eval "local pos=\${arr$1[$2]}"
  98. if [ "$pos" == "${snake_color}o$no_color" ]; then
  99. return 0
  100. fi
  101. return 1
  102. }
  103. give_food() {
  104. local food_r=$((RANDOM % height))
  105. local food_c=$((RANDOM % width))
  106. eval "local pos=\${arr$food_r[$food_c]}"
  107. while [ "$pos" != ' ' ]; do
  108. food_r=$((RANDOM % height))
  109. food_c=$((RANDOM % width))
  110. eval "pos=\${arr$food_r[$food_c]}"
  111. done
  112. eval "arr$food_r[$food_c]=\"$food_color@$no_color\""
  113. }
  114. move_snake() {
  115. local newhead_r=$((head_r + move_r[direction]))
  116. local newhead_c=$((head_c + move_c[direction]))
  117. eval "local pos=\${arr$newhead_r[$newhead_c]}"
  118. if $(is_dead $newhead_r $newhead_c); then
  119. alive=1
  120. return
  121. fi
  122. if [ "$pos" == "$food_color@$no_color" ]; then
  123. length+=1
  124. eval "arr$newhead_r[$newhead_c]=\"${snake_color}o$no_color\""
  125. body="$(((direction+2)%4))$body"
  126. head_r=$newhead_r
  127. head_c=$newhead_c
  128. score+=1
  129. give_food;
  130. return
  131. fi
  132. head_r=$newhead_r
  133. head_c=$newhead_c
  134. local d=$(echo $body | grep -o '[0-3]$')
  135. body="$(((direction+2)%4))${body%[0-3]}"
  136. eval "arr$tail_r[$tail_c]=' '"
  137. eval "arr$head_r[$head_c]=\"${snake_color}o$no_color\""
  138. # new tail
  139. local p=${move_r[(d+2)%4]}
  140. local q=${move_c[(d+2)%4]}
  141. tail_r=$((tail_r+p))
  142. tail_c=$((tail_c+q))
  143. }
  144. change_dir() {
  145. if [ $(((direction+2)%4)) -ne $1 ]; then
  146. direction=$1
  147. fi
  148. delta_dir=-1
  149. }
  150. getchar() {
  151. trap "" SIGINT SIGQUIT
  152. trap "return;" $SIG_DEAD
  153. while true; do
  154. read -s -n 1 key
  155. case "$key" in
  156. [qQ]) kill -$SIG_QUIT $game_pid
  157. return
  158. ;;
  159. [kK]) kill -$SIG_UP $game_pid
  160. ;;
  161. [lL]) kill -$SIG_RIGHT $game_pid
  162. ;;
  163. [jJ]) kill -$SIG_DOWN $game_pid
  164. ;;
  165. [hH]) kill -$SIG_LEFT $game_pid
  166. ;;
  167. esac
  168. done
  169. }
  170. game_loop() {
  171. trap "delta_dir=0;" $SIG_UP
  172. trap "delta_dir=1;" $SIG_RIGHT
  173. trap "delta_dir=2;" $SIG_DOWN
  174. trap "delta_dir=3;" $SIG_LEFT
  175. trap "exit 1;" $SIG_QUIT
  176. while [ "$alive" -eq 0 ]; do
  177. echo -e "\n${text_color} Your score: $score $no_color"
  178. if [ "$delta_dir" -ne -1 ]; then
  179. change_dir $delta_dir
  180. fi
  181. move_snake
  182. draw_board
  183. sleep 0.03
  184. done
  185. echo -e "${text_color}Oh, No! You 0xdead$no_color"
  186. # signals the input loop that the snake is dead
  187. kill -$SIG_DEAD $$
  188. }
  189. clear_game() {
  190. stty echo
  191. echo -e "\033[?25h"
  192. }
  193. init_game
  194. init_snake
  195. give_food
  196. draw_board
  197. game_loop &
  198. game_pid=$!
  199. getchar
  200. clear_game
  201. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement