Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Echo off & CD "%~dp0"
- ======================================================================================
- ::: Last Updated: 07/12/2020
- ::: getkey.exe and sleep.bat required for enhanced controls and gameplay timing
- ::: Download from:
- ======================================================================================
- ::: https://drive.google.com/file/d/18M21SoDpC4FyFBcsiYnqUAGOaciHIQMD/view?usp=sharing
- ::: Download contains:
- ::::::::::::::::::::::::::::::::::::::::::::::::::
- ::: Getkey.Exe by Antonio {https://stackoverflow.com/users/778560/aacini} for Extended key controls.
- ::: Tetris.Bat by T3RRY {https://stackoverflow.com/users/12343998/t3rr0r}
- ::: Sleep.bat by Dave Benham {https://www.dostips.com/forum/memberlist.php?mode=viewprofile&u=2258}
- ======================================================================================
- :newgame
- CHCP 65001 > nul
- Setlocal EnableExtensions DISABLEdelayedexpansion
- wmic OS get OSArchitecture,caption | FIND "10" >nul || (ECHO/Windows 10 required for ascii escape codes & Endlocal & Exit /B)
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- Title Tetris by T3RRY & rem commenced 30/10/2020
- rem ::: 30/10/2020 Piece creation, basic collision detection, piece movement implemented.
- rem ::: 31/10/2020 New piece and Game over trigger tests added.
- rem ::: 31/10/2020 Color, Piece rotation added
- rem ::: 01/11/2020 Function to test for a completed line added.
- rem ::: 01/11/2020 Scoring system added
- rem ::: 02/11/2020 Replaced choice controller with getkeys.exe
- rem ::: 02/11/2020 Implemented game levels and pace control
- rem ::: 02/11/2020 Augmented Graphics engine. New:
- rem ::: the x coords for piece drop site shown at screen base.
- rem ::: show inverted line on match
- rem ::: Unicode character ( active piece ) and Ascii character ( Locked piece )
- rem ::: 07/11/2020 Added Next Piece display
- rem ::: 13/11/2020 Corrected rotation X axis shift so pieces now maintain current Min X axis.
- rem ::: 16/11/2020 Replaced delay timing method to use Dave Benhams Sleep.bat for finer control of delay increments
- rem ------/* Getkeys controller. allows variable delay for speed increase based on score */
- For /F "Delims=" %%C in ('dir "%~dp0*GetKey.exe" /B /S') Do If not defined GetKey Set "GetKey="%%C" /n"
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- rem ---------------------------------------------------- /* ASCII escape code definition */
- for /F "delims=#" %%a in ('"prompt #$E# & for %%a in (1) do rem"') do set "\E=%%a"
- rem ------------------------------------------------ /* ensure } reference var undefined */
- (For /F "Tokens=1,2 Delims==" %%G in ('Set "}"')Do Set "%%G=") 2> nul
- rem ------------------------------------------------------------------ /* define macro's */
- Set "nPiece[1]=Set /A "x1=5,y1=1,x2=6,y2=1,x3=7,y3=1,x4=8,y4=1""
- Set "nPiece[2]=Set /A "x1=6,y1=1,x2=7,y2=1,x3=6,y3=2,x4=7,y4=2""
- Set "nPiece[3]=Set /A "x1=7,y1=1,x2=6,y2=1,x3=5,y3=2,x4=5,y4=1""
- Set "nPiece[4]=Set /A "x1=5,y1=1,x2=6,y2=1,x3=7,y3=1,x4=7,y4=2""
- Set "nPiece[5]=Set /A "x1=5,y1=2,x2=6,y2=2,x3=6,y3=1,x4=7,y4=1""
- Set "nPiece[6]=Set /A "x1=5,y1=1,x2=6,y2=1,x3=6,y3=2,x4=7,y4=2""
- Set "nPiece[7]=Set /A "x1=5,y1=1,x2=6,y2=1,x3=6,y3=2,x4=7,y4=1""
- Set "iPiece[1]=Set /A "ix1=20,iy1=16,ix2=21,iy2=16,ix3=22,iy3=16,ix4=23,iy4=16""
- Set "iPiece[2]=Set /A "ix1=21,iy1=16,ix2=22,iy2=16,ix3=21,iy3=17,ix4=22,iy4=17""
- Set "iPiece[3]=Set /A "ix1=20,iy1=16,ix2=21,iy2=16,ix3=22,iy3=16,ix4=20,iy4=17""
- Set "iPiece[4]=Set /A "ix1=20,iy1=16,ix2=21,iy2=16,ix3=22,iy3=16,ix4=22,iy4=17""
- Set "iPiece[5]=Set /A "ix1=20,iy1=17,ix2=21,iy2=17,ix3=21,iy3=16,ix4=22,iy4=16""
- Set "iPiece[6]=Set /A "ix1=20,iy1=16,ix2=21,iy2=16,ix3=21,iy3=17,ix4=22,iy4=17""
- Set "iPiece[7]=Set /A "ix1=20,iy1=16,ix2=21,iy2=16,ix3=21,iy3=17,ix4=22,iy4=16""
- Set "tetra1=▓"
- Set "tetra2=X"
- Set /A iPce=%random% %%7 + 1
- Set "DropMarker=For %%n in (1 2)Do if %%n==2 (For /F "Tokens=1,2 Delims={}" %%G in ("!Marker!")Do ( <nul Set /P "=%\E%[%%~Gm%\E%[23;!#x1!H%%~H%\E%[23;!#x2!H%%~H%\E%[23;!#x3!H%%~H%\E%[23;!#x4!H%%~H%\E%[0m" ))Else Set marker="
- Set "MoveLeft=Set "valid=0"&Set /A "_x1=!x1!-1,_x2=!x2!-1,_x3=!x3!-1,_x4=!x4!-1" & (For %%v in ("!y1!;!_x1!" "!y2!;!_x2!" "!y3!;!_x3!" "!y4!;!_x4!")Do (IF "!}%%~v!" == "" (Set /A "Valid=!Valid! + 1"))) & If "!Valid!" == "4" (Set /A "x1-=1,x2-=1,x3-=1,x4-=1")"
- Set "MoveRight=Set "valid=0"&Set /A "_x1=!x1!+1,_x2=!x2!+1,_x3=!x3!+1,_x4=!x4!+1" & (For %%v in ("!y1!;!_x1!" "!y2!;!_x2!" "!y3!;!_x3!" "!y4!;!_x4!")Do (IF "!}%%~v!" == "" (Set /A "Valid=!Valid! + 1"))) & If "!Valid!" == "4" (Set /A "x1+=1,x2+=1,x3+=1,x4+=1")"
- Set "MoveDown=Set "valid=0"&Set /A "_y1=!y1!+1,_y2=!y2!+1,_y3=!y3!+1,_y4=!y4!+1" & (For %%v in ("!_y1!;!x1!" "!_y2!;!x2!" "!_y3!;!x3!" "!_y4!;!x4!")Do (IF "!}%%~v!" == "" (Set /A "Valid=!Valid! + 1"))) & (If "!Valid!" == "4" (Set /A "y1+=1,y2+=1,y3+=1,y4+=1")Else (Set /A "Score+=25"&Set "}!y1!;!x1!=%\E%[!y1!;!x1!H%\E%[3!pce!m!tetra2!%\E%[0m"& Set "}!y2!;!x2!=%\E%[!y2!;!x2!H%\E%[3!pce!m!tetra2!%\E%[0m"& Set "}!y3!;!x3!=%\E%[!y3!;!x3!H%\E%[3!pce!m!tetra2!%\E%[0m"& Set "}!y4!;!x4!=%\E%[!y4!;!x4!H%\E%[3!pce!m!tetra2!%\E%[0m"& >"%TEMP%\tetris.~tmp" (For /F "Tokens=2* Delims==" %%G in ('Set }')Do Echo/%%G) & (For %%. in (!y1! !y2! !y3! !y4!)Do if %%. EQU 2 (Goto :GameOver)) & ( Call :isMatch & Goto :newpiece )))"
- Set "ShowPiece=<Nul Set /P "=%\E%[3!pce!m%\E%[!y1!;!x1!H!tetra1!%\E%[!y2!;!x2!H!tetra1!%\E%[!y3!;!x3!H!tetra1!%\E%[!y4!;!x4!H!tetra1!%\E%[0m""
- Set "HideLast=<Nul Set /P "=%\E%[!ly1!;!lx1!H %\E%[!ly2!;!lx2!H %\E%[!ly3!;!lx3!H %\E%[!ly4!;!lx4!H %\E%[0m""
- rem ---------------------------------------------------------- /* Define Control Display */
- Set "Score=0"
- Set /A "level=1,MaxSpeed=5"
- Set "}1;20=%\E%[1;20H%\E%[90mScore: %\E%[91m!score!"
- Set "}3;20=%\E%[3;20H%\E%[33mControls:"
- Set "}4;20=%\E%[4;20H ◄ - Left"
- Set "}5;20=%\E%[5;20H ▼ - Down"
- Set "}6;20=%\E%[6;20H ► - Right"
- Set "}7;20=%\E%[7;20HSpace - Rotate"
- Set "}8;20=%\E%[8;20HPage▼ - Drop Piece"
- Set "}9;20=%\E%[9;20HEnter - Pause"
- Set "}10;20=%\E%[10;20H%\E%[32mEscape - Exit%\E%[0m"
- Set "}12;20=%\E%[12;20H%\E%[90mLevel: %\E%[36m%\E%[7m!level!%\E%[0m"
- Set "}13;20=%\E%[13;20H%\E%[90mSpeed: %\E%[33m%\E%[7m!MaxSpeed!%%%\E%[0m"
- Set "}15;20=%\E%[14;20H%\E%[90mNext Tetramino:%\E%[0m"
- Set "BEL=( Echo/| CHOICE /N > nul 2> nul )"
- rem -------------------- /* Establish environment for macro usage and code block actions */
- Setlocal EnableDelayedExpansion
- ::: { Define Variables For mapping errorlevel to Key.
- ::: ** Numbers within the below ranges must not be assigned as other variables: k# **
- Set "k-82=Insert"
- Set "k-80=Down"
- Set "k-75=Left"
- Set "k-81=PageDown"
- Set "k-77=Right"
- Set "k32=space"
- Set "k13=enter"
- Set "k27=ESC"
- ::: }
- mode 54,24
- rem ----------------------------------------------------------------- /* hide the cursor */
- <nul Set /P "=%\E%[?25l"
- rem --------------------------------------------------------------- /* define the border */
- For %%s in (1 12)Do For /L %%n in (1 1 23) Do (
- Set "}%%n;%%s=%\E%[%%n;%%sH%\E%[90m.%\E%[0m"
- If %%n LSS 3 Set "}%%n;%%s=%\E%[%%n;%%sH%\E%!!%\E%[0m"
- If %%n==23 For /L %%b in (2 1 11)Do (
- Set "}%%n;%%b=%\E%[%%n;%%bH%\E%[90m.%\E%[0m"
- )
- )
- >"%TEMP%\tetris.~tmp" (For /F "Tokens=2* Delims==" %%G in ('Set "}"')Do Echo/%%G)
- :newpiece
- rem -------------- /* level is Score based and is used to control the speed of the game */
- For /L %%l in (2 1 20)Do For /F "Delims=" %%G in ('Set /A "tst=(%%l-1)*10000"')Do if !Score! GTR %%G Set "level=%%l"
- Set /A "MaxSpeed=!level! * 5"
- CLS
- Type "%TEMP%\tetris.~tmp"
- Set "pce=%iPce%"
- Set /A iPce=%random% %%7 + 1
- !iPiece[%iPce%]!
- !nPiece[%pce%]!
- %ShowPiece%
- %Dropmarker:#x=x%{3!Pce!}{▄}
- :loop
- rem ----------------------------- /* get pieces last y;x vals to blank out with hidelast */
- For %%c in (y x)Do For %%i in (1 2 3 4)Do Set "l%%c%%i=!%%c%%i!"
- %Dropmarker:#x=x%{3!Pce!}{▄}
- <nul Set /P "=%\E%[!iy1!;!ix1!H%\E%[3!iPce!m%Tetra1%%\E%[0m%\E%[!iy2!;!ix2!H%\E%[3!iPce!m%Tetra1%%\E%[0m%\E%[!iy3!;!ix3!H%\E%[3!iPce!m%Tetra1%%\E%[0m%\E%[!iy4!;!ix4!H%\E%[3!iPce!m%Tetra1%%\E%[0m"
- rem ----------------------------------------------------------------------- /* game pace */
- Set /A Delay=400 / level
- Call Sleep.bat %Delay% !Time!
- Set Key=
- %GetKey%
- For %%E in (!Errorlevel!) Do Set "Key=!k%%E!"
- If Not "!Key!" == "" (
- Goto :Move
- )
- %MoveDown%
- %HideLast%
- %Dropmarker:#x=lx%{90}{.}
- %ShowPiece%
- Goto :loop
- rem ----------------------------------------------------------------- /* game controller */
- :Move
- For %%G in (!Key!) Do (
- If /I "%%G" == "esc" ( %BEL% & TITLE Quit Y\N?&For /F "Delims=" %%C in ('Choice /N /C:YN')Do if %%C==Y (Title & Goto :quit)Else (Title Tetris by T3RRY))
- If /I "%%G" == "enter" ( Title Paused & Pause > nul & Title Tetris by T3RRY )
- If /I "%%G" == "pagedown" For /L %%s in (1 1 21)Do %MoveDown%
- If /I "%%G" == "left" (
- %Moveleft%
- %Dropmarker:#x=lx%{90}{.}
- )
- If /I "%%G" == "right" (
- %Moveright%
- %Dropmarker:#x=lx%{90}{.}
- )
- If /I "%%G" == "down" %Movedown%
- rem ------------------------------------------------------------ /* start rotation logic */
- rem --- [ Horizontal flip followed by mirror to simulate 90 degree rotation. ]
- If /I "%%G" == "space" (
- rem ----------------------------------------------------------------- /* flip horizontal */
- Set /A midX=500,midY=500
- For %%A in ("!y1!;!x1!" "!y2!;!x2!" "!y3!;!x3!" "!y4!;!x4!") Do (
- For /F "Tokens=1,2 Delims=;" %%X in ("%%~A") Do (
- Set /A "oY=%%~X"
- Set /A "oX=%%~Y"
- )
- If !oY! LSS !midY! Set /A "midY=!oY!"
- If !oX! LSS !midX! Set /A "midX=!oX!"
- )
- Set "pixel=0"
- For %%B in ("!y1!;!x1!" "!y2!;!x2!" "!y3!;!x3!" "!y4!;!x4!") Do (
- Set /A pixel+=1
- For /F "Tokens=1,2 Delims=;" %%r in ("%%~B") Do (
- Set /A "ny!pixel!=(%%~s-midX)+!midY!,nx!pixel!=(%%~r-!midY!)+!midX!"
- ))
- rem --------------- /* mirror, correcting piece centre X axis by piece type / orientation */
- Set "pixel=0"
- Set /A lmidX=500,umidX=0
- For %%C in (!nx1! !nx2! !nx3! !nx4!) Do (
- If %%C LSS !lmidX! (Set /A "lmidX=%%C")
- If %%C GTR !umidX! (Set /A "umidX=%%C")
- )
- If !Centre!==0 (
- Set "Centre=1"
- ) Else Set Centre=0"
- Set /A PceWidth=umidX-lmidX
- If !PceWidth!==2 Set "Centre=1"
- If !Pce!==2 Set "Centre=1"
- If !Pce!==1 (
- If !PceWidth!==1 Set "Centre=0"
- If !PceWidth!==3 Set "Centre=1"
- )
- Set /A "Mid.X=( !lmidX! + !umidX! ) / 2"
- For %%X in (!nx1! !nx2! !nx3! !nx4!) Do (
- Set /A "pixel=!pixel! + 1"
- Set /A "nx!pixel!=%%X + !centre!"
- IF %%X LSS !Mid.X! (Set /A "nx!pixel!= %%X + ((!Mid.X!-%%X) * 2) + !centre!")
- IF %%X GTR !Mid.X! (Set /A "nx!pixel!= %%X - ((%%X-!Mid.X!) * 2) + !centre!")
- )
- rem ------------------------------------------- /* collision detection for rotated coords */
- Set "valid=0"
- For /L %%i in (1 1 4)Do (
- for %%c in ("!ny%%i!;!nx%%i!")Do If "!}%%~c!" == "" (
- Set /A "valid=!valid!+1"
- ))
- If "!valid!" == "4" (
- For %%v in (x y)Do For /L %%i in (1 1 4)Do (
- Set "%%v%%i=!n%%v%%i!"
- )
- %Dropmarker:#x=lx%{90}{.}
- ))
- rem --------------------------------------------------------------- /* end rotation logic */
- rem ------------------------------------------------------------ /* display current state */
- TYPE "%TEMP%\tetris.~tmp"
- %HideLast%
- %ShowPiece%
- %Dropmarker:#x=x%{3!Pce!}{▄}
- )
- Goto :loop
- rem ----------------------------- /* test for completed line when a piece is set in place */
- :isMatch
- %HideLast%
- %ShowPiece%
- Set "match=0"
- Set "ymin=24"
- Set "ymax=0"
- For %%n in (!y1! !y2! !y3! !y4!)Do (
- if %%n gtr !ymax! Set "ymax=%%n"
- if %%n lss !ymin! Set "ymin=%%n"
- )
- rem ------------- /* test completion of line for each y coord for last piece set in place */
- For /L %%i in (!ymin! 1 !ymax!)Do (
- Set "#of10=0"
- For /L %%c in (2 1 11)Do If Not "!}%%i;%%c!" == "" Set /A "#of10=!#of10!+1"
- If "!#of10!" == "10" (
- <nul Set /P "=%\E%[7m!}%%i;2!%\E%[7m!}%%i;3!%\E%[7m!}%%i;4!%\E%[7m!}%%i;5!%\E%[7m!}%%i;6!%\E%[7m!}%%i;7!%\E%[7m!}%%i;8!%\E%[7m!}%%i;9!%\E%[7m!}%%i;10!%\E%[7m!}%%i;11!"
- Call Sleep.bat 200 !Time!
- Set /A "match=!match!+1"
- Set /A "Score+=250 * ( !match! + ( !level! / 3 ) )"
- Set /A "lineabove=%%i-1"
- For /L %%n in (0 1 !lineabove!) Do (
- Set /A "offset=%%n+1"
- rem -------------------------- /* transfer updated coord values after iteration complete */
- For %%o in (!offset!)Do For /L %%x in (2 1 11) Do If not "!}%%n;%%x!" == "" (
- Set "n}%%o;%%x=!}%%n;%%x:[%%n;=[%%o;!"
- ) Else (
- Set "n}%%o;%%x="
- ))
- For /L %%Y in (1 1 %%i) Do For /L %%X in (2 1 11) Do Set "}%%Y;%%X=!n}%%Y;%%X!"
- ))
- rem ----------------------------- /* Update display values for each cell to display file */
- >"%TEMP%\tetris.~tmp" (For /F "Tokens=2* Delims==" %%G in ('Set "}"')Do Echo/%%G)
- Exit /B 0
- :Delay
- exit /B 0
- :gameover
- %HideLast%
- %ShowPiece%
- %BEL%
- Echo/%\E%[2;20H%\E%[31mGame Over.%\E%[0m
- Timeout /T 2 /NoBreak > nul
- Pause > nul
- CLS
- Echo(%\E%[12;18H%\E%[33mPlay Again %\E%[32mY%\E%[33m\%\E%[31mN%\E%[33m ?%\E%[0m
- For /F "Delims=" %%C in ('Choice /N') Do if "%%C" == "Y" (
- Endlocal
- Endlocal
- Goto :newgame
- )
- :quit
- rem -------------------------------------- /* restore the cursor ; End of script cleanup */
- <nul Set /P "=%\E%[?25h"
- Del /Q "%TEMP%\tetris.~tmp" 2> nul
- Endlocal
- Endlocal
- cls
- (Title )
- Goto :Eof
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement