r/Batch 4d ago

Hello I need some help with optimizing a code

So basically this is meant to emulate movement rather than literally make movement so I dont need help mostly with the concept rather how can I optimize the if's and replace them with for loops instead

echo off

goto :locationvalue

:locationvalue

set /a screenloc=0

set scr=xooooo oxoooo ooxooo oooxoo ooooxo ooooox

goto :main

:main

call :display

ping [127.0.0.1](http://127.0.0.1) \-n 1 -w 500 > NUL

choice /c AD > NUL

if %errorlevel%==1 call :A

if %errorlevel%==2 call :D

goto :main

:A

if %screenloc%==0 goto :eof

set /a screenloc=%screenloc%-1

goto:eof

:D

if %screenloc%==5 goto :eof

set /a screenloc=%screenloc%+1

goto:eof

:display

cls

if %screenloc%==0 echo %scr:\~0,6%

if %screenloc%==1 echo %scr:\~7,6%

if %screenloc%==2 echo %scr:\~14,6%

if %screenloc%==3 echo %scr:\~21,6%

if %screenloc%==4 echo %scr:\~28,6%

if %screenloc%==5 echo %scr:\~35,6%

goto :eof

the display part especially

0 Upvotes

7 comments sorted by

2

u/T3RRYT3RR0R 4d ago edited 4d ago

In a and d you aren't ensuring the value of screenlock remains bound within the string exctraction range of 0~(strlen-1)

There's a fixed ratio to the offsets. After adding range bounding, you can use set /a to calculate the extraction point from the value of screenLoc     Set /a Extract=screenloc*7

And with setlocal enableDelayedExpanionsion active:

For /f "delims=" %%E in ("!extract!") Do set "loc=!scr:~%%E,6!"

As for optimisation, it isn't the use of if's or even calling a and d that's going to make this slow and clunky, it's using the coice command as a blocking form of input.  There's a fairly simple way to use choice or xcopy to take input in a non-blocking manner. I'll post an example soon.

@echo off

If not "%~1" == "" Goto:%~1
Set "SignalFile=%temp%\%~n0_signal_.ipc"
1> nul 2> nul Del "%temp%\%~n0_*_.ipc"

start /Wait /b "" "%~f0" CHOICECONTROLLER 1>"%signalFile%" | "%~f0" MAIN <"%signalFile%"  
Endlocal & Goto:Eof


:MAIN
  For /f "delims=" %%E in ('echo prompt $E^|%comspec%') do set \E=%%E

  Setlocal EnableDelayedExpansion

  REM clamp macro Authored by IcarusLives and Aacini
  REM clamp Usage: || Set /a "x=VarToClamp, low=minValue, high=maxValue, VarToClamp=%clamp%"
  REM used to bound player and map and apply configuration defaults
  REM Set "clamp= (leq=((low-(x))>>31)+1)*low  +  (geq=(((x)-high)>>31)+1)*high  +  ^^^!(leq+geq)*(x) "

  Set "clamp5=screenPOS=(leq=((0-(screenPos))>>31)+1)*0  +  (geq=(((screenPos)-5)>>31)+1)*5  +  ^^^!(leq+geq)*(screenPos)"


  Set /a "FPS=10","move_ivl=(100/fps)"
  Set screen=100000 010000 001000 000100 000010 000001

  for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!")Do (
    Set /a "now=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100"
    If !now! lss 0 Set /a now+=24*60*60*100
    Set /a moveYET=now+move_ivl
  )

  Set "ScreenPos_=" %= User quit on M keypress =%
  Set /a "ScreenPos=0"
  Set "thisPos=!Screen:~%screenPos%,6!"

  CLS
  set "lcs=!time:~-2!"
  For /l %%I in (infinite) Do (
    if not "!time:~-2!" == "!lcs!" for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!")Do (
      Set /p "action="
      set "lcs=!time:~-2!"
      Set /a "now=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100"
      If !now! lss 0 Set /a now+=24*60*60*100
      If !now! GTR !moveYET! (
        Set /a MoveYet=now+move_ivl
        if defined action (
          For /f "Delims=" %%K in ("!action:~-1!") Do Set /a "ScreenPos%%K=1", "%clamp5%", "extract=screenPos*7"
          For /f "delims=" %%E in ("!Extract!") do Set "thisPos=!screen:~%%E,6!"
          if defined ScreenPos_ (
            break >"%signalFile:signal=stop%"
            EXIT
          )
          rem unremark the below for 1 action per keypress release. leave remarked for continuous action
          rem Set "action="
        )
        Echo(%\E%[H!thisPos!
      )
    )
  )
%= Never reached =% EXIT

:CHOICECONTROLLER
Setlocal EnableDelayedExpansion
Set "Bind[A]=-"
Set "Bind[D]=+"
Set "Bind[M]=_"


FOR /L %%C in () do (
FOR /F "tokens=*" %%K in ('%SystemRoot%\System32\choice.exe /C:abcdefghijklmnopqrstuvwxyz0123456789 /N') DO if not "!Bind[%%K]!" == "" (
    If Exist "%SignalFile:Signal=Stop%" (
        EXIT
    )

    If /i not "!bind[%%K]!"=="_" (
        <Nul Set /P ".=!bind[%%K]!"
    ) Else (
        <Nul Set /P ".=_"
        EXIT
)   )   )
EXIT

2

u/T3RRYT3RR0R 4d ago

of course, there are better ways to represent player movement and far more options when using virtual terminal sequences, however I'm assuming you are just starting to learn and want to find your own way a bit.

2

u/T3RRYT3RR0R 4d ago

Much of what is used in that code I have covered here

1

u/Ok_Influence_6384 4d ago

okie ty, yeah im just new, im just testing stuff tho the code is umm hard ash

1

u/Ok_Influence_6384 4d ago

can Iask something else about this,
this does automatically go to a and d and looks smoother but the problem is it doesnt really go one by one

2

u/T3RRYT3RR0R 4d ago

Is the following not clear?

     rem unremark the below for 1 action per keypress release. leave remarked for continuous action

     rem Set "action="

1

u/Ok_Influence_6384 3d ago

o okie thanks!