2048: Difference between revisions

1,470 bytes added ,  3 years ago
→‎{{header|Batch File}}: highly improved version!
m (→‎{{header|Phix}}: added syntax colouring the hard way)
(→‎{{header|Batch File}}: highly improved version!)
Line 2,779:
 
=={{header|Batch File}}==
<lang dos>:: 2048 Game Task from RosettaCode.org
:: Batch File Implementation v2.0
 
@echo off
setlocal enabledelayedexpansion
cls
 
rem initialization
:begin_game
set "size=4" %== Setboard variablessize ==%
set "score=0" %== current score ==%
set "won=0" %== boolean for winning ==%
set "target=2048" %== as the game title says ==%
set "SUP_score=0"
for /l %%AR in (1,1,4%size%) do for /l %%BC in (1,1,4%size%) do set /a "X_%%AR_%%BC=0"
 
rem add two numbers in the board
call :addtile
call :addtile
 
%==rem Mainmain game loop ==%
:main_loop
set "changed=0"
call :display
echo(
echo Keys: WASD (Slide Movement^), N (New game^), P (Exit^)
 
%== Get Keypress ==%
set "key="
for /f "delims=" %%? in ('xcopy /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%?"
set "key=%key:~-1%"
 
%== Process keypress ==%
if /i "!key!"=="W" (
for /l %%? in (1,1,4) do call :slide X_1%%? X_2%%? X_3%%? X_4%%?
)
if /i "!key!"=="A" (
for /l %%? in (1,1,4) do call :slide X_%%?1 X_%%?2 X_%%?3 X_%%?4
)
if /i "!key!"=="S" (
for /l %%? in (1,1,4) do call :slide X_4%%? X_3%%? X_2%%? X_1%%?
)
if /i "!key!"=="D" (
for /l %%? in (1,1,4) do call :slide X_%%?4 X_%%?3 X_%%?2 X_%%?1
)
if /i "!key!"=="N" goto :begin_game
if /i "!key!"=="P" exit /b
 
%== Check if the board changed ==%
if %changed% neq 0 call :addtile
 
%== Check if already won ==%
if %won% equ 1 (
set "msg=Nice one... You WON^!^!"
goto :gameover
)
 
%== Check for lose condition ==%
set /a "real_blanks=blank_count-1"
if %real_blanks% leq 0 (
for /l %%A in (1,1,4) do for /l %%B in (1,1,4) do set "TRY_%%A%%B=!X_%%A%%B!"
set "TRY_changed=%changed%" & set "changed=0"
set "SUP_score=1"
for /l %%? in (1,1,4) do call :slide TRY_%%?1 TRY_%%?2 TRY_%%?3 TRY_%%?4
for /l %%? in (1,1,4) do call :slide TRY_1%%? TRY_2%%? TRY_3%%? TRY_4%%?
if !changed! equ 0 (
set "msg=No moves are possible... Game Over :("
goto :gameover
) else (set "changed=!TRY_changed!" & set "SUP_score=0")
)
goto main_loop
 
 
::~~~~~~~~~~~~~~~~~~~~ Sub Procedures ~~~~~~~~~~~~~~~~~~~~::
%== Game Over xD ==%
:gameover
call :display
echo(
echo(Keys: WASD (Slide Movement), N (New game), P (Exit)
echo(!msg!
echo(
echo(Keys: N (New game^), P (Exit^)
 
rem get keypress trick
:key_loop
set "key="
for /f "delims=" %%? in ('xcopy /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%?"
set "key=%key:~-1%"
if /i "!key!"=="N" goto :begin_game
if /i "!key!"=="P" exit /b
goto :key_loop
 
set "changed=0" %== boolean for changed board ==%
%== The main slider of numbers in tiles ==%
set "valid_key=0" %== boolean for pressing WASD ==%
:slide
rem process keypress
set "next="
if /i "!key!" equ "W" (set "valid_key=1" & call :slide "C" "1,1,%size%" "X")
set "slide_1="
if /i "!key!" equ "A" (set "valid_key=1" & call :slide "R" "1,1,%size%" "X")
set "slide_2="
if /i "!key!" equ "S" (set "valid_key=1" & call :slide "C" "%size%,-1,1" "X")
for %%? in (%*) do if !%%?! neq 0 set "slide_1=!slide_1! !%%?!"
if /i "!key!" equ "D" (set "valid_key=1" & call :slide "R" "%size%,-1,1" "X")
for %%? in (!slide_1!) do (
if /i "!key!" equ "N" goto begin_game
set "scan=%%?"
if /i "!scankey!"== equ "!next!P" (exit /b 0
if "%valid_key%" equ "0" goto main_loop
set /a "next*=2"
 
if !SUP_score! equ 0 set /a "score+=!next!"
rem check if the board changed
%== WINNING CONDITION!!! ==%
if %changed% neq 0 call :addtile
if "!next!" equ "2048" set "won=1"
 
set "scan="
rem check for win condition
)
if %won% equ 1 (
set "slide_2=!slide_2! !next!"
set "nextmsg=Nice one... You WON^!scan^!"
goto gameover
)
 
set "slide_2=!slide_2! !next!"
rem check for lose condition
for /l %%? in (1,1,4) do set "final_%%?=0"
if %blank_count% equ 0 (
set "cnt=0" & for %%? in (!slide_2!) do if !cnt! lss 4 (
for /l %%R in (1,1,%size%) do for /l %%C in (1,1,%size%) do set "LX_%%R_%%C=!X_%%R_%%C!"
set /a "cnt+=1"
set "save_changed=%changed%" & set "changed=0" %== save actual changed for test ==%
set "final_!cnt!=%%?"
call :slide "C" "1,1,%size%" "LX"
)
call :slide "R" "1,1,%size%" "LX"
if not "!%1!!%2!!%3!!%4!"=="!final_1!!final_2!!final_3!!final_4!" set "changed=1"
set "cnt=0" & for %%?if in!changed! (%*)equ do0 (
set "msg=No moves are possible... Game Over :("
set /a "cnt+=1"
goto gameover
set /a "%%?=final_!cnt!"
) else set "changed=!save_changed!"
)
goto :EOFmain_loop
 
%==rem Addadd number to tilea ==%random blank tile
:addtile
set "blank_count=0" %== blank tile counter ==%
set "blank_list="
rem create pseudo-array blank_tiles
set "blank_count=0"
for /l %%AR in (1,1,4) do for /l %size%B in (1,1,4) do (
for /l %%C in (1,1,%size%) do (
if !X_%%A%%B! equ 0 (
if !X_%%R_%%C! equ 0 (
set "blank_list=!blank_list!X_%%A%%B"
set /a set "blank_tiles[!blank_count+!]=1X_%%R_%%C"
set /a "blank_count+=1"
)
)
)
)
set /a "pick_tile=(%random% %% %blank_count%)*4"
)
set /a "rnd=%random%%%10+1"
if %blank_count% equ 0 goto :EOF
set "tile_new=!blank_list:~%pick_tile%,4!"
set /a "pick_tile=%random%%%%blank_count%"
if %rnd%==5 (set !tile_new!=4) else (set !tile_new!=2)
set "new_tile=!blank_tiles[%pick_tile%]!"
set /a "rnd_newnum=%random%%%10"
rem 10% chance new number is 4, 90% chance it's 2
if %rnd_newnum% equ 5 (set "%new_tile%=4") else (set "%new_tile%=2")
set /a "blank_count-=1" %== to be used for checking lose condition ==%
goto :EOF
 
%==rem Displaydisplay the table ==%board
:display
cls
echo (2048 Game in Batch
echo(
set "wall=+"
for /l %%A in (1,1,4) do (
for /l %%BC in (1,1,4%size%) do (set "wall=!wall!----+"
for /l %%R in (1,1,%size%) do (
set "DX_%%A%%B=!X_%%A%%B!"
set "disp_row=|"
if !tile_new!==X_%%A%%B (set "DX_%%A%%B= +!X_%%A%%B!") else (
for /l %%C in (1,1,%size%) do (
if !X_%%A%%B! lss 1000 set "DX_%%A%%B= !DX_%%A%%B!"
if "!new_tile!" equ "X_%%AR_%%B! lss 100C" (set "DX_%%AR_%%BC= +!DX_X_%%AR_%%BC!") else (
if !X_%%A%%B! lss 10 set "DX_%%AR_%%BC= !DX_X_%%AR_%%BC!"
if !X_%%AR_%%BC! equlss 01000 set "DX_%%AR_%%BC= !DX_%%R_%%C!"
if !X_%%R_%%C! lss 100 set "DX_%%R_%%C= !DX_%%R_%%C!"
)
if !X_%%R_%%C! lss 10 set "DX_%%R_%%C= !DX_%%R_%%C!"
)
if !X_%%R_%%C! equ 0 set "DX_%%R_%%C= "
echo +----+----+----+----+
)
echo ^|!DX_%%A1!^|!DX_%%A2!^|!DX_%%A3!^|!DX_%%A4!^|
set "disp_row=!disp_row!!DX_%%R_%%C!|"
)
echo(%wall%
echo(!disp_row!
)
echo(%wall%
echo +----+----+----+----+
echo(
echo(Score: %score%
goto :EOF
 
rem the main slider of numbers in tiles
:slide
rem %%A and %%B are used here because sliding direction is variable
for /l %%A in (1,1,%size%) do (
rem first slide: removing blank tiles in the middle
set "slide_1="
set "last_blank=0" %== boolean if last tile is blank ==%
for /l %%B in (%~2) do (
if "%~1" equ "R" (set "curr_tilenum=!%~3_%%A_%%B!"
) else if "%~1" equ "C" (set "curr_tilenum=!%~3_%%B_%%A!")
if !curr_tilenum! equ 0 (set "last_blank=1") else (
set "slide_1=!slide_1! !curr_tilenum!"
if !last_blank! equ 1 set "changed=1"
set "last_blank=0"
)
)
rem second slide: addition of numbered tiles
rem slide_2 would be pseudo-array
set "slide_2_count=0"
set "skip=1" %== boolean for skipping after previous summing ==%
if "!slide_1!" neq "" for %%S in (!slide_1! 0) do (
if !skip! equ 1 (
set "prev_tilenum=%%S" & set "skip=0"
) else if !skip! equ 0 (
if %%S equ !prev_tilenum! (
set /a "sum=%%S+!prev_tilenum!"
set /a "score+=sum"
set "changed=1" & set "skip=1"
rem check for winning condition!
if !sum! equ !target! set "won=1"
) else (
set "sum=!prev_tilenum!"
set "prev_tilenum=%%S"
)
set "slide_2[!slide_2_count!]=!sum!"
set /a "slide_2_count+=1"
)
)
rem new values of tiles
set "slide_2_run=0" %== running counter for slide_2 ==%
for /l %%B in (%~2) do (
if "%~1" equ "R" (set "curr_tile=%~3_%%A_%%B"
) else if "%~1" equ "C" (set "curr_tile=%~3_%%B_%%A")
for %%? in ("!slide_2_run!") do (
if %%~? lss !slide_2_count! (set "!curr_tile!=!slide_2[%%~?]!"
) else (set "!curr_tile!=0")
)
set /a "slide_2_run+=1"
)
)
goto :EOF
 
rem game over xD
:gameover
call :display
echo(
echo(!msg!
echo(
echo(Press any key to exit . . .
echo Score: %score%
pause>nul
goto :EOF</lang>
exit /b 0</lang>
{{out}}
<pre>2048 Game in Batch
535

edits