• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0
            #!/bin/bash

            # Tetris Game
            # 10.21.2003 xhchen<[email]xhchen@winbond.com.tw[/email]>

            #APP declaration
            APP_NAME="${0##*[\\/]}"
            APP_VERSION="1.0"


            #顏色定義
            cRed=1
            cGreen=2
            cYellow=3
            cBlue=4
            cFuchsia=5
            cCyan=6
            cWhite=7
            colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)

            #位置和大小
            iLeft=3
            iTop=2
            ((iTrayLeft = iLeft + 2))
            ((iTrayTop = iTop + 1))
            ((iTrayWidth = 10))
            ((iTrayHeight = 15))

            #顏色設(shè)置
            cBorder=$cGreen
            cScore=$cFuchsia
            cScoreValue=$cCyan

            #控制信號
            #改游戲使用兩個進程,一個用于接收輸入,一個用于游戲流程和顯示界面;
            #當前者接收到上下左右等按鍵時,通過向后者發(fā)送signal的方式通知后者。
            sigRotate=25
            sigLeft=26
            sigRight=27
            sigDown=28
            sigAllDown=29
            sigExit=30

            #七中不同的方塊的定義
            #通過旋轉(zhuǎn),每種方塊的顯示的樣式可能有幾種
            box0=(0 0 0 1 1 0 1 1)
            box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
            box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
            box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
            box4=(0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2)
            box5=(0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2)
            box6=(0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 1 2)
            #所有其中方塊的定義都放到box變量中
            box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})
            #各種方塊旋轉(zhuǎn)后可能的樣式數(shù)目
            countBox=(1 2 2 2 4 4 4)
            #各種方塊再box數(shù)組中的偏移
            offsetBox=(0 1 3 5 7 11 15)

            #每提高一個速度級需要積累的分數(shù)
            iScoreEachLevel=50        #be greater than 7

            #運行時數(shù)據(jù)
            sig=0                #接收到的signal
            iScore=0        #總分
            iLevel=0        #速度級
            boxNew=()        #新下落的方塊的位置定義
            cBoxNew=0        #新下落的方塊的顏色
            iBoxNewType=0        #新下落的方塊的種類
            iBoxNewRotate=0        #新下落的方塊的旋轉(zhuǎn)角度
            boxCur=()        #當前方塊的位置定義
            cBoxCur=0        #當前方塊的顏色
            iBoxCurType=0        #當前方塊的種類
            iBoxCurRotate=0        #當前方塊的旋轉(zhuǎn)角度
            boxCurX=-1        #當前方塊的x坐標位置
            boxCurY=-1        #當前方塊的y坐標位置
            iMap=()                #背景方塊圖表

            #初始化所有背景方塊為-1, 表示沒有方塊
            for ((i = 0; i < iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; done


            #接收輸入的進程的主函數(shù)
            function RunAsKeyReceiver()
            {
                    local pidDisplayer key aKey sig cESC sTTY

                    pidDisplayer=$1
                    aKey=(0 0 0)

                    cESC=`echo -ne "\033"`
                    cSpace=`echo -ne "\040"`

                    #保存終端屬性。在read -s讀取終端鍵時,終端的屬性會被暫時改變。
                    #如果在read -s時程序被不幸殺掉,可能會導(dǎo)致終端混亂,
                    #需要在程序退出時恢復(fù)終端屬性。
                    sTTY=`stty -g`

                    #捕捉退出信號
                    trap "MyExit;" INT TERM
                    trap "MyExitNoSub;" $sigExit

                    #隱藏光標
                    echo -ne "\033[?25l"


                    while :
                    do
                            #讀取輸入。注-s不回顯,-n讀到一個字符立即返回
                            read -s -n 1 key

                            aKey[0]=${aKey[1]}
                            aKey[1]=${aKey[2]}
                            aKey[2]=$key
                            sig=0

                            #判斷輸入了何種鍵
                            if [[ $key == $cESC && ${aKey[1]} == $cESC ]]
                            then
                                    #ESC鍵
                                    MyExit
                            elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]
                            then
                                    if [[ $key == "A" ]]; then sig=$sigRotate        #<向上鍵>
                                    elif [[ $key == "B" ]]; then sig=$sigDown        #<向下鍵>
                                    elif [[ $key == "D" ]]; then sig=$sigLeft        #<向左鍵>
                                    elif [[ $key == "C" ]]; then sig=$sigRight        #<向右鍵>
                                    fi
                            elif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate        #W, w
                            elif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown        #S, s
                            elif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft        #A, a
                            elif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight        #D, d
                            elif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown        #空格鍵
                            elif [[ $key == "Q" || $key == "q" ]]                        #Q, q
                            then
                                    MyExit
                            fi

                            if [[ $sig != 0 ]]
                            then
                                    #向另一進程發(fā)送消息
                                    kill -$sig $pidDisplayer
                            fi
                    done
            }

            #退出前的恢復(fù)
            function MyExitNoSub()
            {
                    local y

                    #恢復(fù)終端屬性
                    stty $sTTY
                    ((y = iTop + iTrayHeight + 4))

                    #顯示光標
                    echo -e "\033[?25h\033[${y};0H"
                    exit
            }


            function MyExit()
            {
                    #通知顯示進程需要退出
                    kill -$sigExit $pidDisplayer

                    MyExitNoSub
            }


            #處理顯示和游戲流程的主函數(shù)
            function RunAsDisplayer()
            {
                    local sigThis
                    InitDraw

                    #掛載各種信號的處理函數(shù)
                    trap "sig=$sigRotate;" $sigRotate
                    trap "sig=$sigLeft;" $sigLeft
                    trap "sig=$sigRight;" $sigRight
                    trap "sig=$sigDown;" $sigDown
                    trap "sig=$sigAllDown;" $sigAllDown
                    trap "ShowExit;" $sigExit

                    while :
                    do
                            #根據(jù)當前的速度級iLevel不同,設(shè)定相應(yīng)的循環(huán)的次數(shù)
                            for ((i = 0; i < 21 - iLevel; i++))
                            do
                                    sleep 0.02
                                    sigThis=$sig
                                    sig=0

                                    #根據(jù)sig變量判斷是否接受到相應(yīng)的信號
                                    if ((sigThis == sigRotate)); then BoxRotate;        #旋轉(zhuǎn)
                                    elif ((sigThis == sigLeft)); then BoxLeft;        #左移一列
                                    elif ((sigThis == sigRight)); then BoxRight;        #右移一列
                                    elif ((sigThis == sigDown)); then BoxDown;        #下落一行
                                    elif ((sigThis == sigAllDown)); then BoxAllDown;        #下落到底
                                    fi
                            done
                            #kill -$sigDown $$
                            BoxDown        #下落一行
                    done
            }


            #BoxMove(y, x), 測試是否可以把移動中的方塊移到(x, y)的位置, 返回0則可以, 1不可以
            function BoxMove()
            {
                    local j i x y xTest yTest
                    yTest=$1
                    xTest=$2
                    for ((j = 0; j < 8; j += 2))
                    do
                            ((i = j + 1))
                            ((y = ${boxCur[$j]} + yTest))
                            ((x = ${boxCur[$i]} + xTest))
                            if (( y < 0 || y >= iTrayHeight || x < 0 || x >= iTrayWidth))
                            then
                                    #撞到墻壁了
                                    return 1
                            fi
                            if ((${iMap[y * iTrayWidth + x]} != -1 ))
                            then
                                    #撞到其他已經(jīng)存在的方塊了
                                    return 1
                            fi
                    done
                    return 0;
            }


            #將當前移動中的方塊放到背景方塊中去,
            #并計算新的分數(shù)和速度級。(即一次方塊落到底部)
            function Box2Map()
            {
                    local j i x y xp yp line

                    #將當前移動中的方塊放到背景方塊中去
                    for ((j = 0; j < 8; j += 2))
                    do
                            ((i = j + 1))
                            ((y = ${boxCur[$j]} + boxCurY))
                            ((x = ${boxCur[$i]} + boxCurX))
                            ((i = y * iTrayWidth + x))
                            iMap[$i]=$cBoxCur
                    done

                    #消去可被消去的行
                    line=0
                    for ((j = 0; j < iTrayWidth * iTrayHeight; j += iTrayWidth))
                    do
                            for ((i = j + iTrayWidth - 1; i >= j; i--))
                            do
                                    if ((${iMap[$i]} == -1)); then break; fi
                            done
                            if ((i >= j)); then continue; fi

                            ((line++))
                            for ((i = j - 1; i >= 0; i--))
                            do
                                    ((x = i + iTrayWidth))
                                    iMap[$x]=${iMap[$i]}
                            done
                            for ((i = 0; i < iTrayWidth; i++))
                            do
                                    iMap[$i]=-1
                            done
                    done

                    if ((line == 0)); then return; fi

                    #根據(jù)消去的行數(shù)line計算分數(shù)和速度級
                    ((x = iLeft + iTrayWidth * 2 + 7))
                    ((y = iTop + 11))
                    ((iScore += line * 2 - 1))
                    #顯示新的分數(shù)
                    echo -ne "\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore}         "
                    if ((iScore % iScoreEachLevel < line * 2 - 1))
                    then
                            if ((iLevel < 20))
                            then
                                    ((iLevel++))
                                    ((y = iTop + 14))
                                    #顯示新的速度級
                                    echo -ne "\033[3${cScoreValue}m\033[${y};${x}H${iLevel}        "
                            fi
                    fi
                    echo -ne "\033[0m"


                    #重新顯示背景方塊
                    for ((y = 0; y < iTrayHeight; y++))
                    do
                            ((yp = y + iTrayTop + 1))
                            ((xp = iTrayLeft + 1))
                            ((i = y * iTrayWidth))
                            echo -ne "\033[${yp};${xp}H"
                            for ((x = 0; x < iTrayWidth; x++))
                            do
                                    ((j = i + x))
                                    if ((${iMap[$j]} == -1))
                                    then
                                            echo -ne "  "
                                    else
                                            echo -ne "\033[1m\033[7m\033[3${iMap[$j]}m\033[4${iMap[$j]}m[]\033[0m"
                                    fi
                            done
                    done
            }


            #下落一行
            function BoxDown()
            {
                    local y s
                    ((y = boxCurY + 1))        #新的y坐標
                    if BoxMove $y $boxCurX        #測試是否可以下落一行
                    then
                            s="`DrawCurBox 0`"        #將舊的方塊抹去
                            ((boxCurY = y))
                            s="$s`DrawCurBox 1`"        #顯示新的下落后方塊
                            echo -ne $s
                    else
                            #走到這兒, 如果不能下落了
                            Box2Map                #將當前移動中的方塊貼到背景方塊中
                            RandomBox        #產(chǎn)生新的方塊
                    fi
            }

            #左移一列
            function BoxLeft()
            {
                    local x s
                    ((x = boxCurX - 1))
                    if BoxMove $boxCurY $x
                    then
                            s=`DrawCurBox 0`
                            ((boxCurX = x))
                            s=$s`DrawCurBox 1`
                            echo -ne $s
                    fi
            }

            #右移一列
            function BoxRight()
            {
                    local x s
                    ((x = boxCurX + 1))
                    if BoxMove $boxCurY $x
                    then
                            s=`DrawCurBox 0`
                            ((boxCurX = x))
                            s=$s`DrawCurBox 1`
                            echo -ne $s
                    fi
            }


            #下落到底
            function BoxAllDown()
            {
                    local k j i x y iDown s
                    iDown=$iTrayHeight

                    #計算一共需要下落多少行
                    for ((j = 0; j < 8; j += 2))
                    do
                            ((i = j + 1))
                            ((y = ${boxCur[$j]} + boxCurY))
                            ((x = ${boxCur[$i]} + boxCurX))
                            for ((k = y + 1; k < iTrayHeight; k++))
                            do
                                    ((i = k * iTrayWidth + x))
                                    if (( ${iMap[$i]} != -1)); then break; fi
                            done
                            ((k -= y + 1))
                            if (( $iDown > $k )); then iDown=$k; fi
                    done

                    s=`DrawCurBox 0`        #將舊的方塊抹去
                    ((boxCurY += iDown))
                    s=$s`DrawCurBox 1`        #顯示新的下落后的方塊
                    echo -ne $s
                    Box2Map                #將當前移動中的方塊貼到背景方塊中
                    RandomBox        #產(chǎn)生新的方塊
            }


            #旋轉(zhuǎn)方塊
            function BoxRotate()
            {
                    local iCount iTestRotate boxTest j i s
                    iCount=${countBox[$iBoxCurType]}        #當前的方塊經(jīng)旋轉(zhuǎn)可以產(chǎn)生的樣式的數(shù)目

                    #計算旋轉(zhuǎn)后的新的樣式
                    ((iTestRotate = iBoxCurRotate + 1))
                    if ((iTestRotate >= iCount))
                    then
                            ((iTestRotate = 0))
                    fi

                    #更新到新的樣式, 保存老的樣式(但不顯示)
                    for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))
                    do
                            boxTest[$j]=${boxCur[$j]}
                            boxCur[$j]=${box[$i]}
                    done

                    if BoxMove $boxCurY $boxCurX        #測試旋轉(zhuǎn)后是否有空間放的下
                    then
                            #抹去舊的方塊
                            for ((j = 0; j < 8; j++))
                            do
                                    boxCur[$j]=${boxTest[$j]}
                            done
                            s=`DrawCurBox 0`

                            #畫上新的方塊
                            for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))
                            do
                                    boxCur[$j]=${box[$i]}
                            done
                            s=$s`DrawCurBox 1`
                            echo -ne $s
                            iBoxCurRotate=$iTestRotate
                    else
                            #不能旋轉(zhuǎn),還是繼續(xù)使用老的樣式
                            for ((j = 0; j < 8; j++))
                            do
                                    boxCur[$j]=${boxTest[$j]}
                            done
                    fi
            }


            #DrawCurBox(bDraw), 繪制當前移動中的方塊, bDraw為1, 畫上, bDraw為0, 抹去方塊。
            function DrawCurBox()
            {
                    local i j t bDraw sBox s
                    bDraw=$1

                    s=""
                    if (( bDraw == 0 ))
                    then
                            sBox="\040\040"
                    else
                            sBox="[]"
                            s=$s"\033[1m\033[7m\033[3${cBoxCur}m\033[4${cBoxCur}m"
                    fi

                    for ((j = 0; j < 8; j += 2))
                    do
                            ((i = iTrayTop + 1 + ${boxCur[$j]} + boxCurY))
                            ((t = iTrayLeft + 1 + 2 * (boxCurX + ${boxCur[$j + 1]})))
                            #\033[y;xH, 光標到(x, y)處
                            s=$s"\033[${i};${t}H${sBox}"
                    done
                    s=$s"\033[0m"
                    echo -n $s
            }


            #更新新的方塊
            function RandomBox()
            {
                    local i j t

                    #更新當前移動的方塊
                    iBoxCurType=${iBoxNewType}
                    iBoxCurRotate=${iBoxNewRotate}
                    cBoxCur=${cBoxNew}
                    for ((j = 0; j < ${#boxNew[@]}; j++))
                    do
                            boxCur[$j]=${boxNew[$j]}
                    done


                    #顯示當前移動的方塊
                    if (( ${#boxCur[@]} == 8 ))
                    then
                            #計算當前方塊該從頂端哪一行"冒"出來
                            for ((j = 0, t = 4; j < 8; j += 2))
                            do
                                    if ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fi
                            done
                            ((boxCurY = -t))
                            for ((j = 1, i = -4, t = 20; j < 8; j += 2))
                            do
                                    if ((${boxCur[$j]} > i)); then i=${boxCur[$j]}; fi
                                    if ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fi
                            done
                            ((boxCurX = (iTrayWidth - 1 - i - t) / 2))

                            #顯示當前移動的方塊
                            echo -ne `DrawCurBox 1`

                            #如果方塊一出來就沒處放,Game over!
                            if ! BoxMove $boxCurY $boxCurX
                            then
                                    kill -$sigExit ${PPID}
                                    ShowExit
                            fi
                    fi



                    #清除右邊預(yù)顯示的方塊
                    for ((j = 0; j < 4; j++))
                    do
                            ((i = iTop + 1 + j))
                            ((t = iLeft + 2 * iTrayWidth + 7))
                            echo -ne "\033[${i};${t}H        "
                    done

                    #隨機產(chǎn)生新的方塊
                    ((iBoxNewType = RANDOM % ${#offsetBox[@]}))
                    ((iBoxNewRotate = RANDOM % ${countBox[$iBoxNewType]}))
                    for ((j = 0, i = (${offsetBox[$iBoxNewType]} + $iBoxNewRotate) * 8; j < 8; j++, i++))
                    do
                            boxNew[$j]=${box[$i]};
                    done

                    ((cBoxNew = ${colorTable[RANDOM % ${#colorTable[@]}]}))

                    #顯示右邊預(yù)顯示的方塊
                    echo -ne "\033[1m\033[7m\033[3${cBoxNew}m\033[4${cBoxNew}m"
                    for ((j = 0; j < 8; j += 2))
                    do
                            ((i = iTop + 1 + ${boxNew[$j]}))
                            ((t = iLeft + 2 * iTrayWidth + 7 + 2 * ${boxNew[$j + 1]}))
                            echo -ne "\033[${i};${t}H[]"
                    done
                    echo -ne "\033[0m"
            }


            #初始繪制
            function InitDraw()
            {
                    clear
                    RandomBox        #隨機產(chǎn)生方塊,這時右邊預(yù)顯示窗口中有方快了
                    RandomBox        #再隨機產(chǎn)生方塊,右邊預(yù)顯示窗口中的方塊被更新,原先的方塊將開始下落
                    local i t1 t2 t3

                    #顯示邊框
                    echo -ne "\033[1m"
                    echo -ne "\033[3${cBorder}m\033[4${cBorder}m"

                    ((t2 = iLeft + 1))
                    ((t3 = iLeft + iTrayWidth * 2 + 3))
                    for ((i = 0; i < iTrayHeight; i++))
                    do
                            ((t1 = i + iTop + 2))
                            echo -ne "\033[${t1};${t2}H||"
                            echo -ne "\033[${t1};${t3}H||"
                    done

                    ((t2 = iTop + iTrayHeight + 2))
                    for ((i = 0; i < iTrayWidth + 2; i++))
                    do
                            ((t1 = i * 2 + iLeft + 1))
                            echo -ne "\033[${iTrayTop};${t1}H=="
                            echo -ne "\033[${t2};${t1}H=="
                    done
                    echo -ne "\033[0m"


                    #顯示"Score"和"Level"字樣
                    echo -ne "\033[1m"
                    ((t1 = iLeft + iTrayWidth * 2 + 7))
                    ((t2 = iTop + 10))
                    echo -ne "\033[3${cScore}m\033[${t2};${t1}HScore"
                    ((t2 = iTop + 11))
                    echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iScore}"
                    ((t2 = iTop + 13))
                    echo -ne "\033[3${cScore}m\033[${t2};${t1}HLevel"
                    ((t2 = iTop + 14))
                    echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iLevel}"
                    echo -ne "\033[0m"
            }


            #退出時顯示GameOVer!
            function ShowExit()
            {
                    local y
                    ((y = iTrayHeight + iTrayTop + 3))
                    echo -e "\033[${y};0HGameOver!\033[0m"
                    exit
            }


            #顯示用法.
            function Usage
            {
                    cat << EOF
            Usage: $APP_NAME
            Start tetris game.

              -h, --help              display this help and exit
                  --version           output version information and exit
            EOF
            }


            #游戲主程序在這兒開始.
            if [[ "$1" == "-h" || "$1" == "--help" ]]; then
                    Usage
            elif [[ "$1" == "--version" ]]; then
                    echo "$APP_NAME $APP_VERSION"
            elif [[ "$1" == "--show" ]]; then
                    #當發(fā)現(xiàn)具有參數(shù)--show時,運行顯示函數(shù)
                    RunAsDisplayer
            else
                    bash $0 --show&        #以參數(shù)--show將本程序再運行一遍
                    RunAsKeyReceiver $!        #以上一行產(chǎn)生的進程的進程號作為參數(shù)
            fi


            from:
            http://bbs.chinaunix.net/thread-184858-1-1.html
            posted on 2010-03-26 11:51 chatler 閱讀(313) 評論(0)  編輯 收藏 引用 所屬分類: Shell
            <2008年9月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關(guān),覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品VIDEOSSEX久久发布| 久久se这里只有精品| 久久精品欧美日韩精品| 亚洲天堂久久精品| 久久亚洲精品国产精品婷婷| 久久久久99精品成人片试看| 久久亚洲AV永久无码精品| 久久精品人人做人人爽97 | 久久99热这里只有精品66| 久久精品黄AA片一区二区三区 | 97精品国产97久久久久久免费| 久久久久99精品成人片试看| 香蕉aa三级久久毛片| 久久精品成人免费网站| 亚洲精品乱码久久久久久 | 久久久久亚洲av无码专区| 婷婷久久综合| 久久综合狠狠综合久久激情 | 久久精品国产免费观看三人同眠| 国产成人精品久久亚洲| 亚洲AV日韩精品久久久久| 看全色黄大色大片免费久久久| 久久99国产精品久久99果冻传媒| 久久综合给久久狠狠97色| 欧美一区二区久久精品| 久久久久无码精品| 精品水蜜桃久久久久久久| 久久久久国产一级毛片高清版| 久久久精品人妻一区二区三区蜜桃| 2021国内精品久久久久久影院| 久久中文字幕视频、最近更新| 国产成人精品久久亚洲高清不卡 | 久久免费视频观看| 日韩亚洲欧美久久久www综合网 | 亚洲欧美成人久久综合中文网| 国产精品久久久久久久午夜片| 亚洲国产成人久久精品动漫| 好久久免费视频高清| 日韩精品久久久久久| 国产精品美女久久久久av爽| 婷婷综合久久中文字幕|