当前位置:  技术问答>linux和unix

AIX下工作的选手们辛苦了,来玩会游戏(微雷)

    来源: 互联网  发布时间:2016-11-19

    本文导语:  代码(snake.sh): #!/usr/bin/ksh ############################################################################# # 程序名: snake.sh                                                         # # 时  间: 2011.03.03 ...

代码(snake.sh):

#!/usr/bin/ksh
#############################################################################
# 程序名: snake.sh                                                         #
# 时  间: 2011.03.03                                                       #
# 作  者: hiroyukki                                                        #
# 用  途: 贪食蛇游戏                                                       #
#############################################################################

# 从 ini 文件里获取配置项
function getProperty {
    local INIFILE=$1
    local KEY=$2
    grep "${KEY}" ${INIFILE} | awk -F= '{print $2}'
}

# 读取程序配置
function getConfig {
    if [ ! -f "${CFGFILE}" ]
    then
        echo "未找到配置文件: ${CFGFILE}"
        if [ -f "${SINGLEFILE}" ]
        then
            rm -f ${SINGLEFILE}
        fi
        return -1
    fi
    getProperty ${CFGFILE} "bodyColor" | read color
    if [ -z "${color}" ]
    then
        color=BLACK
    fi
    case ${color} in
        RED) 
            BDCOLOR=31;;
        GREEN) 
            BDCOLOR=32;;
        BLACK) 
            BDCOLOR=30;;
        YELLOW) 
            BDCOLOR=33;;
        CYAN) 
            BDCOLOR=36;;
        *) 
            echo "Invalid color: ${color}"
            return -1
    esac

    getProperty ${CFGFILE} "foodColor" | read color
    if [ -z "${color}" ]
    then
        color=BLACK
    fi
    case ${color} in
        RED) 
            FDCOLOR=31;;
        GREEN) 
            FDCOLOR=32;;
        BLACK) 
            FDCOLOR=30;;
        YELLOW) 
            FDCOLOR=33;;
        CYAN) 
            FDCOLOR=36;;
        *) 
            echo "Invalid color: ${color}"
            return -1
    esac
    
    return 0
}

# 移动到目标坐标并输出第三个参数
function moveTo {
    echo "[$1;$2H$3"
}

