@echo off
rem
rem Sokoban.bat
rem (c) 2008 Aleksej Borisov aka Imp5
rem
rem testing for CHOICE
set choice_supported=1
choice /? > nul
if %errorlevel% NEQ 0 set choice_supported=0
rem ---------------------------------------------------------------
set level=0
goto load_level_%level%
rem ---------------------------------------------------------------
:main_loop
cls
echo.
echo%z0%
echo%z1%
echo%z2%
echo%z3%
echo%z4%
echo%z5%
echo%z6%
echo%z7%
echo%z8%
echo%z9%
echo%z10%
echo%z11%
echo%z12%
echo%z13%
echo.
echo.
set /a dx=0
set /a dy=0
if %need_score% NEQ 0 goto skip_well_done
call :level_complete
goto load_level_%level%
:skip_well_done
if %choice_supported% NEQ 0 goto skip_set_p
echo Type [W] [S] [A] [D] to move [Q] to exit and press [Enter].
set /p ch=
if not '%ch%'=='' set ch=%ch:~0,1%
if (%ch%)==(W) goto key_up
if (%ch%)==(S) goto key_down
if (%ch%)==(A) goto key_left
if (%ch%)==(D) goto key_right
if (%ch%)==(Q) goto key_exit
if (%ch%)==(w) goto key_up
if (%ch%)==(s) goto key_down
if (%ch%)==(a) goto key_left
if (%ch%)==(d) goto key_right
if (%ch%)==(q) goto key_exit
goto end_switch_keys
:skip_set_p
if %choice_supported% NEQ 1 goto skip_choice
echo Press [W] [S] [A] [D] to move [Q] to exit.
choice /C:WSADQ > nul
if errorlevel 5 goto key_exit
if errorlevel 4 goto key_right
if errorlevel 3 goto key_left
if errorlevel 2 goto key_down
if errorlevel 1 goto key_up
goto end_switch_keys
:skip_choice
:key_exit
cls
goto EOF
:key_right
set /a dx=1
set /a dy=0
goto end_switch_keys
:key_left
set /a dx=-1
set /a dy=0
goto end_switch_keys
:key_down
set /a dx=0
set /a dy=1
goto end_switch_keys
:key_up
set /a dx=0
set /a dy=-1
goto end_switch_keys
:end_switch_keys
set /a next_x=x+dx
set /a next_y=y+dy
set /a next_x2=x+dx*2
set /a next_y2=y+dy*2
call :getvalue %next_x% %next_y%
set next_value=%result%
if %next_value%==@ set next_value=.
if %next_value%==. goto can_move
if %next_value%==# goto cannot_move
if %next_value% NEQ 0 goto skip_zero
call :getvalue %next_x2% %next_y2%
if %result% NEQ X goto skip_x0
call :setvalue %next_x2% %next_y2% 0
call :setvalue %next_x% %next_y% .
set next_value=X
goto can_move
:skip_x0
if %result% NEQ . goto skip_dot0
call :setvalue %next_x2% %next_y2% o
call :setvalue %next_x% %next_y% .
set next_value=X
set /a need_score=need_score+1
goto can_move
:skip_dot0
goto cannot_move
:skip_zero
if %next_value% NEQ o goto skip_o
call :getvalue %next_x2% %next_y2%
if %result% NEQ X goto skip_x1
call :setvalue %next_x2% %next_y2% 0
call :setvalue %next_x% %next_y% .
set next_value=.
set /a need_score=need_score-1
goto can_move
:skip_x1
if %result% NEQ . goto skip_dot1
call :setvalue %next_x2% %next_y2% o
call :setvalue %next_x% %next_y% .
set next_value=.
goto can_move
:skip_dot1
goto cannot_move
:skip_o
:can_move
call :setvalue %x% %y% %saved_value%
set saved_value=%next_value%
set /a x+=dx
set /a y+=dy
call :setvalue %x% %y% @
:cannot_move
goto main_loop
rem ---------------------------------------------------------------
:load_level_0
set z0=.
set z1= #############
set z2= #......###..#
set z3= #......###..#
set z4= #...o.......#
set z5= #........X..#
set z6= #...o.......#
set z7= #........X..#
set z8= #...........#
set z9= #..###......#
set z10= #..###......#
set z11= #...........#
set z12= #############
set z13=.
set /a x=4
set /a y=3
set /a need_score=2
set saved_value=.
call :setvalue %x% %y% @
goto main_loop
rem ---------------------------------------------------------------
:load_level_1
set z0=.
set z1=.
set z2= #########
set z3= #.......#
set z4= #.o.##..#
set z5= ######.##..#
set z6= #.....o....#
set z7= #.o........#
set z8= ######..#####
set z9= #.........#
set z10= #..X.X.X..#
set z11= #.........#
set z12= ###########
set z13=.
set /a x=6
set /a y=9
set /a need_score=3
set saved_value=.
call :setvalue %x% %y% @
goto main_loop
rem ---------------------------------------------------------------
:load_level_2
set z0= #########
set z1= ##.......#
set z2= ####### #........#
set z3= #.....### #.o......#
set z4= ##.###.o.######..####..###
set z5= #.o..............# #....#
set z6= #...#...####.....# #....#
set z7= ##XX#...# ####### ###.##
set z8= ##.##### #.#
set z9= #.# ##### #.#
set z10= #.##########...## #.#
set z11= ##...............#####.#
set z12= #.X.#######............#
set z13= ##### ##############
set /a x=4
set /a y=4
set /a need_score=3
set saved_value=.
call :setvalue %x% %y% @
goto main_loop
rem ---------------------------------------------------------------
:load_level_3
cls
echo.
echo.
echo.
echo -------------------------------------
echo C O N G R A T U L A T I O N S
echo -------------------------------------
echo.
echo.
pause > nul
goto EOF
rem ---------------------------------------------------------------
:level_complete
echo Well Done!
pause > nul
set /a level=level+1
goto EOF
rem ---------------------------------------------------------------
:setvalue
set xx=%1
set yy=%2
set /a xx_plus_1=xx+1
call set z%yy%=%%z%yy%:~0,%xx%%%%%3%%z%yy%:~%xx_plus_1%%%
goto EOF
rem ---------------------------------------------------------------
:getvalue
set xx=%1
set yy=%2
call set result=%%z%yy%:~%xx%,1%%
goto EOF
:EOF