Subscribe to MORPH        RSS Feed
-----

Batch Tetris Game

Icon Leave Comment
This is a pretty good batch Tetris game

@echo off
color 0a
setlocal EnableDelayedExpansion

if "%~1" neq "" goto %1

title Tetris
set "F16x8=REM"

cls
echo/
echo ===  Batch game - Tetris  ===
echo/
echo/
echo Tetris pieces are controlled with these keys:
echo/
echo                                 rot.right
echo rot.             rot.     move      I      move
echo left ^<- A S D -^> right    left ^<- J K L -^> right
echo           ^|                         ^|
echo           v                         v
echo       soft drop                 hard drop
echo/
echo/
echo Press P to pause the game; press N to end game
echo/
echo/
pause
cls

rem Field dimensions
set /A cols=10, lines=20

set /A col=cols+6, lin=lines+8
%F16x8% set /A lin+=lines+2
mode CON: cols=%col% lines=%lin%
if %errorlevel% neq 0 (
   echo Configuration error^^^!
   echo You must select a font size that allows to set
   echo a text window of %col% columns X %lin% lines
   pause
   goto :EOF
)

chcp 850 > NUL
cd . > pipeFile.txt
"%~F0" Input >> pipeFile.txt  |  "%~F0" Main < pipeFile.txt
ping localhost -n 2 > NUL
del pipeFile.txt
goto :EOF



:Input
set "com[J]=Dx=-1"
set "com[L]=Dx=1"
set "com[K]=del=3"
set "com[I]=R=-1"
set "com[A]=R=1"
set "com[D]=R=-1"
set "com[S]=Dy=-1"
set "com[Y]=Y"
set "com[N]=N=1"
set "com[P]=pause=1"

for /L %%# in () do (
   set "key="
   for /F "delims=" %%k in ('xcopy /W "%~F0" "%~F0" 2^>NUL') do if not defined key set "key=%%k"
   for /F %%k in ("!key:~-1!") do (
      echo(!com[%%k]!
      if /I "%%k" equ "N" exit
   )
)
rem exit



:Main

(
   for /F "delims==" %%v in ('set') do set "%%v="
   set /A cols=%cols%, lines=%lines%
   set "F16x8=%F16x8%"
)

rem Initialize the Field
for /L %%i in (1,1,%cols%) do set "spc=!spc! "
for /L %%i in (1,1,%lines%) do set "F%%i=  %spc%"
set /A top=lines+1
set "F%top%=  " & set "F0=  "
for /L %%i in (1,1,%cols%) do set "F%top%=!F%top%!" & set "F0=!F0!"
set "F%top%=!F%top%!" & set "F0=%F0%"
set "F-1=  Level: 1" & set "Level=1"
set "F-2=   Rows: 0" & set "Rows=0"
set "F-3=  Score: 0" & set "Score=0"
for /L %%i in (1,1,%cols%) do set "blk=!blk!"
set /A top=lines+3, delay=50
%F16x8% set /A linesP2=lines+2

rem Define all ":orientations:" of the O I S Z L J T pieces via "triplets":
rem (offset Y . offset X . length X); one "triplet" for each horizontal line
for %%t in ( "O:0.-1.2 -1.-1.2"
             "I:0.-2.4:1.0.1 0.0.1 -1.0.1 -2.0.1"
             "S:0.0.2 -1.-1.2:1.0.1 0.0.2 -1.1.1"
             "Z:0.-1.2 -1.0.2:1.1.1 0.0.2 -1.0.1"
             "L:0.-1.3 -1.-1.1:1.0.1 0.0.1 -1.0.2:1.1.1 0.-1.3:1.-1.2 0.0.1 -1.0.1"
             "J:0.-1.3 -1.1.1:1.0.2 0.0.1 -1.0.1:1.-1.1 0.-1.3:1.0.1 0.0.1 -1.-1.2"
             "T:0.-1.3 -1.0.1:1.0.1 0.0.2 -1.0.1:1.0.1 0.-1.3:1.0.1 0.-1.2 -1.0.1" ) do (
   set "pc=%%~t"
   set "i=-1"
   for /F "delims=" %%p in (^"!pc::^=^
% New line %
!^") do (
      if !i! lss 0 (set "pc=%%p") else set "!pc!!i!=%%p"
      set /A i+=1
   )
   set "!pc!N=!i!"
)
set "pcs=OISZLJT"