# 该函数接受3个参数,第一个是下限,第二个是上限,第三个传1生成奇数
function random {
    # 如果参数少于3个,返回0
    if [ $# -lt 3 ]
    then
        return 0
    fi
    curSec=`date "+%M%S" | cut -c3-4`
    curMin=`date "+%M%S" | cut -c1-2`
    tmp=`expr $2 - $1`
    sec=`expr ${curMin} * 60 + ${curSec}`
    result=`expr ${sec} % ${tmp}`
    result=`expr ${result} + $1 + 1`
    # 如果参数3传的是1,则生成奇数
    if [ $3 -eq "1" ]
    then
        tmp=`expr ${result} % 2`
        if [ ${tmp} -eq 0 ]
        then
            result=`expr ${result} - 1`
        fi
    fi 
    echo $result
}

# 绘制墙壁
function drawWall {
    moveTo 1 1 "■■■■■■■■■■■■■■■■"
    for i in 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    do
        moveTo ${i} 1 "■                            ■"
    done
    moveTo 16 1 "■■■■■■■■■■■■■■■■"
}

# 输出蛇身
function drawBody {
    moveTo $1 $2 "[${BDCOLOR}m■[40m[0m"
}

# 画食物
function drawFood {
    moveTo $1 $2 "[${FDCOLOR}m■[40m[0m"
}

# 绘制分数
function drawScore {
    local SCORE=$1
    moveTo 18 13 "[41m得分:${SCORE}[40m[0m"
}

# 绘制死亡通知,这里不用再取SCORE了,能执行至此,前面肯定取过至少一次
# 死亡,其实名字起的不对,应该是结束,包含胜利结束和撞墙(撞自己)结束
# 传参数1表示死亡,0表示胜利
function drawDie {
    local REASON=$1
    if [ "${REASON}" = "0" ]
    then
        moveTo 18 6 "[41m您胜利了!您的得分:${SCORE}[40m[0m"
        return
    fi
    moveTo 18 6 "[41m游戏结束,您的得分:${SCORE}[40m[0m"
}

# 退出时通知子进程退出
function onExit {
    echo "exit" > ${CTLFILE} 
    if [ -f "${TMPFILE}" ]
    then
        rm -f ${TMPFILE} > /dev/null
    fi
    
    if [ -f "${DRCTFILE}" ]
    then
        rm -f ${DRCTFILE} > /dev/null
    fi
    
    if [ -f "${SINGLEFILE}" ]
    then
        rm -f ${SINGLEFILE} > /dev/null
    fi
    
    # 让子进程退出的权宜之计……
    # 似乎不需要,虽然子进程是后台,但是他爹在活着,杀他爹时他也死?
    # 就是说子进程根本来不及清理,因为他没捕获信号,没关系,他爹死前清理就行了
    # 事实上,只有用户正常退出(输入Q)后,才会由子进程清理控制文件
    echo "等待子进程退出..."
    sleep 2
    if [ -f "${CTLFILE}" ]
    then
        rm -f ${CTLFILE} > /dev/null
    fi
    clear
    exit 0
}

# 吃掉一个食物,吃的时候比较简单,就是把食物标志变成身体标志而已,但要放在其他所有
# 身体结点前,因为食物的位置已经是新的头了
function eat {
    grep "score" ${CTLFILE} | awk -F':' '{print $2}' | read SCORE
    if [ -z "${SCORE}" ]
    then
        SCORE=0
    fi
    SCORE=`expr ${SCORE} + 10`
    grep "food" ${CTLFILE} > ${TMPFILE}
    grep "body" ${CTLFILE} >> ${TMPFILE}
    echo "score:${SCORE}" >> ${TMPFILE}
    sed 's/food/body/g' ${TMPFILE} > ${CTLFILE}
    nextFood
}

# 生成下一个食物,没考虑生成到蛇身上的情况,管它呢
function nextFood {
    FOODX=`random 2 15 0`
    FOODY=`random 2 28 1`
    grep -v "food" ${CTLFILE} > ${TMPFILE}
    echo "food:${FOODX}:${FOODY}" >> ${TMPFILE}
    cp ${TMPFILE} ${CTLFILE}
}

# 是否在下一步能吃到食物,返回0表示能,返回1表示正常,
# 返回2表示我被自己撞了一下腰或我被石头撞了一下头
function isPieFromSky {
    # 取当前蛇头位置,根据方向计算出下一个要走的位置
    HEADX=`grep "body" ${CTLFILE} | head -n1 | awk -F':' '{print $2}'`
    HEADY=`grep "body" ${CTLFILE} | head -n1 | awk -F':' '{print $3}'`
    NEXTX=${HEADX}
    NEXTY=${HEADY}
    DIRECTION=`cat ${DRCTFILE}`
    if [ "${DIRECTION}" = "${UP}" ]
    then
        NEXTX=`expr ${NEXTX} - 1`
    elif [ "${DIRECTION}" = "${LEFT}" ]
    then
        NEXTY=`expr ${NEXTY} - 2`
    elif [ "${DIRECTION}" = "${DOWN}" ]
    then
        NEXTX=`expr ${NEXTX} + 1`
    elif [ "${DIRECTION}" = "${RIGHT}" ]
    then
        NEXTY=`expr ${NEXTY} + 2`
    fi
    
    # X Y都不能越墙,否则是撞
    if [ ${NEXTX} -gt 15 -o ${NEXTX} -lt 2 -o ${NEXTY} -gt 30 -o ${NEXTY} -lt 2 ]
    then
        return 2
    fi
    
    # 撞自己了
    LINES=`grep "body:${NEXTX}:${NEXTY}" ${CTLFILE} | wc | awk '{print $1}'`
    if [ ${LINES} -ne 0 ]
    then
        return 2
    fi
    
    FOODX=`grep "food" ${CTLFILE} | awk -F':' '{print $2}'`
    FOODY=`grep "food" ${CTLFILE} | awk -F':' '{print $3}'`
    if [ "${NEXTX}" = "${FOODX}" -a "${NEXTY}" = "${FOODY}" ]
    then
        return 0
    fi
    
    return 1
}

# 生成蛇头,初始化调用
function genHead {
    grep -v "body" ${CTLFILE} > ${TMPFILE}
    echo "body:2:3" >> ${TMPFILE}
    cp ${TMPFILE} ${CTLFILE}
}

# 蛇移动,所谓蛇移动,其实是把蛇尾放到蛇头的下一个位置如有10个身体结点
# 则前9个不动,第十个放到第一个的下一个位置,这个位置和方向有关系
# 如此,至少在视觉上,他在移动……
# 这里有个取巧的地方,已知只有在判断是否天上掉馅饼后才做此调用,故可用天上掉馅饼
# 函数中已经得到的数据,如 NEXTX
function goGoGo {
    # 先获取身体结点个数
    LINES=`grep "body" ${CTLFILE} | wc | awk '{print $1}'`
    # 直接生成一个新的放前面
    echo "body:${NEXTX}:${NEXTY}" > ${TMPFILE}
    HEADLINE=`expr ${LINES} - 1`
    grep "body" ${CTLFILE} | head -n${HEADLINE} >> ${TMPFILE}
    grep -v "body" ${CTLFILE} >> ${TMPFILE}
    cp ${TMPFILE} ${CTLFILE}
}

# 死的时候,杀自己爹,伦理丧失啊,通过杀自己爹,让自己爹清理部分东西,
# 并且自己爹临死时会给自己交待后事
# 我好像理解错误,对函数使用 & 这个函数还是在同一个进程里?也就是说父的说法不成立?
# 其实应该 kill ${PID} 而不是 kill ${PPID}?
# 在AIX下, 两者竟然都通过, redhat下,两者都不能成功杀
# 如果是同一个进程,意思是说,exit就行了?
function die {
    drawDie $1
    kill -2 $$
}

# 分数过200就算赢了,赢了程序退出,同样杀爹……
function win {
    die 0
}

# 这是独立的一个进程,用来检测当前游戏状态并绘制
function moveThread {
    # 先生成下一个食物
    nextFood
    # 生成蛇头
    genHead
    THREADID=`echo $$`
    echo "${RIGHT}" > ${DRCTFILE}
    while true
    do
        # 先查看是否有退出标志
        grep "exit" ${CTLFILE} | wc | read LINE DISCARD
        if [ "${LINE}" = "1" ]
        then
            rm -f ${CTLFILE} > /dev/null
            return
        fi
        
        # 画上墙
        drawWall
        
        # 画分数
        SCORE=`grep "score" ${CTLFILE} | awk -F':' '{print $2}'`
        if [ -z "${SCORE}" ]
        then
            SCORE=0
        fi
        drawScore ${SCORE}
        if [ ${SCORE} -gt 190 ]
        then
            win
        fi
        
        # 画食物
        X=`grep "food" ${CTLFILE} | awk -F':' '{print $2}'`
        Y=`grep "food" ${CTLFILE} | awk -F':' '{print $3}'`
        if [ -z "${X}" -o -z "${Y}" ]
        then
            echo "Food not found!"
            die
            continue
        fi
        drawFood ${X} ${Y}
        
        # 如果撞上食物,吃!,如果撞上墙,死!否则正常走
        isPieFromSky
        RETVAL=$?
        if [ ${RETVAL} -eq 0 ]
        then
            eat
        elif [ ${RETVAL} -eq 2 ]
        then
            die
        else
            goGoGo
        fi
        
        # 没死的话,画身体吧
        grep "body" ${CTLFILE} | awk -F':' '{print $2" "$3}' | while read X Y
        do
            drawBody ${X} ${Y}
        done
        
        sleep 1
    done
}

# 获取当前蛇的前进方向
function getCurDrct {
    cat ${DRCTFILE} | read DIRECTION
    if [ -z "${DIRECTION}" ]
    then
        DIRECTION=0
    fi
    
    return ${DIRECTION}
}

# 游戏开始
function gameStart {
    clear
    touch ${CFGFILE} ${CTLFILE} ${DRCTFILE}
    moveThread &
    # 循环读用户输入来改变蛇的方向,有个需要注意的是,比如,当前方向是右,则不能直接转向左
    while true
    do
        read INPUT
        case ${INPUT} in
            a|A)
                getCurDrct
                if [ $? -ne ${RIGHT} ]
                then
                    echo "${LEFT}" > ${DRCTFILE}
                fi
                ;;
            s|S)
                getCurDrct
                if [ $? -ne ${UP} ]
                then
                    echo "${DOWN}" > ${DRCTFILE}
                fi
                ;;
            d|D)
                getCurDrct
                if [ $? -ne ${LEFT} ]
                then
                    echo "${RIGHT}" > ${DRCTFILE}
                fi
                ;;
            w|W)
                getCurDrct
                if [ $? -ne ${DOWN} ]
                then
                    echo "${UP}" > ${DRCTFILE}
                fi
                ;;
            q|Q)
                onExit;;
            *)
                continue;;
        esac
    done
    return 0
}

