-3

I expect to be able to buy items in the shop and have it do the correct subtraction. In the code below, you start out with 10 gold pieces, (gp), but whenever option 2 or 4, to spend 5gp or 1gp, is entered, it takes away all 10gp. I know that it's because it doesn't go past the first if %input%== 1 but I don't know how to fix it, I have tried almost everything, including if/else statements, but I may not have been doing them properly.

:shop
cls
echo You see a middle aged man behind the counter
echo of the shop as well as a younger man sweeping the floors.
echo "Hello young travelers. Welcome, is there anything
echo I can help you find?"
:purchase
echo --------------------------------------------------------
echo %name%
echo Gold: %gp%
echo --------------------------------------------------------
echo.
echo 1) Battleaxe   10gp  Stats: 1d8(S) Versatile(1d10)
echo 2) Mace         5gp  Stats: 1d6(B)
echo 3) L.Crossbow  20gp  Stats: 1d8(P) Range 80/320
echo 4) 5 Bolts      1gp  Equip with Crossbow
echo 5) Go Back
echo.
set /p input=Enter:

if %input%== 5 goto main
if %input%== 1
if %gp% LSS 10 goto nofunds
set /a gp= %gp% - 10
goto shopcont
if %input%== 2
if %gp% LSS 5 goto nofunds
set /a gp= %gp% - 5
goto shopcont
if %input%== 3
if %gp% LSS 20 goto nofunds
set /a gp= %gp% - 20
goto shopcont
if %input%== 4
if %gp% LSS 1 goto nofunds
set /a gp= %gp% - 1
goto shopcont
goto shop

:nofunds
cls
echo You don't have enough gold to purchase that item.
pause >nul
goto shop

:shopcont
cls
echo Would you like to purchase anything else?
goto purchase

I am still new at this so examples and explanations would be wonderful!

Please do not tell me to use choice.exe instead of Set /P, unless it will fix the actual issue.

Compo
  • 36,585
  • 5
  • 27
  • 39
B1u3Soul
  • 11
  • 1
  • I found this SO thread that outlines a *rough* implementation at a switch/case statement. I'm not entirely sure what the issue is either, but I suspect it's how batch is handling the nested if logic:https://stackoverflow.com/questions/18423443/switch-statement-equivalent-in-windows-batch-file – sacredfaith Jul 23 '19 at 06:40
  • I have removed all of the unnecessary indentation from your code, because those are used to highlight open parenthesised code blocks and you've not used parentheses. If the young travellers have only `10`gp, why offer a `20`gp item they cannot purchase? _unless they first buy a battle axe, and threaten the counter clerk and cleaner!_ – Compo Jul 23 '19 at 08:05

2 Answers2

0

In the below example, I have used Set /P under :purchase to satisfy your ill advised stipulation to not use choice.exe, (which I used under :shopcont instead).

