当前位置: > shell编程 >

Shell游戏:迷宫

时间:2014-09-12 22:38来源:http://bbs.chinaunix.net/ 作者:it
  1. #!/bin/bash
  2.  
  3.  
  4. Width=30  
  5. Height=15  
  6. PadX=10
  7. PadY=5
  8.  
  9.  
  10. P="\033[32mO\033[0m"
  11. PB="\033[4m\033[32mO\033[0m\033[0m"
  12. clear
  13.  
  14. function DrawBox(){     
  15.    local i j inx iny outx outy
  16.    function DrawCell(){
  17.       local cell num  i
  18.       cell=$1; num=$2; str=""
  19.       for((i=1;i<=$num;i++));  do str=$str$cell; done
  20.       echo "$str"
  21.    }
  22.  
  23.    Bank=`DrawCell ' '  $PadX  `           
  24.    Line=`DrawCell "|_" $Width `          
  25.    FirstLine=`DrawCell " _" $Width `
  26.    for((i=1;i<=$PadY;i++));do echo ;done  
  27.    echo "$Bank$FirstLine"                 
  28.    for((j=1;j<=$Height;j++)); do echo  "$Bank$Line|"; done
  29.  
  30.    echo -ne "\033[$((PadY+2));$((PadX+1))H "
  31.    echo -ne "\033[$((PadY+Height+1));$((PadX+Width*2+1))H "
  32. }
  33.  
  34. function CordToKey(){
  35.    local x y Max
  36.    Max=100
  37.    x=$1
  38.    y=$2
  39.    ((x+=Max))
  40.    ((y+=Max))
  41.    echo $x$y
  42. }
  43.  
  44. function Values(){
  45.    local i j
  46.    for((i=PadX+2;i<=PadX+Width*2;i+=2))
  47.    do
  48.       for((j=PadY+2;j<=PadY+Height+1;j++))
  49.       do
  50.         values[`CordToKey $i $j`]="$i|$j"
  51.         buttom[`CordToKey $i $j`]="_"
  52.       done
  53.    done
  54. }
  55.  
  56.  
  57. function DirectionCK(){      
  58.     local X Y D newX newY
  59.     X=$1; Y=$2  
  60.     D=()
  61.  
  62.     ((newY=Y-1))
  63.     [[ ${values[`CordToKey $X $newY`]} =~ "\|" && $X -ne $((PadX+Width*2)) && $X -ne  $((PadX+2)) ]] && D[${#D[*]}]=up
  64.  
  65.     ((newX=X-2))
  66.     [[ ${values[`CordToKey $newX $Y`]} =~ "\|" && $Y -ne $((PadY+2)) && $Y -ne $((PadY+Height+1)) ]] && D[${#D[*]}]=left
  67.  
  68.     ((newY=Y+1))
  69.     [[ ${values[`CordToKey $X $newY`]} =~ "\|" ]] && D[${#D[*]}]=down
  70.  
  71.     ((newX=X+2))
  72.     [[ ${values[`CordToKey $newX $Y`]} =~ "\|" ]] && D[${#D[*]}]=right
  73.  
  74.      echo ${D[*]}
  75. }
  76.  
  77. function DirectionBack(){   
  78.     local k D Dtion Dirtion Dirtions
  79.     while :
  80.     do
  81.        X=${PathX[$step]}
  82.        Y=${PathY[$step]}
  83.        D=${PathD[$step]}
  84.        [[ ${cicle[`CordToKey $X $Y`]} == 1 ]] && { ((step--));continue;}
  85.        Dtion=(`DirectionCK $X $Y`)
  86.        Dirtion=${Dtion[@]%$D}
  87.        Dirtions=(`echo $Dirtion`)
  88.        ClearBack $step
  89.        cicle[`CordToKey $X $Y`]=1
  90.        [[ ${#Dirtions[*]} -gt 0 ]] && break
  91.        ((step--))
  92.     done
  93.     Direction=(`echo ${Dirtions[*]}`)
  94.     ((step--))
  95. }
  96.  
  97. function CreatePath(){
  98.    local Wx Wy
  99.    PathX=()     
  100.    PathY=()     
  101.    PathD=()     
  102.    CWallX=()    
  103.    CWallY=()    
  104.    ClearWalls=()
  105.    step=-1       
  106.    ((X=PadX+2))
  107.    ((Y=PadY+2))
  108.    while :
  109.    do
  110.       Direction=(`DirectionCK $X $Y`)
  111.  
  112.       [[ ${#Direction[*]} -eq 0 ]] && {
  113.              DirectionBack;
  114.       }
  115.       direction=${Direction[$RANDOM%${#Direction[*]}]}
  116.       oldX=$X
  117.       oldY=$Y
  118.       Wx=$X
  119.       Wy=$Y
  120.       ((step++))
  121.       case $direction in
  122.          up)((Y--))
  123.             ((Wy=Y))
  124.             ;;
  125.          down)((Y++))
  126.             ((Wy=Y-1))
  127.             ;;
  128.          left)((X-=2))
  129.             ((Wx=X+1))
  130.             ;;
  131.          right)((X+=2))
  132.             ((Wx=X-1))
  133.             ;;
  134.        esac
  135.        values[`CordToKey $oldX $oldY`]="path"
  136.        values[`CordToKey $Wx $Wy`]="nowall"
  137.        PathX[$step]=$oldX
  138.        PathY[$step]=$oldY
  139.        PathD[$step]=$direction
  140.        CWallX[$step]=$Wx
  141.        CWallY[$step]=$Wy
  142.        [[ $X -eq $((PadX+Width*2)) && $Y -eq $((PadY+Height+1)) ]] && break
  143.    done
  144.    ((step++))
  145.    [[ $X -eq $((PadX+Width*2)) ]] &&  ((Wy=Y-1))
  146.    [[ $Y -eq $((PadY+Height+1)) ]] && ((Wx=X-1))
  147.    CWallX[$step]=$Wx
  148.    CWallY[$step]=$Wy
  149. }
  150.  
  151. function SetButtom(){
  152.     local n x y d
  153.     for((n=0;n<${#PathD[*]};n++))
  154.     do
  155.        x=${PathX[$n]}
  156.        y=${PathY[$n]}
  157.        d=${PathD[$n]}
  158.        [[ $d == "down" ]] && buttom[`CordToKey $x $y`]=""
  159.        ((y--))
  160.        [[ $d == "up" ]] &&  buttom[`CordToKey $x $y`]=""
  161.      done
  162. }
  163.  
  164. function SideRoadCK(){
  165.    local X Y D newX newY
  166.    X=$1; Y=$2  
  167.    D=()
  168.  
  169.    ((newY=Y-1))
  170.    [[ ${values[`CordToKey $X $newY`]} =~ "\|" ]] && D[${#D[*]}]=up
  171.  
  172.    ((newX=X-2))
  173.    [[ ${values[`CordToKey $newX $Y`]} =~ "\|"  ]] && D[${#D[*]}]=left
  174.  
  175.    ((newY=Y+1))
  176.    [[ ${values[`CordToKey $X $newY`]} =~ "\|" ]] && D[${#D[*]}]=down
  177.  
  178.    ((newX=X+2))
  179.    [[ ${values[`CordToKey $newX $Y`]} =~ "\|" ]] && D[${#D[*]}]=right
  180.  
  181.    echo ${D[*]}
  182. }
  183.  
  184.  
  185. function CreateSideRoad(){
  186.    local  loop num i p X Y Direction direction Wx Wy  oldX oldY
  187.    loop=0
  188.    SidePath=()
  189.    SideWall=()
  190.    num=${#PathX[*]}
  191.    while :
  192.    do
  193.       ((p=$RANDOM%num))
  194.       X=${PathX[$p]}
  195.       Y=${PathY[$p]}
  196.       ((loop++))
  197.       while :
  198.       do
  199.          oldX=$X
  200.          oldY=$Y
  201.          Wx=$X
  202.          Wy=$Y
  203.          Direction=(`SideRoadCK $X $Y`)
  204.          [ ${#Direction[*]} -eq 0 ] && break
  205.          direction=${Direction[$RANDOM%${#Direction[*]}]}
  206.          case $direction in
  207.              up)((Y--))
  208.                 ((Wy=Y))
  209.                 buttom[`CordToKey $X $Y`]=""
  210.                 ;;
  211.              down)((Y++))
  212.                 ((Wy=Y-1))
  213.                 buttom[`CordToKey $oldX $oldY`]=""
  214.                 ;;
  215.              left)((X-=2))
  216.                 ((Wx=X+1))
  217.                 ;;
  218.              right)((X+=2))
  219.                 ((Wx=X-1))
  220.                 ;;
  221.          esac
  222.          values[`CordToKey $oldX $oldY`]="sideroad"
  223.          values[`CordToKey $Wx $Wy`]="nowall"
  224.          SidePath[${#SidePath[*]}]=$oldX
  225.          SidePath[${#SidePath[*]}]=$oldY
  226.          SideWall[${#SideWall[*]}]=$Wx
  227.          SideWall[${#SideWall[*]}]=$Wy
  228.       done
  229.       [ $loop -eq 30 ] && break
  230.    done
  231.  
  232. }
  233.  
  234. function ClearBack(){
  235.     local s X Y d
  236.     s=$1
  237.     X=${PathX[$s]}
  238.     Y=${PathY[$s]}
  239.     d=${PathD[$s]}
  240.     values[`CordToKey $X $Y`]="$X|$Y"
  241.     unset PathX[$s]
  242.     unset PathY[$s]
  243.     unset PathD[$s]
  244.     unset CWallX[$s]
  245.     unset CWallY[$s]
  246. }
  247.  
  248. function ClearWall(){
  249.     local i x y
  250.     for((i=0;i<$step;i++))
  251.     do
  252.        x=${CWallX[$i]}
  253.        y=${CWallY[$i]}
  254.        echo -ne "\033[$y;${x}H "
  255.     done
  256. }
  257.  
  258. function ClearSideWall(){
  259.    local i j x y
  260.    for((i=0;i<${#SideWall[*]};i+=2))
  261.    do
  262.        ((j=i+1))
  263.        x=${SideWall[$i]}
  264.        y=${SideWall[$j]}
  265.        echo -ne "\033[$y;${x}H "
  266.    done
  267.  
  268. }
  269.  
  270.  
  271. function MoveP(){
  272.     local X Y oldX oldY  B
  273.     X=$1; Y=$2; oldX=$3; oldY=$4
  274.  
  275.     B="\033[4m \033[0m"
  276.  
  277.     if [[ ${buttom[`CordToKey $oldX $oldY`]} == "_" ]];then
  278.          echo -e "\033[$oldY;${oldX}H$B"
  279.     else
  280.          echo -e "\033[$oldY;${oldX}H "
  281.     fi
  282.  
  283.     if [[ ${buttom[`CordToKey $X $Y`]} == "_" ]];then
  284.          echo -e "\033[$Y;${X}H$PB"
  285.     else
  286.          echo -e "\033[$Y;${X}H$P"
  287.     fi
  288.     if [[ $X -eq $((PadX+Width*2)) && $Y -eq $((PadY+Height+1)) ]];then
  289.         ((WinX=PadX+Width/2))
  290.         ((WinY=PadY+Height+3))
  291.         echo -e "\033[$WinY;${WinX}H\033[31mCongratulation,You Pass!\033[0m"
  292.         Exit
  293.     fi
  294. }
  295.  
  296. function MoveXY(){
  297.    local  D Wx Wy oldX oldY v b
  298.    D=$1
  299.    oldX=$MX
  300.    oldY=$MY
  301.    Wx=$MX
  302.    Wy=$MY
  303.    case $D in
  304.       x++)((Wx=MX+1))
  305.           v=${values[`CordToKey $Wx $Wy`]}
  306.           [[ $v != "nowall" || $MX -gt $((PadX+Width*2)) ]] && continue
  307.           ((MX+=2))
  308.           ;;
  309.       x--)((Wx=MX-1))
  310.           v=${values[`CordToKey $Wx $Wy`]}
  311.           [[ $v != "nowall" || $MX -lt $((PadX+2)) ]] && continue
  312.           ((MX-=2))
  313.           ;;
  314.       y++)b=${buttom[`CordToKey $MX $MY`]}
  315.           [[ $b == "_" || $MY -gt $((PadY+Height+1)) ]] && continue
  316.           ((MY++))
  317.           ;;
  318.       y--)((Wy=MY-1))
  319.           b=${buttom[`CordToKey $MX $Wy`]}
  320.           [[ $b == "_" || $MY -le $((PadY+2)) ]] && continue
  321.           ((MY--))
  322.           ;;
  323.     esac
  324.     MoveP $MX $MY $oldX $oldY
  325. }
  326.  
  327. function Moving(){
  328.    ((MX=PadX+2))
  329.    ((MY=PadY+2))
  330.    if [[ ${buttom[`CordToKey $MX $MY`]} == "_" ]];then
  331.         echo -ne "\033[$MY;${MX}H$PB"
  332.    else
  333.         echo -ne "\033[$MY;${MX}H$P"
  334.    fi
  335.    sTTY=`stty -g`
  336.    echo -ne "\033[?25l"
  337.    trap "Exit" INT TERM
  338.    while :
  339.    do
  340.       read -s -n 1 key
  341.       [[ "$key" == "A" ]] && MoveXY y--
  342.       [[ "$key" == "B" ]] && MoveXY y++
  343.       [[ "$key" == "C" ]] && MoveXY x++
  344.       [[ "$key" == "D" ]] && MoveXY x--
  345.    done
  346.  
  347. }
  348. function Exit(){
  349.   local x y
  350.   ((y=PadY+Height+5))
  351.   echo -e "\033[?25h\033[${y};0H"
  352.   stty $sTTY
  353.   echo -ne "\033[$y;0H"
  354.   exit
  355. }
  356.  
  357. Values
  358. DrawBox
  359. CreatePath
  360. SetButtom
  361. CreateSideRoad
  362. ClearWall
  363. ClearSideWall
  364. Moving
复制代码
玩法:用方向键把小球移到右下角出口处即可。
注:迷宫地图生成比较慢,大约5秒左右,请耐心等候。
 

 

 

mg.jpg


 

GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
测试通过,大牛!!!
 

 

 

f.PNG

http://bbs.chinaunix.net/thread-3579315-1-1.html


(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容