set "init=1"
for /L %%# in () do (

   if defined init (
      setlocal EnableDelayedExpansion
      set "init="

      rem Create the first "previous" piece
      for /L %%i in (0,1,!time:~-1!) do set /A p=!random!%%7
      for %%p in (!p!) do set "p2=!pcs:~%%p,1!"
      for %%p in (!p2!) do set "p3=!%%p0!" & set "p4=!%%pN!"

      set "new=1"
   )

   if defined new (
      set "new="

      rem Take the "previous" piece as current one
      set "pc=!p2!" & set "p0=!p3!" & set "pN=!p4!"

      rem Create a new "previous" piece
      for /L %%i in (1,1,2) do (
         set /A p=!random!*7/32768
         for %%p in (!p!) do (
            set "p=!pcs:~%%p,1!"
            if !p! neq !pc! set "p2=!p!"
         )
      )
      for %%p in (!p2!) do set "p3=!%%p0!" & set "p4=!%%pN!"

      rem Insert the new "previous" piece in its place, above Field
      set /A x=3+cols/2, y=top, yp=top-1
      set "F!yp!=   %spc%"
      for %%p in (!p3!) do (
         for /F "tokens=1-3 delims=." %%i in ("%%p") do (
            set /A yp=y+%%i, xp=x+%%j, xL=xp+%%k
            for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
               set "F%%a=!spc:~0,%%b!!blk:~0,%%k!!spc:~%%c!"
            )
         )
      )

      rem Try to insert the new current piece in the Field...
      set /A x=3+cols/2, y=lines,   b=1
      for %%p in (!p0!) do (
         for /F "tokens=1-3 delims=." %%i in ("%%p") do (
            set /A yp=y+%%i, xp=x+%%j, xL=xp+%%k
            for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
               if "!F%%a:~%%b,%%k!" neq "!spc:~0,%%k!" set     "b="
               set "F%%a=!F%%a:~0,%%b!!blk:~0,%%k!!F%%a:~%%c!"
            )
         )
      )
      cls
      for /L %%i in (%top%,-1,-3) do (
         echo(!F%%i!
%F16x8%  if %%i geq %linesP2% echo(!F%%i!
%F16x8%  if %%i geq 1 if %%i leq %lines% echo(!F%%i!
      )

      rem ... if that was not possible:
      if not defined b call :endGame & endlocal

      set "p1=!p0!"
      set /A "pI=0, del=delay, b=1!time:~-2!"

   )

   rem Control module: move the piece as requested via a key, or down one row each %del% centiseconds
   set "move="
   set /A "Dy=Dx=0"
   set /P "com="
   if defined com (
      set /A "!com!, move=1"
      set "com="
      if defined N exit
      if defined pause call :Pause & set "move="
      set "b=1!time:~-2!"
   ) else (
      set /A "e=1!time:~-2!, elap=e-b, elap-=(elap>>31)*100"
      if !elap! geq !del! set /A b=e, Dy=move=-1
   )

   if defined move (

      rem Delete the piece from its current position, and store current coordinates
      set i=0
      for %%p in (!p0!) do for /F "tokens=1-3 delims=." %%i in ("%%p") do (
         set /A yp=y+%%i, xp=x+%%j, xL=xp+%%k
         for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
            set "F%%a=!F%%a:~0,%%b!!spc:~0,%%k!!F%%a:~%%c!"
            set /A i+=1
            set "c!i!=%%a %%b %%c %%k"
         )
      )

      rem If move is Rotate: get rotated piece
      if defined R (
         set /A "p=(pI+R+pN)%%pN"
         for /F "tokens=1,2" %%i in ("!pc! !p!") do set "p1=!%%i%%j!"
      )

      rem Test if the piece can be placed at the new position, and store new coordinates
      set j=0
      for %%p in (!p1!) do if defined move (
         for /F "tokens=1-3 delims=." %%i in ("%%p") do (
            set /A yp=y+%%i+Dy, xp=x+%%j+Dx, xL=xp+%%k
            for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
               if "!F%%a:~%%b,%%k!" equ "!spc:~0,%%k!" (
                  set /A j+=1
                  set "n!j!=%%a %%b %%c %%k"
               ) else (
                  set "move="
               )
            )
         )
      )

      if defined move (

         rem Place the piece at the new position
         for /L %%j in (1,1,!j!) do (
            for /F "tokens=1-4" %%a in ("!n%%j!") do (
               set "F%%a=!F%%a:~0,%%b!!blk:~0,%%d!!F%%a:~%%c!"
            )
         )

         rem Update the Field in screen
         cls
         for /L %%i in (%top%,-1,-3) do (
            echo(!F%%i!
%F16x8%     if %%i geq %linesP2% echo(!F%%i!
%F16x8%     if %%i geq 1 if %%i leq %lines% echo(!F%%i!
         )

         rem Update any changes in the piece
         set /A y+=Dy, x+=Dx
         if defined R set "p0=!p1!" & set "pI=!p!" & set "R="

      ) else (   rem The piece can not be moved

         rem Recover the piece at its current position
         for /L %%i in (1,1,!i!) do (
            for /F "tokens=1-4" %%a in ("!c%%i!") do (
               set "F%%a=!F%%a:~0,%%b!!blk:~0,%%d!!F%%a:~%%c!"
            )
         )
         if defined R set "p1=!p0!" & set "R="

         if !Dy! neq 0 (   rem The piece "lands"

            rem Count completed lines
            set "j=0"
            for /L %%i in (1,1,!i!) do for /F %%a in ("!c%%i!") do (
               if "!F%%a:~3,%cols%!" equ "%blk%" (
                  set "F%%a=  %spc: ==%"
                  set /A j+=1
               )
            )

            if !j! neq 0 (
               rem Update scores (See N-Blox at http://www.tetrisfriends.com/help/tips_appendix.php#rankingsystem)
               set /A "xp=Level*(40+((j-2>>31)+1)*60+((j-3>>31)+1)*200+((j-4>>31)+1)*900), Score+=xp, Rows+=j, xL=Level, Level=(Rows-1)/10+1"
               set "F-2=!F-2:~0,8!+!j!     "
               set "xp=!xp!     "
               set "F-3=!F-3:~0,8!+!xp:~0,6!"
               echo  BEL Ctrl-G Ascii-7
               cls
               for /L %%i in (%top%,-1,-3) do (
                  echo(!F%%i!
%F16x8%           if %%i geq %linesP2% echo(!F%%i!
%F16x8%           if %%i geq 1 if %%i leq %lines% echo(!F%%i!
               )
               set "F-1=!F-1:~0,8! !Level!"
               set "F-2=!F-2:~0,8! !Rows!"
               set "F-3=!F-3:~0,8! !Score!"
               if !Level! neq !xL! if !delay! gtr 5 set /A delay-=5

               rem Remove completed lines
               set "i=1"
               for /L %%i in (1,1,%lines%) do (
                  set "F!i!=!F%%i!"
                  if "!F%%i:~3,1!" neq "=" set /A i+=1
               )
               for /L %%i in (!i!,1,%lines%) do set "F%%i=  %spc%"
               call :Delay 95
               cls
               for /L %%i in (%top%,-1,-3) do (
                  echo(!F%%i!
%F16x8%           if %%i geq %linesP2% echo(!F%%i!
%F16x8%           if %%i geq 1 if %%i leq %lines% echo(!F%%i!
               )
            )

            rem Request to show a new piece
            set "new=1"

         )

      )

   )

)

:endGame
set /P "=Play again? " < NUL
:choice
   set /P "com="
if not defined com goto choice
if /I "%com%" equ "Y" exit /B
if /I "%com:~0,1%" neq "N" set "com=" & goto choice
echo N
exit


:Pause
set "pause=!F%lines%!"
set "F%lines%=  %spc:          =  PAUSED  %"
cls & for /L %%i in (%top%,-1,-3) do (
         echo(!F%%i!
%F16x8%  if %%i geq %linesP2% echo(!F%%i!
%F16x8%  if %%i geq 1 if %%i leq %lines% echo(!F%%i!
      )
:wait
   set /P "com="
if not defined com goto wait
set "com="
set "F%lines%=%pause%"
cls & for /L %%i in (%top%,-1,-3) do (
         echo(!F%%i!
%F16x8%  if %%i geq %linesP2% echo(!F%%i!
%F16x8%  if %%i geq 1 if %%i leq %lines% echo(!F%%i!
      )
set "pause="
exit /B


:Delay centisecs
set "b=1%time:~-2%"
:wait2
   set /A "e=1%time:~-2%, elap=e-b, elap-=(elap>>31)*100"
if %elap% lss %1 goto wait2
set "b=1%time:~-2%"
exit /B

0 Comments On This Entry

 

Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

October 2017

S M T W T F S
1234567
891011121314
15161718192021
22 232425262728
293031    

Recent Entries

Search My Blog

0 user(s) viewing

0 Guests
0 member(s)
0 anonymous member(s)

Categories