셸 탐식 뱀 실현
117229 단어 ------》shell
1. 배경
최근 에 base shell 의 기본 문법 지식 을 체계적으로 보고 싶 었 습 니 다. 그런데 이런 if else 를 본 후에 무엇 을 하 는 지 모 르 고 탐식 뱀 을 썼 다 고 생각 했 습 니 다. 저 는 셸 로 탐식 뱀 을 쓰 는 것 을 처음 생각 한 줄 알 았 습 니 다. 그런데 나중에 누군가가 쓴 것 을 보 았 습 니 다. 그런데 저도 게 으 른 사람 이 라 서 제 생각 으로 이 루어 졌 습 니 다.이러한 기본 적 인 셸 문법 을 익히다.
이 포 인 트 는 셸 문법 을 연습 하고 싶 어서 뱀 을 탐식 하 는 실현 알고리즘 이 중요 한 것 이 아니 라 예전 에 대학 때 각종 작은 게임 들 이 어떤 언어 로 도 썼 는데 이런 작은 알고리즘 들 이 성능 을 고려 하지 않 으 면 정말 재 미 없 었 다.
물론 탐식 뱀 이 가장 잘 사용 하 는 데이터 구 조 는 당연히 stack 이지 만 저 는 셸 로 스 택 을 실현 하 는 것 을 고려 하 는 데 시간 을 들 이 고 싶 지 않 습 니 다. 그래서 정태 적 인 1 차원 배열 과 동태 적 인 1 차원 배열 로 이 루어 졌 습 니 다. (셸 중의 배열 은 원래 동태 적 인 것 입 니 다. 제 가 이렇게 말 하 는 것 은 제 실현 효과 가 이 렇 습 니 다)
2. 환경
win 10 에 설 치 된 Linux 베타 버 전 (ubuntu 14.0) 의 bash
아래 코드 를 복사 할 수 없 는 파트너 가 있다 면 실행 환경 을 고려 하 십시오.
3. 소스 코드
아래 의 중국어 주석 은 방금 추 가 된 것 입 니 다. 이 bash 는 중국 어 를 지원 하지 않 습 니 다. 제 영어 가 정말 엉망 이어서 방금 중국어 주석 을 넣 었 습 니 다.
놀 때 는 상하 좌우 버튼 을 사용 하면 됩 니 다.
주요 한 사 고 는 바로 탐식 뱀 운행 인터페이스 에서 배경 프로 세 스 를 사용 하고 다른 프로 세 스 로 입력 을 감청 하 는 것 이다. (제 생각 은 셸 프로 세 스 였 으 면 좋 겠 습 니 다. 탐식 뱀 운행 중의 대기 시간 에 입력 을 감청 하 는 것 이 었 습 니 다. 나중에 이런 방법 이 있 었 다 는 것 을 알 게 되 었 습 니 다. 저 는 이 를 통 해 신 호 를 전달 하여 처리 하 겠 습 니 다)
#
# the width
with=42
# the height
height=22
#
# area
area=(
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 9
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9
)
#bool
false=0
true=1
#
#snake info
head=47
tail=45
originPos=(45 46 47)
snakeBody=2
snakeFood=3
curPos=(${originPos[*]})
#game logic val
speed=0.2
foodPos=50
left=2
right=-2
up=3
down=-3
moveDirection=$right
eat=$true
#game info
side=$$
main=$!
#
#start show interface
function startShowInterface()
{
seconds=$1
printf "\e[1;42m"
printf "******************************************
"
for ((i=0; i<10; i++))
do
printf "* *
"
done
printf "*******\e[1;31msnake start after: $seconds seconds\e[0m\e[1;42m*******
"
for ((i=0; i<10; i++))
do
printf "* *
"
done
printf "******************************************
"
printf "\e[0m"
}
#start show
function startShow()
{
seconds=1;
while [[ $seconds -gt -1 ]];
do
clear;
startShowInterface $seconds;
sleep 1;
let seconds--;
done
}
startShow;
#
# game main inteface
function gameMainInterface
{
clear;
pos=0
echo -e "\e[1;42m"
for data in ${area[@]};
do
case $data in
[9])
printf "
"
;;
[1])
printf "#"
;;
[0])
printf " "
;;
[$snakeBody])
printf "\e[1;31m"
if [[ $pos = $head ]]; then
printf "@"
else
printf "*"
fi
printf "\e[0m\e[1;42m"
;;
[$snakeFood])
printf "\e[1;34m&\e[0m\e[1;42m"
;;
esac
let pos++
done
echo -e "\e[0m"
}
#initinal snake body and pos
function initSnake()
{
for data in ${originPos[@]};
do
area[$data]=$snakeBody
done
}
initSnake;
#
#draw snake
function drawSnake()
{
for data in ${originPos[@]};
do
area[$data]=0
done
for data in ${curPos[@]};
do
area[$data]=$snakeBody
done
}
#
#generate food
function generateFood()
{
if [[ $eat = $false ]]; then
return
fi
done=$false
while [[ $done = $false ]];
do
newFoodPos=$(( RANDOM%$(( $(( $with-1 ))*$(( $height-1 )) )) ))
[[ ${area[$newFoodPos]} = 0 ]] && area[$foodPos]=0 && foodPos=$newFoodPos && (( area[$foodPos]=$snakeFood )) && done=$true && eat=$false
done
}
# , ,
#move
function snakeMove()
{
originPos=(${curPos[*]})
length=${#curPos[*]}
head=${curPos[$(( $length-1 ))]}
case $moveDirection in
$left)
let head--
[[ $(( $(( $head-2 ))%$with )) -eq 0 ]] && kill -35 $side
;;
$right)
let head++
[[ $(( $head%$with )) -eq 0 ]] && kill -35 $side
;;
$up)
let head=head-with
let head--
[[ $head -lt $with ]] && kill -35 $side
;;
$down)
let head=head+with
let head++
[[ $head -gt $(( $with*$(( $height-1 )) )) ]] && kill -35 $side
;;
esac
if [[ $head -eq $foodPos ]]; then
curPos[length]=$head
eat=$true
else
for ((i=0; i<$((length-1)); i++));
do
curPos[i]=${curPos[$((i+1))]}
done
curPos[$((length-1))]=$head
fi
}
# ,
#main interface
function mainInterface
{
trap "moveDirection=$left" 36
trap "moveDirection=$right" 37
trap "moveDirection=$up" 38
trap "moveDirection=$down" 39
run=$true
while [[ $run -eq $true ]];
do
generateFood;
snakeMove;
drawSnake;
clear;
gameMainInterface;
sleep $speed
done
}
mainInterface &
main=$!
# move snake
function moveDirectionUpdate()
{
if [[ $(( $1+$2 )) -eq 0 || $1 -eq $2 ]];then
return;
fi
case $2 in
$left)
kill -36 $main
;;
$right)
kill -37 $main
;;
$up)
kill -38 $main
;;
$down)
kill -39 $main
;;
esac
}
#
#watch input
function watchInput()
{
curDirection=$left
preDirection=$curDirection
while :;
do
read -s -n 1 op;
[[ $op = "q" ]] && kill -9 $! && return;
[[ $op = "A" ]] && preDirection=$curDirection && curDirection=$up && moveDirectionUpdate $preDirection $curDirection;
[[ $op = "B" ]] && preDirection=$curDirection && curDirection=$down && moveDirectionUpdate $preDirection $curDirection;
[[ $op = "C" ]] && preDirection=$curDirection && curDirection=$right && moveDirectionUpdate $preDirection $curDirection;
[[ $op = "D" ]] && preDirection=$curDirection && curDirection=$left && moveDirectionUpdate $preDirection $curDirection;
done
}
watchInput;
#game over
function gameOver()
{
kill -9 $main
echo "game over."
}
trap "gameOver" 35