找回密码
 欢迎注册
查看: 7611|回复: 3

[原创] 用二进制算法实现俄罗斯方块

[复制链接]
发表于 2017-1-18 21:13:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
本帖最后由 happysxyf 于 2017-1-18 21:34 编辑

俄罗斯方块是一款经典的方块游戏,在俄罗斯方块中存在多种旋转体系法则,比如下面图片中显示的两种:
Tgm_basic_ars_description.png
这里,我们为了实现记录各种方块的形状,使用了抽象的二进制表
□□□□
□■■□
□□■■
□□□□
然后将表首尾相接成为链条。
实现方法:
  1. REM 设置旋转体系:依次为TGM、SRS(第二代超级形码)
  2. ::set "SHAPE=0x159D0x89AB0x159D0x89AB0x126A0x48560x159A0x45260x926A0x456A0x15920x04560x48590x48590x48590x48590x59260x01560x59260x01560x41590x45960x15960x41560x156A0x41520x156A0x4152"
  3.   set "SHAPE=0x159D0x89AB0x26AE0x45670x01590x48560x159A0x45260x81590x456A0x15920x04560x48590x48590x48590x48590x48150x459A0x59260x01560x41590x45960x15960x41560x04590x85960x156A0x4152"
复制代码


在图层的移动中,使用了图像动态显示技术,就是只处理变化的点,其实每次只需要处理4个点
实现方法
  1. for %%p in (!POS[0]!,!POS[1]!,!POS[2]!,!POS[3]!) do (
  2.         set/a "POS_X=(%%p>>2)+X+Dx,POS_Y=(%%p&0x3)+Y+Dy"
  3.         set/a "CHE=P[!POS_X!][!POS_Y!]"
  4. )
复制代码


