« »
2008-03-16Shell

63

shell写的推箱子(源程序)

#!/bin/sh
#map目录为地图文件目录
#地图文件说明:0:背景、1:墙、2:地板、3:箱子、4:目的地、5:人 9:箱子在目的地

SAVEDTTY=$(stty -g)
echo -ne “\33[?25l"

#画横线
Draw_Line()
{
for((i=2;i<60;i++))
do
      echo -ne "\33[${1};${i}H="
done
}

#画竖线
Draw_Row()
{
for((i=$(($iMapHeight+1));i<=$(($iMapHeight+5));i++))
do
      echo -ne "\33[${i};${1}H "
done
}

#显示帮助信息
Draw_Info()
{
echo -ne "\33[37;42m"
Draw_Line $(($iMapHeight+1))
Draw_Row 1
Draw_Row 60
echo -ne "\33[$(($iMapHeight+5));1H        -- MoveBox CopyRight 2008-02-10 ArchieYao --        \33[0m"
echo -ne "\33[0m\33[$(($iMapHeight+2));2HMan:\33[36;45m**\33[0m   Box:\33[33;42m[]\33[0m \
Destination:\33[34;43m[]\33[0m   Box in Destination:\33[37;46m[]\n”
echo -ne “\33[0m\33[$(($iMapHeight+3));2HPlay:ArrowKey NextLevel:n LastLevel:l Undo:u Redo:r Quit:q\n"
echo -ne "\33[0m\33[$(($iMapHeight+4));2HLevel:$iMapLevel   \n"
}

#计算移动步骤
#==========================================================
Move_Step()
{
if [ "$1" == "+" ]
then
      iMoveSteps=$((iMoveSteps+1))
else
      iMoveSteps=$((iMoveSteps-1))
fi
echo -ne “\33[0m"
echo -ne "\33[$(($iMapHeight+4));18H Steps:$iMoveSteps    \n"
}

#画每一关的地图
#==========================================================
Draw_Map()
{
iDescNum=0 #目的地的数量
iMan_X=0   #人的位置x
iMan_Y=0   #人的位置y
iMoveSteps=0 #移动步数
sMap=$1".map" #地图文件名
iMapWidth=`head -n 1 map/$sMap|wc -L` #地图宽度
iMapHeight=`cat map/$sMap|wc -l`   #地图高度

aDescX=() #aDescX数组,记录目的地位置x
aDescY=() #aDescY数组,记录目的地位置y
aMapArray=() #aMapArray数组

rm -f tsz.undo >/dev/null 2>&1
rm -f tsz.redo >/dev/null 2>&1
clear

y=1
while read LINE
do
    tmp=(`echo "N"$LINE |awk -F "" '{for(i=1;i<=NF;i++){printf("%s ",$i)}}'`) #把坐标设为1起
    for((x=1;x<=$iMapWidth;x++))
    do
      k=$(((y*iMapWidth)+x))
      aMapArray[$k]=${tmp[$x]} #把二维地图转化为一维数组
      x2=$((x*2)) #横向(x)用两个字符表示一格
      case ${tmp[$x]} in
        0) #背景
          echo -ne “\33[34;44m"
          echo -ne "\33[${y};${x2}H[]”
         ;;
        1) #墙
          echo -ne “\33[31;41m"
          echo -ne "\33[${y};${x2}H[]”
          ;;
        2) #地板
          echo -ne “\33[36;47m"
          echo -ne "\33[${y};${x2}H[]”
          ;;
        3) #箱子
          echo -ne “\33[33;42m"
          echo -ne "\33[${y};${x2}H[]”
          ;;
       4) #目的地
          echo -ne “\33[34;43m"
          echo -ne "\33[${y};${x2}H[]”
          aDescX[$iDescNum]=$x
          aDescY[$iDescNum]=$y
          iDescNum=$((iDescNum+1))
          ;;
       5) #人
          echo -ne “\33[36;45m"
          echo -ne "\33[${y};${x2}H**"
          iMan_X=$x
          iMan_Y=$y
          ;;
       9) #箱子在目的地
          echo -ne "\33[37;46m"
          echo -ne "\33[${y};${x2}H[]”
          aDescX[$iDescNum]=$x
          aDescY[$iDescNum]=$y
          iDescNum=$((iDescNum+1))
          ;;
      esac
    done
y=$(($y+1))
done<map/$sMap
Draw_Info
}

#检查是否过关
#==========================================================
Ispass()
{
for((i=0;i<${#aDescX[@]};i++))
do
    iDesc_X=${aDescX[$i]}
    iDesc_Y=${aDescY[$i]}
    if [ ${aMapArray[$(((iDesc_Y*iMapWidth)+iDesc_X))]} -ne 9 ]
    then
      return 0
    fi
done
echo -ne “\33[31m"
#echo -ne "\33[0m"
echo -ne "\33[$(($iMapHeight+4));50H passed!\n"
}

#移动操作
#==========================================================
Move()
{
case $1 in
"up")
    iMove_X1=$((iMan_X*2))
    iMove_Y1=$((iMan_Y-1))
    iMove_X2=$((iMan_X*2))
    iMove_Y2=$((iMan_Y-2))
    iMove_XY1=$((((iMan_Y-1)*iMapWidth)+iMan_X))
    iMove_XY2=$((((iMan_Y-2)*iMapWidth)+iMan_X))
    ;;
"down")
    iMove_X1=$((iMan_X*2))
    iMove_Y1=$((iMan_Y+1))
    iMove_X2=$((iMan_X*2))
    iMove_Y2=$((iMan_Y+2))
    iMove_XY1=$((((iMan_Y+1)*iMapWidth)+iMan_X))
    iMove_XY2=$((((iMan_Y+2)*iMapWidth)+iMan_X))
    ;;
"left")
    iMove_X1=$(((iMan_X-1)*2))
    iMove_Y1=$iMan_Y
    iMove_X2=$(((iMan_X-2)*2))
    iMove_Y2=$iMan_Y
    iMove_XY1=$(((iMan_Y*iMapWidth)+iMan_X-1))
    iMove_XY2=$(((iMan_Y*iMapWidth)+iMan_X-2))
    ;;
"right")
    iMove_X1=$(((iMan_X+1)*2))
    iMove_Y1=$iMan_Y
    iMove_X2=$(((iMan_X+2)*2))
    iMove_Y2=$iMan_Y
    iMove_XY1=$(((iMan_Y*iMapWidth)+iMan_X+1))
    iMove_XY2=$(((iMan_Y*iMapWidth)+iMan_X+2))
    ;;
esac
#判断是否可以移动,判断iMove_X1/y1 是否箱子/墙 判断iMove_X2/y2是否墙
iMan_Xy=$(((iMan_Y*iMapWidth)+iMan_X))

if [ ${aMapArray[iMove_XY1]} -eq 2 -o ${aMapArray[iMove_XY1]} -eq 4 ] #前进方向为地板或目的地
then
    rm -f tsz.redo >/dev/null 2>&1 #移动后不能再redo
    #保存移动记录
    echo “$iMan_Y $iMan_X $iMan_Xy ${aMapArray[iMan_Xy]} $iMove_Y1 $iMove_X1 $iMove_XY1 ${aMapArray[iMove_XY1]} \
$iMove_Y2 $iMove_X2 $iMove_XY2 ${aMapArray[iMove_XY2]}”>>tsz.undo

    #移动人
    echo -ne “\33[36;45m"
    echo -ne "\33[${iMove_Y1};${iMove_X1}H**"
    [[ ${aMapArray[iMove_XY1]} -eq 4 ]] && aMapArray[iMove_XY1]=10      #人走进目的地

    #重画人移动前的位置
    if [ ${aMapArray[iMan_Xy]} -eq 10 ] #原位置在目的地上,则画回目的地
    then
      aMapArray[iMan_Xy]=4
      echo -ne “\33[34;43m"
      echo -ne "\33[${iMan_Y};$((iMan_X*2))H[]”
    else      #否则画地板
      aMapArray[iMan_Xy]=2
      echo -ne “\33[36;47m"
      echo -ne "\33[${iMan_Y};$((iMan_X*2))H[]”
    fi

    iMan_Y=$iMove_Y1
    iMan_X=$((iMove_X1/2))
    Move_Step +
elif [ ${aMapArray[iMove_XY1]} -eq 3 -o ${aMapArray[iMove_XY1]} -eq 9 ] && [ ${aMapArray[iMove_XY2]} -ne 1 -a ${aMapArray[iMove_XY2]} -ne 3 -a ${aMapArray[iMove_XY2]} -ne 9 ] #箱子,且箱子前面无墙无箱子
then
    #保存移动记录
    rm -f tsz.redo >/dev/null 2>&1
    echo “$iMan_Y $iMan_X $iMan_Xy ${aMapArray[iMan_Xy]} $iMove_Y1 $iMove_X1 $iMove_XY1 ${aMapArray[iMove_XY1]} \
$iMove_Y2 $iMove_X2 $iMove_XY2 ${aMapArray[iMove_XY2]}”>>tsz.undo

    #移动人
    echo -ne “\33[36;45m"
    echo -ne "\33[${iMove_Y1};${iMove_X1}H**"
    [[ ${aMapArray[iMove_XY1]} -eq 4 || ${aMapArray[iMove_XY1]} -eq 9 ]] && aMapArray[iMove_XY1]=10      #人走进目的地4/9

    #移动箱子
    if [ ${aMapArray[iMove_XY2]} -eq 4 ]
    then
      echo -ne “\33[37;46m" #箱子移到目的地
      aMapArray[iMove_XY2]=9
    else
      echo -ne “\33[33;42m" #箱子移动到空地板
      aMapArray[iMove_XY2]=3
    fi
    echo -ne “\33[${iMove_Y2};${iMove_X2}H[]”

    #重画人移动前的位置
    if [ ${aMapArray[iMan_Xy]} -eq 10 ] #原人在目的地上,则画回目的地
    then
      aMapArray[iMan_Xy]=4
      echo -ne “\33[34;43m"
      echo -ne "\33[${iMan_Y};$((iMan_X*2))H[]”
    else      #画地板
      aMapArray[iMan_Xy]=2
      echo -ne “\33[36;47m"
      echo -ne "\33[${iMan_Y};$((iMan_X*2))H[]”
    fi
   
    iMan_Y=$iMove_Y1
    iMan_X=$((iMove_X1/2))
    Move_Step +
fi
Ispass
}

#撤消
#==========================================================
Undo()
{
[[ ! -s tsz.undo ]] && return 0
aTmpUndo=(`tail -n 1 tsz.undo`)
aTmpRedo=(`tail -n 1 tsz.undo`)
Move_Step -
#保存当前状态值到redo中
aTmpRedo[3]=${aMapArray[${aTmpUndo[2]}]}
aTmpRedo[7]=${aMapArray[${aTmpUndo[6]}]}
aTmpRedo[11]=${aMapArray[${aTmpUndo[10]}]}
echo ${aTmpRedo[*]}>>tsz.redo

sed -i ‘$d’ tsz.undo

#更改当前状态
aMapArray[${aTmpUndo[2]}]=${aTmpUndo[3]}
aMapArray[${aTmpUndo[6]}]=${aTmpUndo[7]}
aMapArray[${aTmpUndo[10]}]=${aTmpUndo[11]}

#画位置1 (人)
echo -ne “\33[36;45m"
echo -ne "\33[${aTmpUndo[0]};$((${aTmpUndo[1]}*2))H**”
iMan_Y=${aTmpUndo[0]}
iMan_X=${aTmpUndo[1]}

#画位置2 (地板\箱子\目的地)
if [ ${aTmpUndo[7]} -eq 2 ];then   #地板
    echo -ne “\33[36;47m"
elif [ ${aTmpUndo[7]} -eq 3 ];then #箱子在地板上
    echo -ne “\33[33;42m"
elif [ ${aTmpUndo[7]} -eq 9 ];then #箱子在目的地上
    echo -ne “\33[37;46m"
elif [ ${aTmpUndo[7]} -eq 4 ];then #目的地
    echo -ne “\33[34;43m"
fi
echo -ne "\33[${aTmpUndo[4]};${aTmpUndo[5]}H[]”

#画位置3 (地板\目的地)
if [ ${aTmpUndo[11]} -eq 2 ];then       #地板
    echo -ne “\33[36;47m"
elif [ ${aTmpUndo[11]} -eq 4 ];then     #目的地
    echo -ne “\33[34;43m"
else
    return 0
fi
echo -ne "\33[${aTmpUndo[8]};${aTmpUndo[9]}H[]”

}

#重做
#==========================================================
Redo()
{
[[ ! -s tsz.redo ]] && return 0
aTmpRedo=(`tail -n 1 tsz.redo`)
aTmpUndo=(`tail -n 1 tsz.redo`)
Move_Step +
#保存当前状态值到redo中
aTmpUndo[3]=${aMapArray[${aTmpRedo[2]}]}
aTmpUndo[7]=${aMapArray[${aTmpRedo[6]}]}
aTmpUndo[11]=${aMapArray[${aTmpRedo[10]}]}
echo ${aTmpUndo[*]}>>tsz.undo

sed -i ‘$d’ tsz.redo
aMapArray[${aTmpRedo[2]}]=${aTmpRedo[3]}
aMapArray[${aTmpRedo[6]}]=${aTmpRedo[7]}
aMapArray[${aTmpRedo[10]}]=${aTmpRedo[11]}
#画位置1 (地板\目的地)
if [ ${aTmpRedo[3]} -eq 2 ];then        #地板
    echo -ne “\33[36;47m"
elif [ ${aTmpRedo[3]} -eq 4 ];then #目的地
    echo -ne “\33[34;43m"
fi
echo -ne "\33[${aTmpRedo[0]};$((${aTmpRedo[1]}*2))H[]”

#画位置2 (人)
echo -ne “\33[36;45m"
echo -ne "\33[${aTmpRedo[4]};${aTmpRedo[5]}H**”

iMan_Y=${aTmpRedo[4]}
iMan_X=$((${aTmpRedo[5]}/2))

#画位置3 (箱子)
if [ ${aTmpRedo[11]} -eq 3 ];then #箱子在地板上
    echo -ne “\33[33;42m"
    echo -ne "\33[${aTmpRedo[8]};${aTmpRedo[9]}H[]”
elif [ ${aTmpRedo[11]} -eq 9 ];then #箱子在目的地上
    echo -ne “\33[37;46m"
    echo -ne "\33[${aTmpRedo[8]};${aTmpRedo[9]}H[]”
fi
}

#主程序开始
#==========================================================
iMapLevel=1
Draw_Map $iMapLevel

while :
do
read -s -n 1 LINE
case $LINE in
q) #退出
    echo -ne “\33[0m\33[?25h"
    stty $SAVEDTTY
    stty echo
    clear
    rm -f tsz.undo >/dev/null 2>&1
    rm -f tsz.redo >/dev/null 2>&1
    exit 0
    ;;
A) #up
    Move "up"
    ;;
B) #down
    Move "down"
    ;;
D) #left
    Move "left"
    ;;
C) #right
    Move "right"
    ;;
u) #撤消
    Undo
    ;;
r) #重做
    Redo
    ;;
n) #下一关
    if [ $iMapLevel -lt 50 ];then
      echo -ne “\33[0m"
      iMapLevel=$((iMapLevel+1))
      Draw_Map $iMapLevel
    fi
    ;;
l) #上一关
    if [ $iMapLevel -gt 1 ];then
      echo -ne “\33[0m”
      iMapLevel=$((iMapLevel-1))
      Draw_Map $iMapLevel
    fi
    ;;
esac
done
#========================E–N–D===========================

您还可能感兴趣的内容

日志信息 »

该日志于2008-03-16 13:26由 x72 发表在Shell分类下, 通告目前不可用,你可以至底部留下评论。

没有评论

发表评论 »


返回顶部