用二进制算法实现俄罗斯方块
本帖最后由 happysxyf 于 2017-1-18 21:34 编辑俄罗斯方块是一款经典的方块游戏,在俄罗斯方块中存在多种旋转体系法则,比如下面图片中显示的两种:
这里,我们为了实现记录各种方块的形状,使用了抽象的二进制表
□□□□
□■■□
□□■■
□□□□
然后将表首尾相接成为链条。
实现方法:
REM 设置旋转体系:依次为TGM、SRS(第二代超级形码)
::set "SHAPE=0x159D0x89AB0x159D0x89AB0x126A0x48560x159A0x45260x926A0x456A0x15920x04560x48590x48590x48590x48590x59260x01560x59260x01560x41590x45960x15960x41560x156A0x41520x156A0x4152"
set "SHAPE=0x159D0x89AB0x26AE0x45670x01590x48560x159A0x45260x81590x456A0x15920x04560x48590x48590x48590x48590x48150x459A0x59260x01560x41590x45960x15960x41560x04590x85960x156A0x4152"
在图层的移动中,使用了图像动态显示技术,就是只处理变化的点,其实每次只需要处理4个点
实现方法
for %%p in (!POS!,!POS!,!POS!,!POS!) do (
set/a "POS_X=(%%p>>2)+X+Dx,POS_Y=(%%p&0x3)+Y+Dy"
set/a "CHE=P[!POS_X!][!POS_Y!]"
)
俄罗斯方块代码如下:
@echo off
::**************Happy's俄罗斯方块***********
REM 使用说明:
REM A左D右;W旋转;S加速下落;
REM Q退出;P暂停;方向键继续;
::**************Settings高级设置************
REM 设置窗体
title &setlocal enabledelayedexpansion
mode con cols=35 lines=25&color F0
REM 开启防闪烁,用于画质增强
set F1=1
REM 设置时钟T, 越小下落越快
set T=190
REM 默认皮肤
set "SKIN= ■"
REM 设置旋转体系:依次为TGM、SRS(第二代超级形码)
::set "SHAPE=0x159D0x89AB0x159D0x89AB0x126A0x48560x159A0x45260x926A0x456A0x15920x04560x48590x48590x48590x48590x59260x01560x59260x01560x41590x45960x15960x41560x156A0x41520x156A0x4152"
set "SHAPE=0x159D0x89AB0x26AE0x45670x01590x48560x159A0x45260x81590x456A0x15920x04560x48590x48590x48590x48590x48150x459A0x59260x01560x41590x45960x15960x41560x04590x85960x156A0x4152"
::**************方向控制台******************
if "%1"=="CONTROLP" (
title &MODE CON cols=15 lines=1
for /l %%i in (1,1,100000) do (
set "KEY="
for /f "delims=" %%a in ('xcopy /W . 2^>NUL') do (
if not defined KEY (
set "KEY=%%a"&set "KEY=!KEY:~-1!"
echo %%i!KEY!>key.ini&if /i "!KEY!"=="Q" (exit)
)
)
)
)
start "" "%~f0" CONTROLP
::**************先导程序********************
REM 准备元素
set/a "LEVEL=1,SCORE=0, RU=!random!%%7,RI=(!random!%%4)*6"
for /l %%N in (0,24,144) do (set/a "N=%%N/24"&set "SHAPE!N!=!SHAPE:~%%N,24!")
for /l %%N in (0,1,1 ) do (set "E%%N=!SKIN:~%%N,1!")
for /l %%N in (1,1,10) do (set "LINES=!LINES!━" )
for /l %%N in (1,1,300 ) do (set "SPACE=!SPACE!" )
REM 构建显存
:DISPLAY_RAM
for /l %%j in (0,1,21) do (
set "#[%%j]=1"
for /l %%i in (0,1,11) do (
set/a "BOUNDARY=(%%i)*(%%i-11)*(%%j-21)"
if !BOUNDARY! equ 0 (set "P[%%i][%%j]=1") else (set "P[%%i][%%j]=0")
)
)
::**************主体程序********************
REM ~~~随机块体
:RANDOM_SHAPE
set/a "NU=RU,NI=RI, RU=!random!%%7,RI=(!random!%%4)*6, X=4,Y=1"
echo RW>key.ini
REM ~~~计数面板
set "V1=!LEVEL! "
set "V2=!SCORE! "
set "READM=LEVEL:!V1:~0,3!"
set "READM=SCORE:!V2:~0,3!"
set "READM=NEXT"
REM ~~~读取按键
:READKEY
set/a "Dx=0,Dy=0"
set/p KEY=<key.ini
if /i "!KEY:~-1!"=="P" (goto :READKEY)
if not "!PRE_KEY!"=="!KEY!" (
set PRE_KEY=!KEY!
if /i "!KEY:~-1!"=="A" (set "Dx=-1")
if /i "!KEY:~-1!"=="D" (set "Dx=1" )
if /i "!KEY:~-1!"=="W" (
set "Cache=!SHAPE%NU%:~%NI%,6!"
set/a "Xf=X,NI+=6,NI%%=24"
REM ~~~16进制超级转码
for /l %%j in (0,1,3) do (
set/a "POS[%%j]=Cache&0xF, Cache=Cache>>4" 2>NUL
)
if "!KEY!"=="RW" (
set "Cache2=!SHAPE%RU%:~%RI%,6!"
for /l %%J in (0,1,3) do (
set/a "RPOS[%%J]=Cache2&0xF, Cache2=Cache2>>4" 2>NUL
for /l %%I in (0,1,3) do (
set "R[%%I][%%J]=0"
)
)
for %%p in (!RPOS!,!RPOS!,!RPOS!,!RPOS!) do (
set/a "RPOS_X=%%p>>2,RPOS_Y=%%p&0x3"
set "R[!RPOS_X!][!RPOS_Y!]=1"
)
for /l %%J in (0,1,3) do (
set "TP="
for /l %%I in (0,1,3) do (
set "TP=!TP!!R[%%I][%%J]!"
)
set "TP=!TP:0=%E0%!"
set "TP=!TP:1=%E1%!"
set/a "SN=%%J+8"
set "READM[!SN!]=!TP!"
)
echo WO>key.ini
)
goto :DATA_PROCESSING
)
if /i "!KEY:~-1!"=="Q" (exit)
)
if /i "!KEY:~-1!"=="S" (set "Dy=1"&goto :DATA_PROCESSING)
REM ~~~下落体系
if !Mark! equ 0 (
set "Mark=1"
set "T1=!time:~9,2!"
) else (
set/a "TS=2!time:~9,2!-1!T1!"
set/a "TS=1!TS:~-2!"
if !TS! lss !T! (set "Dy=0") else (set/a "Dy=1,Mark=0")
)
if !Dx! equ 0 if !Dy! equ 0 (goto :READKEY)
REM ~~~数据处理
:DATA_PROCESSING
SETLOCAL
for %%p in (!POS!,!POS!,!POS!,!POS!) do (
set/a "POS_X=(%%p>>2)+X+Dx,POS_Y=(%%p&0x3)+Y+Dy"
set/a "CHE=P[!POS_X!][!POS_Y!]"
if !CHE! equ 0 (
set "P[!POS_X!][!POS_Y!]=1"
) else (
if !Dx! neq 0 (
ENDLOCAL
goto :READKEY
)
if !Dy! equ 1 (
ENDLOCAL
if !Y! lss 2 (
echo GAME OVER!
ping -n 2 127.1>NUL
goto :DISPLAY_RAM
)
REM ~~~固化块体
set "POS_Y_MAX=0"
for %%P in (!POS!,!POS!,!POS!,!POS!) do (
set/a "POS_X=(%%P>>2)+X,POS_Y=(%%P&0x3)+Y"
if !POS_Y_MAX! lss !POS_Y! (set "POS_Y_MAX=!POS_Y!")
set "P[!POS_X!][!POS_Y!]=1"
)
REM ~~~关卡得分
for /l %%J in (!Y!,1,!POS_Y_MAX!) do (
set "TP="
for /l %%I in (1,1,10) do (
set "TP=!TP!!P[%%I][%%J]!"
)
if "!TP!"=="1111111111" (
set/a "SCORE+=10"
set "#%%J=1"
if !SCORE! equ 400 (
for /l %%N in (!Y!,1,!POS_Y_MAX!) do (set "#%%N=")
set/a "SCORE=0,LEVEL+=1,T-=10"
goto :DISPLAY_RAM
)
)
)
REM ~~~极品消行
for /l %%J in (20,-1,5) do (
if defined #%%J (
set "#%%J="
set/a "MarkJ=%%J-1, GK=1"
for /l %%N in (1,1,3) do (
if defined #!MarkJ! (set/a "MarkJ-=1")
)
set "#!MarkJ!=1"
for /l %%I in (1,1,10) do (
set/a "P[%%I][%%J]=P[%%I][!MarkJ!]"
)
)
)
if defined GK (for /l %%J in (20,-1,5) do (set "#[%%J]=1")&set "GK=")
goto :RANDOM_SHAPE
)
if /i "!KEY:~-1!"=="W" (
ENDLOCAL
echo OW>key.ini
set/a "NI=(NI+12)%%24"
goto :READKEY
)
)
)
REM ~~~绘图引擎
if !F1! equ 1 (2>NUL echo !SPACE!&set/p=<NUL) else (cls)
echo ┏%LINES%┓
for /l %%j in (0,1,5) do (set/a "MARK_Y=Y+%%j,#[!MARK_Y!]=1")
for /l %%j in (1,1,20) do (
if not defined #[%%j] (
echo;
) else (
set "TP="
for /l %%i in (1,1,10) do (set "TP=!TP!!P[%%i][%%j]!")
set "TP=!TP:1=%E1%!"
set "TP=!TP:0=%E0%!"
echo ┃!TP!┃!READM[%%j]!
)
)
echo ┗%LINES%┛
echoCopyRight@2016~2018 BY HAPPY
ENDLOCAL&for /l %%j in (1,1,20) do (set "#[%%j]=")
set/a "X+=Dx,Y+=Dy"
goto :READKEY
可执行代码下载
效果图:
页:
[1]