:shop
ClS
Echo You see a middle aged man behind the shop counter, as well as a 
Echo younger man sweeping the floor.
Echo(
Echo "Welcome young travellers, is there anything I can help you with?"
:purchase
Set "input="
Set "invalid=true"
Echo(
Echo ------------------------------------------------------------------
Echo(%name%
Echo Gold: %gp%
Echo ------------------------------------------------------------------
Echo(
Echo 1. Battleaxe   10gp  [Stats: 1d8(S) Versatile(1d10)]
Echo 2. Mace         5gp  [Stats: 1d6(B)]
Echo 3. L.Crossbow  20gp  [Stats: 1d8(P) Range 80/320]
Echo 4. 5 Bolts      1gp  [Equip with Crossbow]
Echo 5. Go Back
Echo(
Set /P "input=Enter: "
For /L %%A In (1,1,5) Do If "%%~A" == "%input:"=%" Set "invalid="
If Defined invalid ClS & GoTo purchase
If %input% Equ 5 GoTo main
If %input% Equ 4 If %gp% GEq 1 Set /A gp -=1 & GoTo shopcont
If %input% Equ 3 If %gp% GEq 20 Set /A gp -=20 & GoTo shopcont
If %input% Equ 2 If %gp% GEq 5 Set /A gp -=5 & GoTo shopcont
If %input% Equ 1 If %gp% GEq 10 Set /A gp -=10 & GoTo shopcont
Echo You do not have enough gold to purchase that item.
:shopcont
"%__AppDir__%choice.exe" /M "Would you like to purchase anything else"
If "%ErrorLevel%"=="1" ClS & GoTo purchase

Please note that I have tried to replicate that which you posted in your question, this assumes that %gp% and %name% are already defined prior to this code section and that the label :main exists elsewhere in your unposted code.

You asked for examples and explanations, but those are readily available under each command's usage information and via web searches, so I will not be pointlessly including such things.

Compo
  • 36,585
  • 5
  • 27
  • 39
-1

The usage of command set /P is not recommended for a simple choice menu. A simple typing mistake by user of batch file can easily result in a syntax error on further processing of the batch file detected by Windows command processor resulting in an unexpected exit of batch file execution. A user playing this batch file game by double clicking on it will not be happy on typing for example by mistake " instead of 2 and suddenly the console window is closed because cmd.exe exited batch file processing because of a serious syntax error caused by " and not good coded batch file.

See also:

However, the main problem is the used syntax on all IF commands. The syntax of command IF can be seen by opening a command prompt, running if /? and reading the output help. if %input%== 1 without a command or a command block starting with ( and ending with matching ) to execute on condition is true on same line results in a syntax error on batch file execution. This can be seen on debugging the batch file.

The indentations have no meaning for cmd.exe regarding to process flow. Windows command processor is not Python. Windows command processor executes one command line respectively command block after the other independent on how many leading spaces or tabs are used to indent the command lines.

See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

An arithmetic expression is the string after set /A evaluated by cmd.exe on execution of the batch file. The help output on running set /? explains that within an arithmetic expression it is possible to reference the value of an environment variable by writing just its name without % or ! around variable name. That has two advantages:

  1. If the environment variable does not exist at all, Windows command processor uses value 0 for not existing environment variable. Using %NotExistingVariable% in an arithmetic expression results in a syntax error because of this string is replaced by nothing which usually results in a missing operand error on evaluation of the arithmetic expression.
  2. Environment variables can be modified with arithmetic expressions multiple times in a command block without usage of delayed expansion.

For that reason set /a gp= %gp% - 10 is not a recommended syntax to decrement the environment variable gp by 10. Better is using set /A gp=gp - 10 and best set /A gp-=10.

The DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ explains that echo. can fail to print an empty line into console window and that echo( is better for this task.

A minimal, complete, and verifiable example for this task is following batch file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "gp=50"
set "name=B1u3Soul"

:Shop
cls
echo You see a middle aged man behind the counter
echo of the shop as well as a younger man sweeping the floors.
echo "Hello young travelers. Welcome, is there anything
echo I can help you find?"
:Purchase
echo --------------------------------------------------------
echo %name%
echo Gold: %gp%
echo --------------------------------------------------------
echo(
echo 1) Battleaxe   10gp  Stats: 1d8(S) Versatile(1d10)
echo 2) Mace         5gp  Stats: 1d6(B)
echo 3) L.Crossbow  20gp  Stats: 1d8(P) Range 80/320
echo 4) 5 Bolts      1gp  Equip with Crossbow
echo 5) Go Back
echo(
%SystemRoot%\System32\choice.exe /C 12345 /N /M "Enter: "

if errorlevel 5 goto Main
if errorlevel 4 set "GoldAmount=1"  & goto GoldInPurse
if errorlevel 3 set "GoldAmount=20" & goto GoldInPurse
if errorlevel 2 set "GoldAmount=5"  & goto GoldInPurse
set "GoldAmount=10"

:GoldInPurse
if %gp% LSS %GoldAmount% goto NoFunds
set /A gp-=GoldAmount
echo(
%SystemRoot%\System32\choice.exe /C YN /N /M "Would you like to purchase anything else [Y/N]? "
cls
if errorlevel 2 goto Main
goto Purchase

:NoFunds
echo(
echo You don't have enough gold to purchase that item.
pause >nul
goto Shop

:Main
endlocal

See also single line with multiple commands using Windows batch file for an explanation of operator & as used in this batch file.

It would be of course possible to use just choice instead of %SystemRoot%\System32\choice.exe. But the usage of full qualified file name (drive + path + file name + file extension) makes the batch file independent on environment defined outside the batch file. For this batch file it does not matter how PATH and PATHEXT is defined on starting the batch file. It depends only on environment variable SystemRoot defined by Windows and which is not modified by applications or users in general.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • choice /?
  • cls /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?

See also:

Mofi
  • 46,139
  • 17
  • 80
  • 143