SINGLEFILE=${HOME}/.snake.flag
if [ -f "${SINGLEFILE}" ]
then
    echo "已经有一个实例在运行!"
    exit 0
fi
touch ${SINGLEFILE}
MAXX=8
MAXY=17
LEFT=1
DOWN=2
RIGHT=3
UP=4
CFGFILE=snake.ini
TMPFILE=.snake.tmp
CTLFILE=.snake.ctl
DRCTFILE=.snake.drct
USER=`whoami`
trap "onExit" 2 3
getConfig
[ $? -ne 0 ] && exit 0
gameStart


配置(snake.ini):

foodColor=GREEN
wallColor=CYAN
bodyColor=RED

|
支持支持

|
支持楼主,这样也能玩

|
好牛x

|

|
那好像只是个网盘~

支持楼主~!~

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 公告:CSDN AIX论坛有奖话题讨论活动(六)——本期话题:AIX的动态工作负载分区和Hypervisor的逻辑分区相比,有何优劣?
  • Oracle10g在AIX上的安装准备工作《Oracle大型数据库系统在AIX/unix上的实战详解》 集中答疑 40
  • AIX 5.3下调用windows 2000上的exe程序,且AIX下需要得到windows下程序执行的返回结果
  • AIX目前最新的编译器都支持C++0x标准里的那些内容?GCC 4.5.0是否能够在AIX上安装?
  • 公告:CSDN AIX论坛有奖话题讨论活动(七)——本期话题:在海量运算方面,和Linux系统相比,AIX系统有优势吗?
  • 哪里可以下载AIX操作系统?
  • 公告:CSDN AIX论坛有奖话题讨论活动(四)——本期话题:从开发周期上来看,和HP-UX、Solaris相比,AIX系统有优势吗?
  • 公告:CSDN AIX论坛有奖话题讨论活动(八)——本期话题:除了数据库应用,还有哪些应用也可以运行于AIX系统之上?(和Linux系统相比较,性能更优)
  • AIX共享内存分配问题
  • 求GCC for AIX5.3
  • aix上编译问题
  • linux -> aix 发展
  • 有关 AIX 编程兼容性方面的疑问
  • aix问题求教--愿给200分!!!
  • 关于AIX的进程间通讯的方法
  • window 向aix 的移植问题----在线等待
  • 普通pc机,可否装aix操作系统?
  • 有谁在AIX下装过下载版的websphere
  • IBM AIX可以用其他的unix 或者 lunix代替吗?
  • 请问AIX下用什么命令能够获取CPU型号、频率信息,多CPU情况下
  • 在AIX(4.3)系统上如何查看内存情况
  • 请教一个AIX下内存分配的问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3