俄罗斯方块代码如下:
  1. [url=home.php?mod=space&uid=2931]@echo[/url] off
  2. ::**************Happy's俄罗斯方块***********
  3. REM 使用说明:
  4. REM A左D右;W旋转;S加速下落;
  5. REM Q退出;P暂停;方向键继续;
  6. ::**************Settings高级设置************
  7. REM 设置窗体
  8.   title &setlocal enabledelayedexpansion
  9.   mode con cols=35 lines=25&color F0
  10. REM 开启防闪烁,用于画质增强
  11.   set F1=1
  12. REM 设置时钟T, 越小下落越快
  13.   set T=190
  14. REM 默认皮肤
  15.   set "SKIN= ■"
  16. REM 设置旋转体系:依次为TGM、SRS(第二代超级形码)
  17. ::set "SHAPE=0x159D0x89AB0x159D0x89AB0x126A0x48560x159A0x45260x926A0x456A0x15920x04560x48590x48590x48590x48590x59260x01560x59260x01560x41590x45960x15960x41560x156A0x41520x156A0x4152"
  18.   set "SHAPE=0x159D0x89AB0x26AE0x45670x01590x48560x159A0x45260x81590x456A0x15920x04560x48590x48590x48590x48590x48150x459A0x59260x01560x41590x45960x15960x41560x04590x85960x156A0x4152"
  19. ::**************方向控制台******************
  20. if "%1"=="CONTROLP" (
  21.         title &MODE CON cols=15 lines=1
  22.         for /l %%i in (1,1,100000) do (
  23.                 set "KEY="
  24.                 for /f "delims=" %%a in ('xcopy /W . 2^>NUL') do (
  25.                         if not defined KEY (
  26.                                 set "KEY=%%a"&set "KEY=!KEY:~-1!"
  27.                                 echo %%i!KEY!>key.ini&if /i "!KEY!"=="Q" (exit)
  28.                         )
  29.                 )
  30.         )
  31. )
  32. start "" "%~f0" CONTROLP
  33. ::**************先导程序********************
  34. REM 准备元素
  35. set/a "LEVEL=1,SCORE=0, RU=!random!%%7,RI=(!random!%%4)*6"
  36. for /l %%N in (0,24,144) do (set/a "N=%%N/24"&set "SHAPE!N!=!SHAPE:~%%N,24!")
  37. for /l %%N in (0,1,1   ) do (set "E%%N=!SKIN:~%%N,1!")
  38. for /l %%N in (1,1,10  ) do (set "LINES=!LINES!━"   )
  39. for /l %%N in (1,1,300 ) do (set "SPACE=!SPACE!"    )
  40. REM 构建显存
  41. :DISPLAY_RAM
  42. for /l %%j in (0,1,21) do (
  43.         set "#[%%j]=1"
  44.         for /l %%i in (0,1,11) do (
  45.                 set/a "BOUNDARY=(%%i)*(%%i-11)*(%%j-21)"
  46.                 if !BOUNDARY! equ 0 (set "P[%%i][%%j]=1") else (set "P[%%i][%%j]=0")
  47.         )
  48. )
  49. ::**************主体程序********************
  50. REM ~~~随机块体
  51. :RANDOM_SHAPE
  52. set/a "NU=RU,NI=RI, RU=!random!%%7,RI=(!random!%%4)*6, X=4,Y=1"
  53. echo RW>key.ini
  54. REM ~~~计数面板
  55. set "V1=!LEVEL!    "
  56. set "V2=!SCORE!    "
  57. set "READM[3]=LEVEL:!V1:~0,3!"
  58. set "READM[5]=SCORE:!V2:~0,3!"
  59. set "READM[7]=NEXT"
  60. REM ~~~读取按键
  61. :READKEY
  62. set/a "Dx=0,Dy=0"
  63. set/p KEY=<key.ini
  64. if /i "!KEY:~-1!"=="P" (goto :READKEY)
  65. if not "!PRE_KEY!"=="!KEY!" (
  66.         set PRE_KEY=!KEY!
  67.         if /i "!KEY:~-1!"=="A" (set "Dx=-1")
  68.         if /i "!KEY:~-1!"=="D" (set "Dx=1" )
  69.         if /i "!KEY:~-1!"=="W" (
  70.                 set "Cache=!SHAPE%NU%:~%NI%,6!"
  71.                 set/a "Xf=X,NI+=6,NI%%=24"
  72.                 REM ~~~16进制超级转码
  73.                 for /l %%j in (0,1,3) do (
  74.                         set/a "POS[%%j]=Cache&0xF, Cache=Cache>>4" 2>NUL
  75.                 )
  76.                 if "!KEY!"=="RW" (
  77.                         set "Cache2=!SHAPE%RU%:~%RI%,6!"
  78.                         for /l %%J in (0,1,3) do (
  79.                                 set/a "RPOS[%%J]=Cache2&0xF, Cache2=Cache2>>4" 2>NUL
  80.                                 for /l %%I in (0,1,3) do (
  81.                                         set "R[%%I][%%J]=0"
  82.                                 )
  83.                         )       
  84.                         for %%p in (!RPOS[0]!,!RPOS[1]!,!RPOS[2]!,!RPOS[3]!) do (
  85.                                 set/a "RPOS_X=%%p>>2,RPOS_Y=%%p&0x3"
  86.                                 set "R[!RPOS_X!][!RPOS_Y!]=1"
  87.                         )
  88.                         for /l %%J in (0,1,3) do (
  89.                                 set "TP="
  90.                                 for /l %%I in (0,1,3) do (
  91.                                         set "TP=!TP!!R[%%I][%%J]!"
  92.                                 )
  93.                                 set "TP=!TP:0=%E0%!"
  94.                                 set "TP=!TP:1=%E1%!"
  95.                                 set/a "SN=%%J+8"
  96.                                 set "READM[!SN!]=!TP!"
  97.                         )
  98.                         echo WO>key.ini
  99.                 )
  100.                 goto :DATA_PROCESSING
  101.         )
  102.         if /i "!KEY:~-1!"=="Q" (exit)
  103. )
  104. if /i "!KEY:~-1!"=="S" (set "Dy=1"&goto :DATA_PROCESSING)
  105. REM ~~~下落体系
  106. if !Mark! equ 0 (
  107.         set "Mark=1"
  108.         set "T1=!time:~9,2!"
  109. ) else (
  110.         set/a "TS=2!time:~9,2!-1!T1!"
  111.         set/a "TS=1!TS:~-2!"
  112.         if !TS! lss !T! (set "Dy=0") else (set/a "Dy=1,Mark=0")
  113. )
  114. if !Dx! equ 0 if !Dy! equ 0 (goto :READKEY)
  115. REM ~~~数据处理
  116. :DATA_PROCESSING
  117. SETLOCAL
  118. for %%p in (!POS[0]!,!POS[1]!,!POS[2]!,!POS[3]!) do (
  119.         set/a "POS_X=(%%p>>2)+X+Dx,POS_Y=(%%p&0x3)+Y+Dy"
  120.         set/a "CHE=P[!POS_X!][!POS_Y!]"
  121.         if !CHE! equ 0 (
  122.                 set "P[!POS_X!][!POS_Y!]=1"
  123.         ) else (
  124.                 if !Dx! neq 0 (
  125.                         ENDLOCAL
  126.                         goto :READKEY
  127.                 )
  128.                 if !Dy! equ 1 (
  129.                         ENDLOCAL
  130.                         if !Y! lss 2 (
  131.                                 echo GAME OVER!
  132.                                 ping -n 2 127.1>NUL
  133.                                 goto :DISPLAY_RAM
  134.                         )
  135.                         REM ~~~固化块体
  136.                         set "POS_Y_MAX=0"
  137.                         for %%P in (!POS[0]!,!POS[1]!,!POS[2]!,!POS[3]!) do (
  138.                                 set/a "POS_X=(%%P>>2)+X,POS_Y=(%%P&0x3)+Y"
  139.                                 if !POS_Y_MAX! lss !POS_Y! (set "POS_Y_MAX=!POS_Y!")
  140.                                 set "P[!POS_X!][!POS_Y!]=1"
  141.                         )
  142.                         REM ~~~关卡得分
  143.                         for /l %%J in (!Y!,1,!POS_Y_MAX!) do (
  144.                                 set "TP="
  145.                                 for /l %%I in (1,1,10) do (
  146.                                         set "TP=!TP!!P[%%I][%%J]!"
  147.                                 )
  148.                                 if "!TP!"=="1111111111" (
  149.                                         set/a "SCORE+=10"
  150.                                         set "#%%J=1"
  151.                                         if !SCORE! equ 400 (
  152.                                                 for /l %%N in (!Y!,1,!POS_Y_MAX!) do (set "#%%N=")
  153.                                                 set/a "SCORE=0,LEVEL+=1,T-=10"
  154.                                                 goto :DISPLAY_RAM
  155.                                         )
  156.                                 )
  157.                         )
  158.                         REM ~~~极品消行
  159.                         for /l %%J in (20,-1,5) do (
  160.                                 if defined #%%J (
  161.                                         set "#%%J="
  162.                                         set/a "MarkJ=%%J-1, GK=1"
  163.                                         for /l %%N in (1,1,3) do (
  164.                                                 if defined #!MarkJ! (set/a "MarkJ-=1")
  165.                                         )
  166.                                         set "#!MarkJ!=1"
  167.                                         for /l %%I in (1,1,10) do (
  168.                                                 set/a "P[%%I][%%J]=P[%%I][!MarkJ!]"
  169.                                         )
  170.                                 )
  171.                         )
  172.                         if defined GK (for /l %%J in (20,-1,5) do (set "#[%%J]=1")&set "GK=")
  173.                         goto :RANDOM_SHAPE
  174.                 )
  175.                 if /i "!KEY:~-1!"=="W" (
  176.                         ENDLOCAL
  177.                         echo OW>key.ini
  178.                         set/a "NI=(NI+12)%%24"
  179.                         goto :READKEY
  180.                 )
  181.         )
  182. )
  183. REM ~~~绘图引擎
  184. if !F1! equ 1 (2>NUL echo         !SPACE!&set/p=<NUL) else (cls)
  185. echo ┏%LINES%┓
  186. for /l %%j in (0,1,5) do (set/a "MARK_Y=Y+%%j,#[!MARK_Y!]=1")
  187. for /l %%j in (1,1,20) do (
  188.         if not defined #[%%j] (
  189.                 echo;
  190.         ) else (
  191.                 set "TP="
  192.                 for /l %%i in (1,1,10) do (set "TP=!TP!!P[%%i][%%j]!")
  193.                 set "TP=!TP:1=%E1%!"
  194.                 set "TP=!TP:0=%E0%!"
  195.                 echo ┃!TP!┃!READM[%%j]!
  196.         )
  197. )
  198. echo ┗%LINES%┛
  199. echo  CopyRight@2016~2018 BY HAPPY
  200. ENDLOCAL&for /l %%j in (1,1,20) do (set "#[%%j]=")
  201. set/a "X+=Dx,Y+=Dy"
  202. goto :READKEY
复制代码

可执行代码下载 俄罗斯方块.rar (2.29 KB, 下载次数: 4)
效果图:
QQ图片20170118211501.png
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-3-29 20:27 , Processed in 0.055701 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表