2048: Difference between revisions
→{{header|Batch File}}: highly improved version!
m (→{{header|Phix}}: added syntax colouring the hard way) |
Simple9371 (talk | contribs) (→{{header|Batch File}}: highly improved version!) |
||
Line 2,779:
=={{header|Batch File}}==
<lang dos>:: 2048 Game Task from RosettaCode
:: Batch File Implementation v2.0
@echo off
setlocal enabledelayedexpansion
rem initialization
:begin_game
set "score=0" %== current score ==%
set "won=0" %== boolean for winning ==%
set "target=2048" %== as the game title says ==%
for /l %%
rem add two numbers in the board
call :addtile
call :addtile
:main_loop
call :display
echo(
echo(Keys: WASD (Slide Movement), N (New game), P (Exit)
rem get keypress trick
set "key="
for /f "delims=" %%? in ('xcopy /w "%~f0" "%~f0" 2^>nul') do if not defined key set "key=%%?"
set "key=%key:~-1%"
set "changed=0" %== boolean for changed board ==%
set "valid_key=0" %== boolean for pressing WASD ==%
rem process keypress
if /i "!key!" equ "W" (set "valid_key=1" & call :slide "C" "1,1,%size%" "X")
if /i "!key!" equ "A" (set "valid_key=1" & call :slide "R" "1,1,%size%" "X")
if /i "!key!" equ "S" (set "valid_key=1" & call :slide "C" "%size%,-1,1" "X")
if /i "!key!" equ "D" (set "valid_key=1" & call :slide "R" "%size%,-1,1" "X")
if /i "!key!" equ "N" goto begin_game
if "%valid_key%" equ "0" goto main_loop
rem check if the board changed
if %changed% neq 0 call :addtile
rem check for win condition
if %won% equ 1 (
goto gameover
)
rem check for lose condition
if %blank_count% equ 0 (
for /l %%R in (1,1,%size%) do for /l %%C in (1,1,%size%) do set "LX_%%R_%%C=!X_%%R_%%C!"
set "save_changed=%changed%" & set "changed=0" %== save actual changed for test ==%
call :slide "C" "1,1,%size%" "LX"
call :slide "R" "1,1,%size%" "LX"
set "msg=No moves are possible... Game Over :("
goto gameover
) else set "changed=!save_changed!"
)
goto
:addtile
set "blank_count=0" %== blank tile counter ==%
rem create pseudo-array blank_tiles
for /l %%
for /l %%C in (1,1,%size%) do (
if !X_%%R_%%C! equ 0 (
set /a "blank_count+=1"
)
)
)
if %blank_count% equ 0 goto :EOF
set /a "pick_tile=%random%%%%blank_count%"
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
:display
cls
echo
echo(
set "wall=+"
for /l %%R in (1,1,%size%) do (
set "disp_row=|"
for /l %%C in (1,1,%size%) do (
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= "
)
set "disp_row=!disp_row!!DX_%%R_%%C!|"
)
echo(%wall%
echo(!disp_row!
)
echo(%wall%
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 . . .
pause>nul
exit /b 0</lang>
{{out}}
<pre>2048 Game in Batch
|