0

I'm trying to make a batch script to hold scores in archery. When I run it and enter the scores 1, 2, and 3 for the 1st, 2nd, and 3rd arrow my expected output is:

Scores:
1st arrow: 1
2nd arrow: 2
3rd arrow: 3
-
Total score: 6
Maximum possible score: 15
Accuracy: 40%

Instead, I get the output:

Scores:
1st arrow:
2nd arrow:
3rd arrow:
-
Total score: 6
Maximum possible score: 15
Accuracy:

The code:

@echo off
color 0f
title Archery Score Logger

:askForConfig
set configFile=defaultConfig.cfg
cls
echo What config file would you like to use?
echo Leave blank for default config.
set /p configFile=Input: 
if exist %configFile% (
    goto loadConfig
) else (
    echo Error!
    echo The specified file does not exist.
    pause
    goto askForConfig
)

:loadConfig
(
    set /p colour=
    set /p numOfArrows=
    set /p maxScorePerArrow=
)<%configFile%
color %colour%

:mainMenu
cls
echo Main Menu
echo -
echo 1 to input scores
echo 2 to exit
echo -
set /p menuChoice=Input: 
if %menuChoice% == 1 (
    set arrowInputCount=1
    set totalScore=0
    set numOfXs=0
    cls
    goto inputScores
) else if %menuChoice% == 2 (
    exit
)

:inputScores
cls
if %arrowInputCount% gtr %numOfArrows% (
    echo Done!
    pause
    goto output
)
set suffix=th
if %arrowInputCount% equ 1 (
    set suffix=st
) else if %arrowInputCount% equ 2 (
    set suffix=nd
) else if %arrowInputCount% equ 3 (
    set suffix=rd
)
echo Input the score for the %arrowInputCount%%suffix% arrow ^(%numOfArrows% total arrows^).
echo Range: ^(1-%maxScorePerArrow%^), 'm' for miss, 'x' for an x.
set /p arrow[arrowInputCount]=Input: 
if %arrow[arrowInputCount]% geq 1 (
    if %arrow[arrowInputCount]% leq %maxScorePerArrow% (
        set /a totalScore+=%arrow[arrowInputCount]%
        set /a arrowInputCount+=1
        goto inputScores
    )
) else if %arrow[arrowInputCount]% == m (
    set /a arrowInputCount+=1
    goto inputScores
) else if %arrow[arrowInputCount]% == x (
    set /a totalScore+=%maxScorePerArrow%
    set /a arrowInputCount+=1
    goto inputScores
)
echo Error!
echo The value you entered was invalid.
pause
goto inputScores

:output
set /a maxPossibleScore=%numOfArrows%*%maxScorePerArrow%
set /a accuracy=%totalScore%/(%maxPossibleScore%/100)
set outputCount=1
cls
echo Scores:
:outputLoop
set suffix=th
if %outputCount% equ 1 (
    set suffix=st
) else if %outputCount% equ 2 (
    set suffix=nd
) else if %outputCount% equ 3 (
    set suffix=rd
)
if %outputCount% leq %numOfArrows% (
    echo %outputCount%%suffix% arrow: %arrow[outputCount]%
    set /a outputCount+=1
    goto outputLoop
)
echo -
echo Total score: %totalScore%
echo Maximum possible score: %maxPossibleScore%
echo Accuracy: %accuracy%^%
echo -
pause
exit

I think the problem is with the array but after reading up on them I still can't see a problem with my code. I saw a few similar problems where they fixed it by adding a line that says:

setlocal EnableDelayedExpansion

but I tried adding it at the start of the program after @echo off and it changed nothing. The values that the program imports for config are in a file called 'defaultConfig.cfg' which reads:

0f
3
5
Finn Perry
  • 67
  • 1
  • 7
  • All array management details are fully explained at [Arrays, linked lists and other data structures in cmd.exe (batch) script](https://stackoverflow.com/questions/10166386/arrays-linked-lists-and-other-data-structures-in-cmd-exe-batch-script/10167990#10167990) – Aacini Aug 26 '17 at 15:36

1 Answers1

0

Please read again on delayedexpansion

To get the content of an array var via a calulated index you need delayed expansion.

When you use.

if %arrow[arrowInputCount]% geq 1

This is just a simple var which happens to have some brackets in the name.
Provided you have already issued a Setlocal EnableDelayedExpansion

if !arrow[%arrowInpuCount%]! geq 1

would work.

But inside a code block you'd need another level of delayed expansion. For echo and set commands you can use a pseudo call, but this doesn't work with an if.
Workaround:

(
  call Set temp=%%arrow[!arrowInpuCount!]%%
  If !temp! geq 1 .....
)

So you first have to get a temporary variable to compare with the if.