Batch movement game bug

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
(_osd_)
Posts: 25
Joined: 01 Mar 2015 07:41

Batch movement game bug

#1 Post by (_osd_) » 11 Aug 2016 04:19

Hello, I have been working on a little test with a topdown-rpg game. This is the code for the movement-test:

Code: Select all

@echo off
mode con cols=56 lines=18
color f0
::
set u1=Û
set u2=Û
set u3=Û
set u4=Û
set u5=Û
set u6=Û
set u7=Û
set u8=Û
set u9=Û
set u10=Û
set u11=Û
set u12=Û
set u13=Û
set u14=Û
set u15=Û
set u16=Û
set u17=Û
set u18=Û
set u19=Û
set u20=±
set u21=±
set u22=±
set u23=±
set u24=±
set u25=±
set u26=±
set u27=±
set u28=±
set u29=±
set u30=±
set u31=±
set u32=±
set u33=±
set u34=±
set u35=±
set u36=Û
set u37=Û
set u38=±
set u39=±
set u40=±
set u41=±
set u42=±
set u43=±
set u44=±
set u45=±
set u46=±
set u47=±
set u48=±
set u49=±
set u50=±
set u51=±
set u52=±
set u53=±
set u54=Û
set u55=Û
set u56=±
set u57=±
set u58=±
set u59=±
set u60=±
set u61=±
set u62=±
set u63=±
set u64=±
set u65=±
set u66=±
set u67=±
set u68=±
set u69=±
set u70=±
set u71=±
set u72=Û
set u73=Û
set u74=Û
set u75=Û
set u76=Û
set u77=Û
set u78=Û
set u79=Û
set u80=Û
set u81=Û
set u82=Û
set u83=Û
set u84=Û
set u85=Û
set u86=Û
set u87=Û
set u88=Û
set u89=Û
set u90=Û

set u20=#
set position=20
set position-full=u20
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:screen
cls
echo %u1%%u2%%u3%%u4%%u5%%u6%%u7%%u8%%u9%%u10%%u11%%u12%%u13%%u14%%u15%%u16%%u17%%u18%
echo.%u19%%u20%%u21%%u22%%u23%%u24%%u25%%u26%%u27%%u28%%u29%%u30%%u31%%u32%%u33%%u34%%u35%%u36%
echo.%u37%%u38%%u39%%u40%%u41%%u42%%u43%%u44%%u45%%u46%%u47%%u48%%u49%%u50%%u51%%u52%%u53%%u54%
echo.%u55%%u56%%u57%%u58%%u59%%u60%%u61%%u62%%u63%%u64%%u65%%u66%%u67%%u68%%u69%%u70%%u71%%u72%
echo %u73%%u74%%u75%%u76%%u77%%u78%%u79%%u80%%u81%%u82%%u83%%u84%%u85%%u86%%u87%%u88%%u89%%u90%
echo.
echo WASD
echo.
echo position:
echo %position%
choice /C WASD /N
if errorlevel 4 (
   set /a position=%position%+1
   if "u%position%"=="Û" (
       set /a position=%position%-1
       goto screen
   )
   set u%position%=±
   goto refresh
)
if errorlevel 3 (
   set /a position=%position%+18
   if "u%position%"=="Û" (
       set /a position=%position%-18
       goto screen     
   )
   set u%position%=±
   goto refresh
)
if errorlevel 2 (
   set /a position=%position%-1
   if "u%position%"=="Û" (
      set /a position=%position%+1
      goto screen   
   )
   set u%position%=±
   goto refresh
)
if errorlevel 1 (
   set /a position=%position%-18
   if "u%position%"=="Û" (
      set /a position=%position%+18
      goto screen
   )
   set u%position%=±
   goto refresh
)


:refresh
set u%position%=#
goto screen


Somehow, the walls don't work. Can anyone help me?

The walls are detected by

