2048: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: added syntax colouring the hard way) |
Simple9371 (talk | contribs) (→{{header|Batch File}}: highly improved version!) |
||
Line 2,779: | Line 2,779: | ||
=={{header|Batch File}}== |
=={{header|Batch File}}== |
||
<lang dos>::2048 Game Task from RosettaCode |
<lang dos>:: 2048 Game Task from RosettaCode |
||
::Batch File Implementation |
:: Batch File Implementation v2.0 |
||
@echo off |
@echo off |
||
setlocal enabledelayedexpansion |
setlocal enabledelayedexpansion |
||
cls |
|||
rem initialization |
|||
:begin_game |
:begin_game |
||
set "size=4" %== board size ==% |
|||
set "score=0" |
set "score=0" %== current score ==% |
||
set "won=0" |
set "won=0" %== boolean for winning ==% |
||
set "target=2048" %== as the game title says ==% |
|||
set "SUP_score=0" |
|||
for /l %% |
for /l %%R in (1,1,%size%) do for /l %%C in (1,1,%size%) do set "X_%%R_%%C=0" |
||
rem add two numbers in the board |
|||
call :addtile |
call :addtile |
||
call :addtile |
call :addtile |
||
rem main game loop |
|||
:main_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 |
call :display |
||
echo( |
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=" |
set "key=" |
||
for /f "delims=" %%? in ('xcopy /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%?" |
for /f "delims=" %%? in ('xcopy /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%?" |
||
set "key=%key:~-1%" |
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 "!key!" equ "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 "msg=Nice one... You WON^!^!" |
|||
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" |
|||
if !changed! equ 0 ( |
|||
set "msg=No moves are possible... Game Over :(" |
|||
set /a "cnt+=1" |
|||
goto gameover |
|||
set /a "%%?=final_!cnt!" |
|||
) else set "changed=!save_changed!" |
|||
) |
) |
||
goto |
goto main_loop |
||
rem add number to a random blank tile |
|||
:addtile |
:addtile |
||
set "blank_count=0" %== blank tile counter ==% |
|||
set "blank_list=" |
|||
rem create pseudo-array blank_tiles |
|||
set "blank_count=0" |
|||
for /l %% |
for /l %%R in (1,1,%size%) 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 "blank_tiles[!blank_count!]=X_%%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 |
goto :EOF |
||
rem display the board |
|||
:display |
:display |
||
cls |
cls |
||
echo |
echo(2048 Game in Batch |
||
echo( |
echo( |
||
set "wall=+" |
|||
for /l %%A in (1,1,4) do ( |
|||
for /l %%C in (1,1,%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_%%R_%%C" (set "DX_%%R_%%C= +!X_%%R_%%C!") else ( |
|||
set "DX_%%R_%%C=!X_%%R_%%C!" |
|||
if !X_%%R_%%C! lss 1000 set "DX_%%R_%%C= !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( |
||
echo(Press any key to exit . . . |
|||
echo Score: %score% |
|||
pause>nul |
|||
goto :EOF</lang> |
|||
exit /b 0</lang> |
|||
{{out}} |
{{out}} |
||
<pre>2048 Game in Batch |
<pre>2048 Game in Batch |