zoukankan      html  css  js  c++  java
  • shell版俄罗斯方块 分类: shell版俄罗斯方块 2015-07-26 19:41 8人阅读 评论(0) 收藏

    shell能是命令行解释器,shell脚本是命令的有序结合。在网上看到一位哥们用shell语言写了一个游戏,俄罗斯方块,佩服呀。为了弥补童年的不足,我们一起用shell语言开始编写我们自己的俄罗斯方块吧。
    我们先来回顾一下,俄罗斯都有哪些方块吧。
    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)
     
    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 = ()东东,这个是什么呢?它是shell中的数组,后面括号里面放的是它的元素,即坐标点.
    一起来看看shell中数组的语法吧
    Bash中,数组变量的赋值有两种方法:
    (1)name=(value1 ... valuen)此时小标从0开始
    (2)name[index]=value
    下面以一个简单的脚本来说明,脚本内容如下
    #!/bin/bash
    #定义数组
    A=(a   b   c   def)
    #把数组按字符串显示输出
    echo ${A[@]}或echo ${A[*]}
    显示:a  b  c   def
    #数组的长度表示${#A[*]}
    len=${#A[*]}或者len=${#A[@]}
    echo ${#A[*]}
    显示: 4
    #改变数组元素的值
    A[3] ="hello word"
    echo ${A[*]}
    显示:a  b  c  hello word
    #循环输出数组
    len=${#A[@]}
    for  ((i =  0;i < len;i ++))
    do
        echo -n "${A[i]}"
    done
    ________________________________

    ((  i = 0 ))
    while ((  i < len ))
    do
        echo "${A[i]}"
        (( i = i + 1))
    done
    #循环输出数组元素的另一种写法,注意,${A[*]}不能写成$A,$A默认是第一个元素,如果A="a b c ded",就可以写$A
    for value in ${A[*]}
    do
    echo $value
    done
    现在坐标点有了,那怎样把这些坐标点显示在屏幕上?这里我们要看一下shell中echo的用法
    echo的基本语法不在进行讲解,我们来看一些其他的
    echo 要变换颜色的时候,要使用-e
    格式:echo -e "33[背景颜色;字体颜色m字符串33[0m"
    eg:
        echo -e "33[41;36m something here 33[0m"
    其中41的位置代表底色,36的位置是代表字的颜色
    那些ascii code是对颜色调用的始末
    33[;m ... 33[0m
    例子:
        让字体变为红色并且不停的闪烁
    echo -e "33[31m33[05m请确认是否要停止当前的sequid进程,输入[Y|N]33[0m"
    字背景颜色范围:40 -- 49
    40:黑      41:深红    42:绿    43:黄    44:蓝    45:紫    46:深绿    47:白色
    字颜色:30 -- 39
    30:黑     31:红    32:绿    33:黄     34:蓝     35:紫     36:深绿    37:白
    ANSI控制码的说明
    33[0m  关闭所有属性    33[1m设置高亮度    33[4m下划线     33[y;xH设置光标位置
    到这里我们把我们要在屏幕显示的坐标点都显示出来吧:
     
     
    效果:
     

    到此我们终于可以在屏幕上画出东东了。


    前面一节,我们在屏幕上画出了俄罗斯方块,现在我们让它动起来,呵呵,动起来...
    思想就是通过改变x,y的坐标,在屏幕的不同地方绘制图形。
    方法是通过方向键(A   S   D  W)来改变x,y的坐标。

    先来看看shell中的信号处理吧

    一、trap捕捉到信号之后,可以有三种反应方式

    (1)执行一段程序来处理这一信号

    (2)接受信号的默认操作

    (3)忽视这一信号

    二、trap对上面三种方式提供了三种基本形式

    第一种形式的trap命令在shell接受到signal  list清单中数值相同的信号时,将执行双引号中的命令串。

    trap 'commands' signal-list

    trap "commands" signal-list

    为了恢复信号的默认操作,使用第二种形式的trap命令:
    trap signal-list

    第三种形式的trap命令允许忽视信号
    trap ""  signal-list

    注意:

    (1)对信号11(段违例)不能捕捉,因为shell本身需要捕捉该信号去进行内存的转储

    (2)在trap中可以定义对信号0的处理(实际上没有这个信号),shell程序在其终止(如执行exit语句时) 发出该信号

    (3)在捕捉到signal-list中指定的信号并执行完相应的命令之后,如果这些命令没有将shell程序终止的话,shell程序将继续执行收到信号时所执行的命令后面的命令

    另外,在trap语句中,单引号和双引号是不同的,当shell程序第一次碰到trap语句时,将把commands中的命令扫描一遍。此时若commands是单引号括起来的话,那么shell不会对commands中的变量和命令进行替换,否则commands中的变量和命令将用当时具体的值来替换。

    1. #!/bin/bash
    2. SigA=20
    3. SigS=21
    4. SigD=22
    5. SigW=23
    6. sig=0
    7. function Register_Signal()
    8. {
    9. trap "sig=$SigA;" $SigA
    10. trap "sig=$SigS;" $SigS
    11. trap "sig=$SigD;" $SigD
    12. trap "sig=$SigW;" $SigW
    13. }
    14. function Recive_Signal()
    15. {
    16. Register_Signal
    17. while true
    18. do
    19. sigThis=$sig
    20. case "$sigThis" in
    21. "$SigA")
    22. echo "A"
    23. sig=0
    24. ;;
    25. "$SigS")
    26. echo "S"
    27. sig=0
    28. ;;
    29. "$SigD")
    30. echo "D"
    31. sig=0
    32. ;;
    33. "$SigW")
    34. echo "W"
    35. sig=0
    36. ;;
    37. esac
    38. done
    39. }
    40. function Kill_Signal()
    41. {
    42. local sigThis
    43. while :
    44. do
    45. read -s -n 1 key
    46. case "$key" in
    47. "W"|"w")
    48. kill -$SigW $1
    49. ;;
    50. "S"|"s")
    51. kill -$SigS $1
    52. ;;
    53. "A"|"a")
    54. kill -$SigA $1
    55. ;;
    56. "D"|"d")
    57. kill -$SigD $1
    58. ;;
    59. "Q"|"q")
    60. kill -9 $1
    61. exit
    62. esac
    63. done
    64. }
    65. if [[ "$1" == "--show" ]]
    66. then
    67. Recive_Signal
    68. else
    69. bash $0 --show &
    70. Kill_Signal $!
    71. fi
    这段shell脚本的功能是:按下A  S  D  W键会打印出对应的字母,按下 Q键退出
     
    上一节我们学了一下shell脚本中信号的用法,这一节我们在屏幕上画出一个方块,并且让它动起来.

    box0=(0  0  0  1  1  0  1  1)
    现在我们就让box0在我们屏幕的任意地方动起来
    实现功能:
    A  -> 左移    D->右移     W->向上     S->向下
    思路就是通过改变x,y的坐标,在屏幕不同的地方,把box0画出来

    1. #!/bin/bash 

    2. #信号
    3. SigA=20
    4. SigS=21
    5. SigD=22
    6. SigW=23
    7. sig=0

    8. #方块在屏幕上的坐标点
    9. box0=(0 0 0 1 1 0 1 1)

    10. #边缘距离
    11. top=3
    12. left=3

    13. #当前x,y坐标
    14. currentX=15
    15. currentY=2

    16. function Draw_Box()
    17. {
    18.     local i j x y

    19.     if (($== 0))
    20.     then
    21.         for ((= 0;i < 8;i += 2))
    22.         do
    23.             ((= left + 3 * (currentX + ${box0[i]})))
    24.             ((= top + currentY + ${box0[i+1]}))

    25.             echo -"33[${y};${x}H "
    26.         done
    27.     else
    28.         echo -"33[31m33[1m"
    29.         for ((= 0;i < 8;i += 2))
    30.         do
    31.             ((= left + 3 * (currentX + ${box0[i]})))
    32.             ((= top + currentY + ${box0[i+1]}))

    33.             echo -"33[${y};${x}H[*]"
    34.         done
    35.     fi

    36.     echo -"33[0m"
    37. }

    38. function move_left()
    39. {    

    40.     if ((currentX == 0 ))
    41.     then
    42.         return 1;
    43.     fi

    44.     #先清除以前的方块
    45.     Draw_Box 0
    46.     
    47.     #改变x坐标
    48.     (( currentX -- ))
    49.     
    50.     #画出新的方块
    51.     Draw_Box 1

    52.     return 0;
    53. }


    54. function move_right()
    55. {    

    56.     if ((currentX > 20 ))
    57.     then
    58.         return 1;
    59.     fi

    60.     #先清除以前的方块
    61.     Draw_Box 0
    62.     
    63.     #改变x坐标
    64.     (( currentX ++ ))
    65.     
    66.     #画出新的方块
    67.     Draw_Box 1

    68.     return 0;
    69. }


    70. function move_up()
    71. {    

    72.     if ((currentY == 0 ))
    73.     then
    74.         return 1;
    75.     fi

    76.     #先清除以前的方块
    77.     Draw_Box 0
    78.     
    79.     #改变x坐标
    80.     (( currentY -- ))
    81.     
    82.     #画出新的方块
    83.     Draw_Box 1

    84.     return 0;
    85. }


    86. function move_down()
    87. {    

    88.     if ((currenty > 20 ))
    89.     then
    90.         return 1;
    91.     fi

    92.     #先清除以前的方块
    93.     Draw_Box 0
    94.     
    95.     #改变x坐标
    96.     (( currentY ++ ))
    97.     
    98.     #画出新的方块
    99.     Draw_Box 1

    100.     return 0;
    101. }


    102. function Register_Signal()
    103. {
    104.     trap "sig=$SigA;" $SigA
    105.     trap "sig=$SigS;" $SigS
    106.     trap "sig=$SigD;" $SigD
    107.     trap "sig=$SigW;" $SigW
    108. }

    109. function Recive_Signal()
    110. {
    111.     Register_Signal

    112.     Draw_Box 1

    113.     while true
    114.     do
    115.         sigThis=$sig

    116.         case "$sigThis" in
    117.             "$SigA")
    118.                 move_left
    119.                 sig=0
    120.                 ;;

    121.             "$SigS")
    122.                 move_down
    123.                 sig=0
    124.                 ;;

    125.             "$SigD")
    126.                 move_right
    127.                 sig=0
    128.                 ;;

    129.             "$SigW")
    130.                 move_up
    131.                 sig=0
    132.                 ;;
    133.         esac
    134.         
    135.     done
    136. }

    137. function Kill_Signal()
    138. {
    139.     local sigThis

    140.     while :
    141.     do
    142.         read --n 1 key
    143.         
    144.         case "$key" in

    145.             "W"|"w")
    146.                 kill -$SigW $1
    147.                 ;;
    148.             "S"|"s")
    149.                 kill -$SigS $1
    150.                 ;;
    151.             "A"|"a")
    152.                 kill -$SigA $1
    153.                 ;;
    154.             "D"|"d")
    155.                 kill -$SigD $1
    156.                 ;;
    157.             "Q"|"q")
    158.                 kill -9 $1
    159.                 exit
    160.      esac

    161.     done
    162. }

    163. if [[ "$1" == "--show" ]]
    164. then
    165.     Recive_Signal
    166. else
    167.     bash $0 --show &
    168.     Kill_Signal $!
    169. fi
    效果图:
     
    就到这吧,下一节我们随机产生方块,让后让它改变形状。

    现在,我们知道,怎样在屏幕上画方块,怎样让方块移动,今天我们将实现,系统随机产生方块,并且让其动起来,嗯,动起来....
     
    现在看看在shell中产生随机数的方法

    一、通过时间获得随机数(date)

    可以说时间是唯一的,也不会重复的,从这个里面获得同一时间的唯一值。

    例子:
        date   +%s
    注意:date   空格   +%s

    如果用它做随机数,相同一秒的数据是一样的。多线程里面基本不能满足要求了。

    date   +%N
    这个相当精确了,就算在多cpu,大量循环里面,同一秒里面,也很难出现相同结果,不过不同时间里面还会有大量重复碰撞

    date  +%s%N
    这个可以说比较完美,加入时间戳,又加上纳秒

    接下来我们看怎么获得数据内怎么样获得随机数
     
    程序运行的结果:
     
     
    二、通过内部系统变量($RANDOM)
    其实,linux已经提供有个系统环境变量了,直接就是随机数
    echo $RANDOM
    通过它,我们可以获得的数据是一个小于或等于5位的整数
    学完了随机数,我们让它帮助我们产生随机方块吧。
     
    1. #!/bin/bash 

    2. #七中不同的方块的定义
    3. #通过旋转,每种方块的显示的样式可能有几种
    4. box0=(0 0 0 1 1 0 1 1)
    5. box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
    6. box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
    7. box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
    8. 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)
    9. 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)
    10. 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)

    11. #把所有盒子放在box中
    12. box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})

    13. #每个盒子在box中的偏移
    14. boxOffset=(0 1 3 5 7 11 15)

    15. #旋转次数
    16. rotateCount=(1 2 2 2 4 4 4)

    17. #颜色数组
    18. colourArry=(31 32 33 34 35 36 37)

    19. #选装类型
    20. rotateType=-1

    21. #盒子标号
    22. boxNum=-1

    23. #新盒子
    24. newBox=()

    25. #边缘距离
    26. top=3
    27. left=3

    28. #当前x,y坐标
    29. currentX=15
    30. currentY=2

    31. function Draw_Box()
    32. {
    33.     local i j x y

    34.     if (($== 0))
    35.     then
    36.         for ((= 0;< 8;+= 2))
    37.         do
    38.             ((= left + 3 * (currentX + ${newBox[i]})))
    39.             ((= top + currentY + ${newBox[i+1]}))

    40.             echo -"33[${y};${x}H "
    41.         done
    42.     else
    43.         echo -"33[${colourArry[$colourNum]}m33[1m"
    44.         for ((= 0;< 8;+= 2))
    45.         do
    46.             ((= left + 3 * (currentX + ${newBox[i]})))
    47.             ((= top + currentY + ${newBox[i+1]}))

    48.             echo -"33[${y};${x}H[*]"
    49.         done
    50.     fi

    51.     echo -"33[0m"
    52. }


    53. function Random_Box()
    54. {
    55.     #随机产生盒子号
    56.     (( boxNum = $RANDOM % 7 ))    
    57.     #随机长生盒子的类型
    58.     ((rotateType = $RANDOM % ${rotateCount[boxNum]}))
    59.     #随机产生颜色
    60.     ((colourNum = $RANDOM % ${#colourArry[*]}))

    61.     #找到所在box中的起始位置
    62.     ((= ${boxOffset[boxNum]} * 8 + rotateType * 8))

    63.     for(( i = 0 ;< 8;++))
    64.     do
    65.         ((newBox[i] = ${box[j+i]}))
    66.     done
    67. }

    68. while :
    69. do
    70.     Random_Box
    71.     Draw_Box 1
    72.     sleep 1
    73.     Draw_Box 0
    74. done
    前面我们已经可以随机产生俄罗斯方块了,今天我们让它随键盘而改变

    1. #!/bin/bash 

    2. #七中不同的方块的定义
    3. #通过旋转,每种方块的显示的样式可能有几种
    4. box0=(0 0 0 1 1 0 1 1)
    5. box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
    6. box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
    7. box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
    8. 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)
    9. 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)
    10. 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)

    11. #把所有盒子放在box中
    12. box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})

    13. #每个盒子在box中的偏移
    14. boxOffset=(0 1 3 5 7 11 15)

    15. #旋转次数
    16. rotateCount=(1 2 2 2 4 4 4)

    17. #颜色数组
    18. colourArry=(31 32 33 34 35 36 37)

    19. #选装类型
    20. rotateType=-1

    21. #盒子标号
    22. boxNum=-1

    23. #新盒子
    24. newBox=()

    25. #边缘距离
    26. top=3
    27. left=3

    28. #当前x,y坐标
    29. currentX=15
    30. currentY=2

    31. #信号
    32. SigA=20
    33. SigS=21
    34. SigD=22
    35. SigW=23
    36. sig=0

    37. #随机产生盒子
    38. function Random_Box()
    39. {
    40.     #随机产生盒子号
    41.     (( boxNum = $RANDOM % 7 ))    
    42.     #随机长生盒子的类型
    43.     ((rotateType = $RANDOM % ${rotateCount[boxNum]}))
    44.     #随机产生颜色
    45.     ((colourNum = $RANDOM % ${#colourArry[*]}))

    46.     #找到所在box中的起始位置
    47.     ((= ${boxOffset[boxNum]} * 8 + rotateType * 8))

    48.     for(( i = 0 ;< 8;++))
    49.     do
    50.         ((newBox[i] = ${box[j+i]}))
    51.     done
    52. }


    53. function Draw_Box()
    54. {
    55.     local i j x y


    56.     if (($== 0))
    57.     then
    58.         for ((= 0;< 8;+= 2))
    59.         do
    60.             ((= left + 3 * (currentX + ${newBox[i]})))
    61.             ((= top + currentY + ${newBox[i+1]}))

    62.             echo -"33[${y};${x}H "
    63.         done
    64.     else
    65.         echo -"33[${colourArry[$colourNum]}m33[1m"
    66.         for ((= 0;< 8;+= 2))
    67.         do
    68.             ((= left + 3 * (currentX + ${newBox[i]})))
    69.             ((= top + currentY + ${newBox[i+1]}))

    70.             echo -"33[${y};${x}H[*]"
    71.         done
    72.     fi

    73.     echo -"33[0m"
    74. }

    75. function move_left()
    76. {    
    77.     local temp

    78.     if (( currentX == 0 ))
    79.     then
    80.         return 1
    81.     fi
    82.     
    83.     #先清除以前的方块
    84.     Draw_Box 0
    85.     
    86.     #改变x坐标
    87.     (( currentX -- ))
    88.     
    89.     #画出新的方块
    90.     Draw_Box 1

    91.     return 0
    92. }


    93. function move_right()
    94. {    

    95.     if ((currentX > 20 ))
    96.     then
    97.         return 1;
    98.     fi

    99.     #先清除以前的方块
    100.     Draw_Box 0
    101.     
    102.     #改变x坐标
    103.     (( currentX ++ ))
    104.     
    105.     #画出新的方块
    106.     Draw_Box 1

    107.     return 0;
    108. }

    109. #记录已经旋转的方块次数
    110. tempCount=0

    111. #按下w键旋转处理
    112. function box_rotate()
    113. {
    114.     local start_post
    115.     
    116.     ((tempCount ++))
    117.     #echo ${rotateCount[boxNum]}
    118.     if ((tempCount >= ${rotateCount[boxNum]}))
    119.     then
    120.         ((tempCount = 0))
    121.     fi

    122.     #每个盒子在box中的始位置
    123.     ((start_post = ${boxOffset[boxNum]} * 8 + tempCount * 8))

    124.     for ((= 0;< 8;++))
    125.     do
    126.         ((newBox[i] = ${box[start_post+i]}))
    127.     done

    128.     return 0
    129. }

    130. function move_rotate()
    131. {    

    132.     if ((currentY == 0 ))
    133.     then
    134.         return 1;
    135.     fi

    136.     #先清除以前的方块
    137.     Draw_Box 0
    138.     
    139.     #改变当前方块的形状
    140.     box_rotate
    141.         
    142.     #画出新的方块
    143.     Draw_Box 1

    144.     return 0;
    145. }


    146. function move_down()
    147. {    

    148.     if ((currenty > 20 ))
    149.     then
    150.         return 1;
    151.     fi

    152.     #先清除以前的方块
    153.     Draw_Box 0
    154.     
    155.     #改变x坐标
    156.     (( currentY ++ ))
    157.     
    158.     #画出新的方块
    159.     Draw_Box 1

    160.     return 0;
    161. }


    162. function Register_Signal()
    163. {
    164.     trap "sig=$SigA;" $SigA
    165.     trap "sig=$SigS;" $SigS
    166.     trap "sig=$SigD;" $SigD
    167.     trap "sig=$SigW;" $SigW
    168. }

    169. function Recive_Signal()
    170. {

    171.     Random_Box
    172.     Draw_Box 1
    173.     Register_Signal

    174.     while true
    175.     do
    176.         sigThis=$sig

    177.         case "$sigThis" in
    178.             "$SigA")
    179.                 move_left
    180.                 sig=0
    181.                 ;;

    182.             "$SigS")
    183.                 move_down
    184.                 sig=0
    185.                 ;;

    186.             "$SigD")
    187.                 move_right
    188.                 sig=0
    189.                 ;;

    190.             "$SigW")
    191.                 move_rotate
    192.                 sig=0
    193.                 ;;
    194.         esac
    195.         
    196.     done
    197. }

    198. function Kill_Signal()
    199. {
    200.     local sigThis

    201.     while :
    202.     do
    203.         read --n 1 key
    204.         
    205.         case "$key" in

    206.             "W"|"w")
    207.                 kill -$SigW $1
    208.                 ;;
    209.             "S"|"s")
    210.                 kill -$SigS $1
    211.                 ;;
    212.             "A"|"a")
    213.                 kill -$SigA $1
    214.                 ;;
    215.             "D"|"d")
    216.                 kill -$SigD $1
    217.                 ;;
    218.             "Q"|"q")
    219.                 kill -9 $1
    220.                 exit
    221.      esac

    222.     done
    223. }

    224. if [[ "$1" == "--show" ]]
    225. then
    226.     Recive_Signal
    227. else
    228.     bash $0 --show &
    229.     Kill_Signal $!
    230. fi
    效果图:
     
    红色部分是我们今天写的代码,思路是使用随机产生的盒子号确定此盒子在box中的位置,然后从此位置开始,把它的所有造型在屏幕上挨个画出来。
    到现在为止,我们可以随机产生俄罗斯方块,并且可以移动和改变,下一节我们在屏幕上画出一个矩阵,让盒子从矩阵的顶部自动下落,到矩阵的底部停止。
     
    我们现在屏幕上画出一个矩阵,这个很简单
    1. #!/bin/bash 

    2. clear

    3. #边缘距离
    4. left=10
    5. top=5

    6. #矩阵的长和宽
    7. widthSize=25
    8. hightSize=25

    9. #画出矩阵
    10. function draw_rectangle()
    11. {
    12.     local x y

    13.     echo -"33[32m33[46m33[1m"

    14.     for ((= 0 ;i < widthSize;i ++))
    15.     do
    16.         ((= left + i))
    17.         ((= top + hightSize - 1))
    18.     
    19.         echo -"33[${top};${x}H="
    20.         echo -"33[${y};${x}H="

    21.     done

    22.     for ((= 0 ;i < hightSize;i ++))
    23.     do
    24.         ((= left + widthSize - 1))
    25.         ((= top + i))
    26.     
    27.         echo -"33[${y};${left}H||"
    28.         echo -"33[${y};${x}H||"

    29.     done

    30.     echo -"33[0m"
    31. }

    32. draw_rectangle
    效果图:
     
    矩阵有了,接下来就是让盒子从矩阵的顶部下落下来到底部停止
    1. #!/bin/bash 

    2. #七中不同的方块的定义
    3. #通过旋转,每种方块的显示的样式可能有几种
    4. box0=(0 0 0 1 1 0 1 1)
    5. box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
    6. box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
    7. box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
    8. 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)
    9. 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)
    10. 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)

    11. #把所有盒子放在box中
    12. box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})

    13. #每个盒子在box中的偏移
    14. boxOffset=(0 1 3 5 7 11 15)

    15. #旋转次数
    16. rotateCount=(1 2 2 2 4 4 4)

    17. #颜色数组
    18. colourArry=(31 32 33 34 35 36 37)

    19. #选装类型
    20. rotateType=-1

    21. #盒子标号
    22. boxNum=-1

    23. #新盒子
    24. newBox=()

    25. #边缘距离
    26. left=10
    27. top=5

    28. #矩阵的长和宽
    29. widthSize=28
    30. hightSize=26

    31. #确定从矩阵那个地方出来
    32. function ensure_postion()
    33. {
    34.     local sumx=0 i j

    35.     ((minx = ${newBox[0]}))
    36.     ((miny = ${newBox[1]}))
    37.     ((maxy = miny ))
    38.     
    39.     for ((= 2; i < ${#newBox[*]};+= 2))
    40.     do 
    41.         #确定最小的x坐标
    42.         if ((minx > ${newBox[i]}))
    43.         then
    44.             ((minx = ${newBox[i]}))
    45.         fi
    46.         
    47.         #确定最小的y坐标
    48.         if ((miny > ${newBox[i+1]}))
    49.         then
    50.             ((miny = ${newBox[i+1]}))
    51.         fi

    52.         if ((${newBox[i]} == ${newBox[i-2]}))
    53.         then
    54.             continue
    55.         fi
    56.         
    57.         ((sumx ++))

    58.     done

    59.     if ((sumx == 0))
    60.     then
    61.         ((sumx = 1))
    62.     fi
    63.     
    64.     #当前x,y坐标
    65.     ((currentX = left + widthSize / 2 - sumx * 2 - minx))
    66.     ((currentY = top + 1 - miny))    

    67.     return 0
    68. }

    69. #画出矩阵
    70. function draw_rectangle()
    71. {
    72.     local x y

    73.     echo -"33[32m33[46m33[1m"

    74.     for ((= 0 ;i < widthSize;i ++))
    75.     do
    76.         ((= left + i))
    77.         ((= top + hightSize - 1))
    78.     
    79.         echo -"33[${top};${x}H="
    80.         echo -"33[${y};${x}H="

    81.     done

    82.     for ((= 0 ;i < hightSize;i ++))
    83.     do
    84.         ((= left + widthSize - 1))
    85.         ((= top + i))
    86.     
    87.         echo -"33[${y};${left}H||"
    88.         echo -"33[${y};${x}H||"

    89.     done

    90.     echo -"33[0m"
    91. }


    92. #画出方块
    93. function Draw_Box()
    94. {
    95.     local i j x y

    96.     if (($== 0))
    97.     then
    98.         for ((= 0;i < 8;i += 2))
    99.         do
    100.             ((= currentX + 3 * ${newBox[i]}))
    101.             ((= currentY + ${newBox[i+1]}))

    102.             echo -"33[${y};${x}H "
    103.         done
    104.     else
    105.         echo -"33[${colourArry[$colourNum]}m33[1m"
    106.         for ((= 0;i < 8;i += 2))
    107.         do
    108.             ((= currentX + 3 * ${newBox[i]}))
    109.             ((= currentY + ${newBox[i+1]}))

    110.             echo -"33[${y};${x}H[*]"
    111.         done
    112.     fi

    113.     echo -"33[0m"
    114. }

    115. #随机产生方块
    116. function Random_Box()
    117. {
    118.     #随机产生盒子号
    119.     (( boxNum = $RANDOM % 7 ))    
    120.     #随机长生盒子的类型
    121.     ((rotateType = $RANDOM % ${rotateCount[boxNum]}))
    122.     #随机产生颜色
    123.     ((colourNum = $RANDOM % ${#colourArry[*]}))

    124.     #找到所在box中的起始位置
    125.     ((= ${boxOffset[boxNum]} * 8 + rotateType * 8))

    126.     for(( i = 0 ;i < 8;i ++))
    127.     do
    128.         ((newBox[i] = ${box[j+i]}))
    129.     done
    130. }

    131. #判断能否下移
    132. function move_test()
    133. {
    134.     local vary=$1 i
    135.     
    136.     #当前的y坐标加上newBox里面的坐标,其值是否大于28
    137.     for ((= 0;i < ${#newBox[@]}; i += 2))
    138.     do
    139.         if ((vary + ${newBox[i+1]} > 28))
    140.         then
    141.             return 0
    142.         fi
    143.     done

    144.     return 1
    145. }


    146. draw_rectangle
    147. Random_Box
    148. ensure_postion

    149. while :
    150. do
    151.     Draw_Box 1

    152.     sleep 0.1
    153.     Draw_Box 0

    154.     ((currentY ++))

    155.     if move_test currentY
    156.     then
    157.         Draw_Box 1
    158.         sleep 2
    159.         Draw_Box 0
    160.         Random_Box
    161.         ensure_postion
    162.     fi

    163. done

    164. echo
    效果图:
    下一次,我们实现通过键盘改变方块形状和移动方块,并且实现累加


    原文:chengyaogen.blog.chinaunix.net

  • 相关阅读:
    MD5加密
    HDU 1800 Flying to the Mars(Trie字典树 upper_bound)
    POJ 3624 Charm Bracelet(01背包 基础)
    hdu 1005 (规律 循环节)
    ZOJ 3710 friends(暴力 枚举 水)
    zoj 3714 Java Beans(枚举 水)
    hdu 1108 最小公倍数(数论基础 水)
    POJ 1797 Heavy Transportation(dijkstra )
    poj 3984 迷宫问题(bfs 打印路径)
    报数游戏(模拟 枚举)
  • 原文地址:https://www.cnblogs.com/zclzqbx/p/4687042.html
Copyright © 2011-2022 走看看