Code: Select all

   set /a position=%position%-18
   if "u%position%"=="Û" (
      set /a position=%position%+18
      goto screen

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Batch movement game bug

#2 Post by Aacini » 11 Aug 2016 14:21

You have a somewhat complex problem here...

Code: Select all

if errorlevel 4 (
   set /a position=%position%+1
   if "u%position%"=="Û" (
       set /a position=%position%-1
       goto screen
   )
   set u%position%=±
   goto refresh
)

Lets suppose that the value of "position" is 5. This line:

Code: Select all

   if "u%position%"=="Û" (

... means if "u5"=="Û" (. You want not "u5"; you want the value of variable "u5". This is usually done enabling Delayed Expansion and enclosing the new name of the variable in exclamation marks (Delayed Expansion):

Code: Select all

   if "!u%position%!"=="Û" (

However you have an additional problem here, because the value of "position" variable have been just modified in the previous line, and, because all these lines are enclosed in parentheses, you would need a double delayed expansion:

Code: Select all

   if "!u!position!!"=="Û" (

..., but this line does NOT work (there is no such "double delayed expansion" thing), so you need a trick. You may do a first delayed expansion in a FOR command, and then a double delayed expansion using the replaceable parameter of the FOR command:

Code: Select all

   for %%p in (!position!) do if "!u%%p!"=="Û" (

This way, the code section would finally look like this:

Code: Select all

if errorlevel 4 (
   set /a position+=1
   for %%p in (!position!) do if "!u%%p!"=="Û" (
       set /a position-=1
       goto screen
   )
   set u%position%=±
   goto refresh
)

Of course, all 4 sections must be modified the same way...

This complex method is the result of the initial complex code. There are multiple ways to do the same thing, and certain methods are much simpler:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

mode con cols=56 lines=18
color f0

rem Initialize the field
for /L %%i in (1,1,19)  do set "u%%i=Û"
for /L %%i in (20,1,71) do set "u%%i=±"
for /L %%i in (72,1,90) do set "u%%i=Û"
for    %%i in (19,36; 37,54; 55,72) do set "u%%i=Û"

set "u20=#"
set position=20

rem Initialize the movements based on the WASD errorlevels of CHOICE command
set "mov[1]=-18"
set "mov[2]=-1"
set "mov[3]=18"
set "mov[4]=1"

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:screen
cls
echo %u1%%u2%%u3%%u4%%u5%%u6%%u7%%u8%%u9%%u10%%u11%%u12%%u13%%u14%%u15%%u16%%u17%%u18%
echo %u19%%u20%%u21%%u22%%u23%%u24%%u25%%u26%%u27%%u28%%u29%%u30%%u31%%u32%%u33%%u34%%u35%%u36%
echo %u37%%u38%%u39%%u40%%u41%%u42%%u43%%u44%%u45%%u46%%u47%%u48%%u49%%u50%%u51%%u52%%u53%%u54%
echo %u55%%u56%%u57%%u58%%u59%%u60%%u61%%u62%%u63%%u64%%u65%%u66%%u67%%u68%%u69%%u70%%u71%%u72%
echo %u73%%u74%%u75%%u76%%u77%%u78%%u79%%u80%%u81%%u82%%u83%%u84%%u85%%u86%%u87%%u88%%u89%%u90%
echo/
echo WASD
echo/
echo position:
echo %position%
choice /C WASD /N
set /A newPos=position+mov[%errorlevel%]
if "!u%newPos%!" equ "Û" goto screen

:refresh
set "u%position%=±"
set "position=%newPos%"
set "u%position%=#"
goto screen

Antonio

(_osd_)
Posts: 25
Joined: 01 Mar 2015 07:41

Re: Batch movement game bug

#3 Post by (_osd_) » 12 Aug 2016 04:21

Thanks a ton, Antonio! :)

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Batch movement game bug

#4 Post by thefeduke » 06 Sep 2016 15:52

Aacini wrote:

Code: Select all

echo/
echo WASD
echo/
echo position:
echo %position%
choice /C WASD /N
So, I put on a gamer hat and did some grunt work. The above produces

Code: Select all

WASD

position: 20
Instead, if I run

Code: Select all

Call :WASDminibox display l1 l2 l3 l4
:: The above line runs just once before the :screen label
Echo/
Echo %l1%
Echo %l2% %sp% %sp% %sp% %sp%or Press 'X','Q' or 'L' to Leave.
Echo %l3%
Echo %l4%
echo/
echo position: %position%
choice /C WASDXQL /N
IF ERRORLEVEL 5 Exit /B
The output can look like

Code: Select all

  ▲
  W    or Press 'X','Q' or 'L' to Leave.
◄ASD►
  ▼

position: 20
The line spacing within the forum code block does not do justice to the text graphic. Pressing further .. . .

Code: Select all

Call :WASDbox save l1 l2 l3 l4 l5 l6 l7
:: The above line runs just once before the :screen label
echo/
Echo %l1%
Echo %l2% %sp% %sp% %sp% %sp%or Press 'X','Q' or 'L' to Leave.
Echo %l3%
Echo %l4%
Echo %l5%
Echo %l6%
Echo %l7%
echo/
echo position: %position%
choice /C WASDXQL /N
IF ERRORLEVEL 5 Exit /B
produces a text graphic that flows without line interruptions on screen

Code: Select all

   ╒═╕
   │▲│    or Press 'X','Q' or 'L' to Leave.
   │W│
╒══╪═╪══╕
│◄A│S│D►│
╘══╡▼╞══╛
   ╘═╛

position: 20
I used partial double lines because I could not find a single line bottom right hand corner.

Maybe it's just me or does anyone know codepage that has it? Edit: Yes, it was me. Thanks to Antonio's show.exe, I found it right at 0xD9.
Anyway, here are what I called :WASDbox and :WASDminiBOX. Both of these can run standalone and will return no variables if called without arguments.

Code: Select all

:WASDminiBOX SaveVariableValue[in,opt]
::           Line1variableName[out,opt]
::           Line2variableName[out,opt]
::           Line3variableName[out,opt]
::           Line4variableName[out,opt]
::           Line5variableName[out,opt]
@echo Off & SetLocal EnableDelayedExpansion

::  Assign backspace, space and four direction symbols with nicknames
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x08"') do (set "x08=%%i" & set    "BS=!x08!")
set "sp= .%BS%"
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x10"') do (set "x10=%%i" & set "Right=!x10!")
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x11"') do (set "x11=%%i" & set  "Left=!x11!")
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x1E"') do (set "x1E=%%i" & set    "Up=!x1E!")
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x1F"') do (set "x1F=%%i" & set  "Down=!x1F!")

:: Set up the dot and star
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0xFA"') do set "xFA=%%i"
Set "dot=%xFA%"
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x0F"') do set "x0F=%%i"
Set "star=%x0F%"

::  Save current code page and set code page to 437
FOR /F "tokens=*" %%A IN ('CHCP') DO FOR %%B IN (%%A) DO SET CHCP=%%B
CHCP 437 >nul

If "%~6" EQU "" (
::  Draw short directionals
    set "m1=%sp%%sp%%up%
    set "m2=%sp%%sp%W
    set "m3=%left%ASD%right%
    set "m4=%sp%%sp%%down%
    set "m5=%sp%

    If /I "%~1" EQU "" Set "Display=1"
    If /I "%~1" EQU "d" Set "Display=1"

    If /I "!display!" EQU "1" (
::      Display short prompt graphic
        Echo.
        Echo !m1!
        Echo !m2!
        Echo !m3!
        Echo !m4!
    )
) Else (
::  Draw short directionals with Star
    set "m1=%sp%%sp%%up%
    set "m2=%sp%%sp%W
    set "m3=%left%A%star%D%right%
    set "m4=%sp%%sp%S
    set "m5=%sp%%sp%%down%

    If /I "!display!" EQU "1" (
::  Display complete prompt graphic
        Echo.
        Echo !m1!
        Echo !m2!
        Echo !m3!
        Echo !m4!
        Echo !m5!
    )
)

::  Restore code page
CHCP %CHCP% >nul

If /I "%display%" EQU "1" (Echo.
    Echo.Not saving lines
    Endlocal
) Else (EndLocal & Rem.Save up to five line values
    If "%~2" NEQ "" (SET "%~2=%m1%") ELSE Set "m1=No name for line 1"
    If "%~3" NEQ "" (SET "%~3=%m2%") ELSE Set "m2=No name for line 2"
    If "%~4" NEQ "" (SET "%~4=%m3%") ELSE Set "m3=No name for line 3"
    If "%~5" NEQ "" (SET "%~5=%m4%") ELSE Set "m4=No name for line 4"
    If "%~6" NEQ "" (SET "%~6=%m5%") ELSE Set "m5=%sp% ")
Exit /B

Code: Select all

:WASDbox SaveVariableValue[in,opt]
::       Line1variableName[out,opt]
::       Line2variableName[out,opt]
::       Line3variableName[out,opt]
::       Line4variableName[out,opt]
::       Line5variableName[out,opt]
::       Line6variableName[out,opt]
::       Line7variableName[out,opt]
@echo Off & SetLocal EnableDelayedExpansion

::  Assign backspace, space and four direction symbols with nicknames
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x08"') do (set "x08=%%i" & set    "BS=!x08!")
set "sp= .%BS%"
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x10"') do (set "x10=%%i" & set "Right=!x10!")
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x11"') do (set "x11=%%i" & set  "Left=!x11!")
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x1E"') do (set "x1E=%%i" & set    "Up=!x1E!")
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x1F"') do (set "x1F=%%i" & set  "Down=!x1F!")

::  Assign formatting characters 0xBF to 0xDF with box nicknames
For %%H in (B C D) do (
    For %%I in (0 1 2 3 4 5 6 7 8 A B C D E F) do (
        For /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x%%H%%I"') do (
            Set "chr=%%i"
            Set "x%%H%%I=!chr!"
::          Add nicknames for the box Characters
            If "%%H%%I" EQU "B5" Set "drawVRbar=!x%%H%%I!"
            If "%%H%%I" EQU "B5" Set "drawRVbar=!x%%H%%I!"
            If "%%H%%I" EQU "B3" Set "drawVbar=!x%%H%%I!"
            If "%%H%%I" EQU "C6" Set "drawVLbar=!x%%H%%I!"
            If "%%H%%I" EQU "C6" Set "drawLVbar=!x%%H%%I!"
            If "%%H%%I" EQU "B8" Set "drawRTcnr=!x%%H%%I!"
            If "%%H%%I" EQU "B8" Set "drawTRcnr=!x%%H%%I!"
            If "%%H%%I" EQU "BE" Set "drawRBcnr=!x%%H%%I!"
            If "%%H%%I" EQU "BE" Set "drawBRcnr=!x%%H%%I!"
            If "%%H%%I" EQU "D5" Set "drawLTcnr=!x%%H%%I!"
            If "%%H%%I" EQU "D5" Set "drawTLcnr=!x%%H%%I!"
            If "%%H%%I" EQU "D4" Set "drawLBcnr=!x%%H%%I!"
            If "%%H%%I" EQU "D4" Set "drawBLcnr=!x%%H%%I!"
            If "%%H%%I" EQU "D1" Set "drawHTbar=!x%%H%%I!"
            If "%%H%%I" EQU "D1" Set "drawTHbar=!x%%H%%I!"
            If "%%H%%I" EQU "CD" Set "drawHbar=!x%%H%%I!"
            If "%%H%%I" EQU "CF" Set "drawHBbar=!x%%H%%I!"
            If "%%H%%I" EQU "CF" Set "drawBHbar=!x%%H%%I!"
            If "%%H%%I" EQU "D8" Set "drawCross=!x%%H%%I!"
        )
    )
)

::  Save current code page and set code page to 437
FOR /F "tokens=*" %%A IN ('CHCP') DO FOR %%B IN (%%A) DO SET CHCP=%%B
CHCP 437 >nul

::  Draw complete line box using nicknamed variables.
set "l1=%sp%%sp%%sp%%drawLTcnr%%drawHbar%%drawRTcnr%
set "l2=%sp%%sp%%sp%%drawVbar%%Up%%drawVbar%
set "l3=%sp%%sp%%sp%%drawVbar%W%drawVbar%
Set "l4=%drawLTcnr%%drawHbar%%drawHbar%%drawCross%%drawHbar%%drawCross%%drawHbar%%drawHbar%%drawRTcnr%"
Set "l5=%drawVbar%%Left%A%drawVbar%S%drawVbar%D%Right%%drawVbar%"
set "l6=%drawLBcnr%%drawHbar%%drawHbar%%drawVRbar%%Down%%drawVLbar%%drawHbar%%drawHbar%%drawRBcnr%"
Set "l7=%sp%%sp%%sp%%drawLBcnr%%drawHbar%%drawRBcnr%

If /I "%~1" EQU "" Set "Display=1"
If /I "%~1" EQU "d" Set "Display=1"

If /I "%display%" EQU "1" (
::  Display complete line box
    Echo.
    Echo %l1%
    Echo %l2%
    Echo %l3%
    Echo %l4%
    Echo %l5%
    Echo %l6%
    Echo %l7%
)

::  Restore code page
CHCP %CHCP% >nul

If /I "%display%" EQU "1" (Echo.
    Echo.Not saving lines
    Endlocal
) Else (EndLocal & Rem.Save seven line values
    If "%~2" NEQ "" (SET "%~2=%l1%") ELSE Set "l1=No name for line 1 text"
    If "%~3" NEQ "" (SET "%~3=%l2%") ELSE Set "l2=No name for line 2 text"
    If "%~4" NEQ "" (SET "%~4=%l3%") ELSE Set "l3=No name for line 3 text"
    If "%~5" NEQ "" (SET "%~5=%l4%") ELSE Set "l4=No name for line 4 text"
    If "%~6" NEQ "" (SET "%~6=%l5%") ELSE Set "l5=No name for line 5 text"
    If "%~7" NEQ "" (SET "%~7=%l6%") ELSE Set "l6=No name for line 6 text"
    If "%~8" NEQ "" (SET "%~8=%l7%") ELSE Set "l7=No name for line 7 text")
Exit /B

John A.

Post Reply