• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • shell版俄羅斯方塊(轉摘)

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    shell版俄羅斯方塊(轉摘) 我所見的最強的shell #!/bin/bash # Tetris Game # 10.21.2003 xhchen #顏色定義 cRed=1 cGreen=2 cYellow=3 cBlue=4 cFuchsia=5 cCyan=6 cWhite=7 colorTable=(cRed cGreen cYellow cBlue cFuchsia cCyan cWhite) #位置和大小 iL

    shell版俄羅斯方塊(轉摘)

    我所見的最強的shell

    #!/bin/bash
    # Tetris Game
    # 10.21.2003 xhchen

    #顏色定義
    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))

    #顏色設置
    cBorder=$cGreen
    cScore=$cFuchsia
    cScoreValue=$cCyan

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

    #七中不同的方塊的定義
    #通過旋轉,每種方塊的顯示的樣式可能有幾種
    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=($ $ $ $ $ $ $)
    #各種方塊旋轉后可能的樣式數目
    countBox=(1 2 2 2 4 4 4)
    #各種方塊再box數組中的偏移
    offsetBox=(0 1 3 5 7 11 15)

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

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

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


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

       pidDisplayer=
       aKey=(0 0 0)

       cESC=`echo -ne ""`
       cSpace=`echo -ne ""`

       #保存終端屬性。在read -s讀取終端鍵時,終端的屬性會被暫時改變。
       #如果在read -s時程序被不幸殺掉,可能會導致終端混亂,
       #需要在程序退出時恢復終端屬性。
       sTTY=`stty -g`
       
       #捕捉退出信號
       trap "MyExit;" INT TERM
       trap "MyExitNoSub;" $sigExit
       
       #隱藏光標
       echo -ne "[?25l"

       
       while (( 1 ))
       do
          #讀取輸入。注-s不回顯,-n讀到一個字符立即返回
          read -s -n 1 key
          
          aKey[0]=$
          aKey[1]=$
          aKey[2]=$key
          sig=0

          #判斷輸入了何種鍵
          if [[ $key == $cESC && $ == $cESC ]]
          then
             #ESC鍵
             MyExit
          elif [[ $ == $cESC && $ == "[" ]]
          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
             #向另一進程發送消息
             kill -$sig $pidDisplayer
          fi
       done
    }

    #退出前的恢復
    function MyExitNoSub()
    {
       local y
       
       #恢復終端屬性
       stty $sTTY
       ((y = iTop + iTrayHeight + 4))

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


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


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

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

       while (( 1 ))
       do
          #根據當前的速度級iLevel不同,設定相應的循環的次數
          for ((i = 0; i < 21 - iLevel; i++))
          do
             sleep 0.02
             sigThis=$sig
             sig=0

             #根據sig變量判斷是否接受到相應的信號
             if ((sigThis == sigRotate)); then BoxRotate;   #旋轉
             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=
       xTest=
       for ((j = 0; j < 8; j += 2))
       do
          ((i = j + 1))
          ((y = $ + yTest))
          ((x = $ + xTest))
          if (( y < 0 || y >= iTrayHeight || x < 0 || x >= iTrayWidth))
          then
             #撞到墻壁了
             return 1
          fi
          if ((${iMap[y * iTrayWidth + x]} != -1 ))
          then
             #撞到其他已經存在的方塊了
             return 1
          fi
       done
       return 0;
    }


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

       #將當前移動中的方塊放到背景方塊中去
       for ((j = 0; j < 8; j += 2))
       do
          ((i = j + 1))
          ((y = $ + boxCurY))
          ((x = $ + 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 (($ == -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]=$
          done
          for ((i = 0; i < iTrayWidth; i++))
          do
             iMap[$i]=-1
          done
       done
       
       if ((line == 0)); then return; fi

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


       #重新顯示背景方塊
       for ((y = 0; y < iTrayHeight; y++))
       do
          ((yp = y + iTrayTop + 1))
          ((xp = iTrayLeft + 1))
          ((i = y * iTrayWidth))
          echo -ne "[$;$H"
          for ((x = 0; x < iTrayWidth; x++))
          do
             ((j = i + x))
             if (($ == -1))
             then
                echo -ne "  "
             else
                echo -ne "[1m[7m[3$m[4$m[][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   #產生新的方塊
       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 = $ + boxCurY))
          ((x = $ + boxCurX))
          for ((k = y + 1; k < iTrayHeight; k++))
          do
             ((i = k * iTrayWidth + x))
             if (( $ != -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   #產生新的方塊
    }


    #旋轉方塊
    function BoxRotate()
    {
       local iCount iTestRotate boxTest j i s
       iCount=$   #當前的方塊經旋轉可以產生的樣式的數目

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

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

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

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


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

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


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

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

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

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

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

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

       #隨機產生新的方塊
       ((iBoxNewType = RANDOM % $))
       ((iBoxNewRotate = RANDOM % $))
       for ((j = 0, i = ($ + $iBoxNewRotate) * 8; j < 8; j++, i++))
       do
          boxNew[$j]=$;
       done

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


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

       #顯示邊框
       echo -ne "[1m"
       echo -ne "[3$m[4$m"
       
       ((t2 = iLeft + 1))
       ((t3 = iLeft + iTrayWidth * 2 + 3))
       for ((i = 0; i < iTrayHeight; i++))
       do
          ((t1 = i + iTop + 2))
          echo -ne "[$;$H||"
          echo -ne "[$;$H||"
       done
       
       ((t2 = iTop + iTrayHeight + 2))
       for ((i = 0; i < iTrayWidth + 2; i++))
       do
          ((t1 = i * 2 + iLeft + 1))
          echo -ne "[$;$H=="
          echo -ne "[$;$H=="
       done
       echo -ne "[0m"

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


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



    #游戲主程序在這兒開始.
    if [[ != "--show" ]]
    then
       bash --show&   #以參數--show將本程序再運行一遍
       RunAsKeyReceiver $!   #以上一行產生的進程的進程號作為參數
       exit
    else
       #當發現具有參數--show時,運行顯示函數
       RunAsDisplayer   
       exit
    fi

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>