I'm fairly new to coding, and I've been told to start with batch files. I'm attempting to make a text based game that prompts the user to choose between a few options to progress through the story. I've got the basic idea down, but I ran into some trouble with making a menu. I've done some research on here, and have searched other sites, but can't seem to make heads or tails of some of the answers to similar questions. Most of the answers write out code that I assume would work, but I need to know the WHY behind these answers, and I haven't really found any answers that I could understand.
TLDR; I need to make a menu for a text based game, that allows the user to return the label they left off on.
What I have so far:
:MainMenu
cls
echo Input Options:
echo.
echo ::1) View Storyline Changes
echo ::2) Restart Test
echo ::3) Resume Test
echo ::4) Help
echo ::5) Quit
echo.
set /p input=Input:
if "%input%" == "1" goto StorylineChanges
if "%input%" == "2" goto Rst
if "%input%" == "3" goto ResumeTest
if "%input%" == "4" goto HelpScrn
if "%input%" == "5" exit
:StorylineChanges
cls
echo Unimportant to test.
echo.
echo Input "m" to go back
echo.
set /p input=Input:
if "%input%" == "m" goto Main Menu
if "%input%" == " " goto WrongInputStorylineChanges
:Rst
cls
goto :StartTest
echo off
:ResumeTest
cls
REM ***THIS IS WHERE I NEED HELP ***
pause >nul
goto StartTest
As you can probably immediately tell, I BARELY have a grasp on basic commands, so please keep that in mind if you provide an answer. I'd really appreciate any help you guys could give me. Thanks so much.
I cannot unravel the spaghetti code, but I can give an example
detailing how to go back to the menu as the title asks.
#echo off
:MainMenu
cls
echo Input Options:
echo.
echo ::1) View Storyline Changes
echo ::2) Restart Test
echo ::3) Resume Test
echo ::4) Help
echo ::5) Quit
echo.
set /p input=Input:
if "%input%" == "1" call :StorylineChanges
if "%input%" == "2" call :Rst
if "%input%" == "3" call :ResumeTest
if "%input%" == "4" call :HelpScrn
if "%input%" == "5" exit /b 0
goto :MainMenu
:StorylineChanges
echo Use "goto :eof" to exit script or exit called label.
pause
goto :eof
:Rst
echo Use "exit /b" to exit script or exit called label with a errorlevel.
pause
exit /b 0
:ResumeTest
>&2 echo Exit called label with errorlevel 1. This line is to stderr.
pause
exit /b 1
:HelpScrn
echo Help. Exit with implicit 0.
pause
exit /b
The above uses call to access each label. Exit of a called label
returns back to the point of the call. The menu is in a loop so it keeps
showing until you input 5 to exit the script.
I added pauses into the labels so you could see the messages before clr
is called.
Related
code:
echo To Start, type start
echo To view Options, type options
echo To Quit Game, type quit
set /p input= Command?
if %input% == start goto Start
if %input% == options goto Options
if %input% == quit goto Exit
else (
goto Menu
)
Basically what it should do is typing one of those choices will go to that part of the code, and typing something that isn't specified will run that script again. This works as intended, but my problem is when I type "not blah" (without quotes, where blah could be anything) it runs the script despite there not being specified action for blah in the code.
Why?
Besides the fact that you did not double quote your variables when comparing, you cannot use else like that. Else has to be on the same line as the closing parenthesis of the previous if statement and the opening parenthesis of the else code block. i.e: ) else (
Anyway to eliminate the need to accommodate for user errors in typing commands just use choice:
#echo off
:menu
choice /c SOQ /M "[S]tart, [O]ptions, [Q]uit"
goto opt%errorlevel%
:opt1
Echo this is the start section
goto :eof
:opt2
echo this is the Options section
goto :eof
:opt3
echo This is the Quit section
exit
:opt0
Goto menu
#echo off
setlocal EnableDelayedExpansion
color b
goto play
:play
cls
set name2= OoggieBoogie
echo Hello, My name is !name2!^^! I'm an AI. I'm here to help with your lazy
Butt :D^^!
timeout /t 3 >null
echo!name2!: May I Have Your Have Your Name Please? :)
color c
echo (Pssst^^! Want to cut the Bullshit and go straight in? Select "Express" please!)
timeout /t 2 >null
echo A. My name is
echo B. Express
set /p input=
if !input! equ B goto Writing2
cls
echo!name2!: Hello !name!, Shall we continue now?
echo 1.Yes :D
echo 2.No -_-" ..
set /p input=!name!:
if !input! equ 1 goto Writing
if !input! equ Yes goto Writing
if !input! equ 2 exit
if !input! equ No exit
:Writing2
echo Okay.. Whatever you want Damn.. I was trying to be nice ^^!
echo Anyway. Inatiating EXPRESS Route----->
goto Writing
Hello!
What I am trying to do here is skipping all the steps and go straight to "Writting2" if typed Express.
I am almost done with this fun program but I can't figure out a good way skip all the steps.
When I type "Express or select 'B'
it crashes.
but If I write a name the program works as usual!
Thanks in Advance!
Sorry in Advance if I did something wrong in the community.
This is a way you can do what you want:
#echo off
color b
goto play
:play
cls
set name2= OoggieBoogie
echo Hello, My name is %name2% I'm an AI. I'm here to help with your lazy
::echo Butt :D^^!
timeout /t 3 >nul
echo %name2%: May I Have Your Have Your Name Please? :)
color c
echo (Pssst^^! Want to cut the Bullshit and go straight in? Select "Express" please!)
timeout /t 2 >nul
echo A. My name is
echo B. Express
choice /c:AB>NUL
if errorlevel 2 goto Writing2
set /p "name=Enter your name: "
:Writing
cls
echo %name2%: Hello %name%, Shall we continue now?
echo 1.Yes :D
echo 2.No -_-" ..
choice /c:1Y2N>NUL
if errorlevel 4 goto exit
if errorlevel 3 goto exit
if errorlevel 2 goto Writing
if errorlevel 1 goto Writing
:Writing2
echo Okay.. Whatever you want Damn.. I was trying to be nice ^^!
echo Anyway. Inatiating EXPRESS Route-----^>
goto Writing
:exit
exit /b
Remember: Variables can be accessed by %variable_name% and you can set them by set "variable_name=variable_value" as #Compo mentioned above.
It is better to use choice /c option in your future batchfiles. A disadvantage of this option is that you cannot enter a string with more than 1 character, but it does it's own errorhandling, so you don't have to deal with invalid responses. Also, when you write
echo Anyway. Initiating EXPRESS Route----->
> symbol causes problems as it is a redirection character and should be escaped:
echo Anyway. Initiating EXPRESS Route-----^>
Not quite sure what I'm doing wrong. For the most part, this works. If I were to type just 1, I would go to opt1.
The problem is, if I type "11", "1111", or even "1234567" it always goes to opt1. The only time it seems to not select opt1 is when the first number is something other than 1.
Likewise, entering 21 chooses option 2. The only way I've been able to get this to work as intended, which is only entering 1, 2, or 3 selects the respective options, is to omit the IF NOT statement.
Could someone kindly point me in the right direction?
#ECHO OFF
CLS
:MAIN_MENU
ECHO Welcome Menu
ECHO.
ECHO 1 - Option 1
ECHO 2 - Option 2
ECHO 3 - Option 3
ECHO.
SET ans=
SET /P ans="Select your option and then press ENTER: "
IF NOT "%ans%" == "" SET ans=%ans:~0,1%
IF "%ans%" == "1" GOTO opt1
IF "%ans%" == "2" GOTO opt2
IF "%ans%" == "3" GOTO opt3
ECHO "%ans%" is not a valid option, please try again!
ECHO.
PAUSE
CLS
GOTO MAIN_MENU
:opt1
ECHO This is option 1
PAUSE
CLS
GOTO MAIN_MENU
:opt2
ECHO This is option 2
PAUSE
CLS
GOTO MAIN_MENU
:opt3
ECHO This is option 3
PAUSE
CLS
GOTO MAIN_MENU
With the code you snipped I can't replicate the bug, however, I do remember to face that very same problem long time ago.
The answer is the quotes; just add it and you will avoid more complex code:
:input
cls
set ans=:
set /p ans=
if "%ans%" equ "1" (
goto opt1
) else (
goto input
)
:opt1
echo success!
EDIT: Regarding the first ans that was set, it is to clean the shell memory. Sometimes a variable could be stored in Windows memory, and even if you do not input anything to the set /p variable, and only press return, the batch will check for the variable and it will already have a value previously set in the memory. Example:
set /p option=
The user input "1". As a result, Windows will store option=1, or, %option% resulting in 1.
So, the even if you do not input anything, the next code will move forward as the answer is previously stored in the memory:
set /p option=
The user does NOT input anything, only press return. The code will move on:
if "%option%" equ "1" do (
echo %option% is equal to 1 because it was previously stored.
)
EDIT: Here is the code, with comments and explanations:
#echo off
:main_menu
cls
echo Welcome menu
echo.
echo 1 - option 1
echo 2 - option 2
echo 3 - option 3
echo.
rem Blank "ans" will clean the memory for a previous set value.
set ans=
rem You can either quote the whole variable with its option, ot not quote it at all.
rem However, its always better to quote it, as follows.
set /p "ans=select your option and then press enter:"
if "%ans%" == "1" goto opt1
if "%ans%" == "2" goto opt2
if "%ans%" == "3" goto opt3
rem The following line will force a loop to main menu if only return is pressed; blank options will not display message.
if "%ans%" == "" goto main_menu
rem In case that another option rather than 1, 2 or 3 are pressed, the loop will warn you, and then return to main menu.
echo "%ans%" is not a valid option, press any key to try again!
pause > nul
goto main_menu
:opt1
cls
echo this is option 1
pause
goto main_menu
:opt2
cls
echo this is option 2
pause
goto main_menu
:opt3
cls
echo this is option 3
pause
goto main_menu
Regarding the %ans:~0,1%, it is to limit the string to a certain position.
So, for example, %any_variable:~0,5% is saying "Start the string since character 0, and go ahead until character 5". You can try that out in the following example. Notice that all echo lines will type out the very same text:
#echo off
set example=Batch files are kinda cool
echo %example%
echo %example:~0,11% are kinda cool
echo Batch files %example:~12%
pause
As it turns out, there were remnants in the code that needed to be removed.
IF NOT "%ans%" == "" SET ans=%ans:~0,1%
IF "%ans%" == "1" GOTO opt1
I'm not entirely sure what that first line was setting however, removing it resolved the issue.
Thanks for all the help, much appreciated!
I have this query to check the status of a service and give options based on that status but I am having some issues in the error portion. IT only seems to work of there is not an option chosen. Even then it only works the first time. AS you can see I have 3 options but if i select option 4 it defaults to option 1. PLease take a look and explain what I am missing.
#echo off
ECHO Status of MGT System Manager Service
Goto Welcome
ECHO.
:Welcome
sc query MGTSM | findstr /i "STATE"
ECHO What would you like to do?
ECHO 1. Start Service
ECHO 2. Stop Service
ECHO 3. Exit
set /p choice=Select your choice.
if '%choice%'=='' ECHO "%choice%" is not valid please try again.
if '%choice%'=='1' goto Start Service
if '%choice%'=='2' goto Stop Service
if '%choice%'=='3' goto Exit
ECHO.
:Start Service
net start MGTSM
goto Welcome
:Stop Service
net stop MGTSM
goto Welcome
:Exit
exit
set /p does not touch the variable, if you enter nothing (just ENTER). Therefore you should delete the variable before:
:Welcome
....
set "choice=" //this deletes %choice%
set /p "choice=Select your choice: "
if '%choice%'=='1' goto StartService
if '%choice%'=='2' goto StopService
if '%choice%'=='3' goto Exit
REM this line is only reached, when all of the "IF ... GOTO" above failed
echo not valid input: "%choice%"
goto welcome
...
Labels and goto have a problem with spaces: goto start service will go to "start", ignoring "service". Same with Labels: :Start Service, the Label is :Start, the "Service" is ignored.
I noticed a post on how to make a batch that opens another batch upon an input. However, I need a way that will make the code pause until the correct input is entered, then continue.
So for example, the code would ask what is the access code?
Then the user would input the correct code, for example 123.
Then the code would say "Welcome!"
Then it would execute another question like "What do you want to do today?"
There would be a list of options:
A. Game
B. Browse
C. Nevermind
The user would in put a, b, or c and the script would start either a game or web browser. If the user selected C, then it would exit.
Thanks for the help!
#echo off
echo Welcome!
echo What do you want to do today?
echo.
echo A. Game
echo.
echo B. Browse
echo.
echo C. Nevermind
echo.
choice /C:ABC /N /M "Enter your choice: "
if "%errorlevel%"=="1" goto :game
if "%errorlevel%"=="2" goto :browse
if "%errorlevel%"=="3" goto :nevermind
goto :error
I think a little bit modified version of code should work just fine.
#Echo off
:Start
cls
echo Welcome !
echo To Greet press one.
echo For Goodbye press two.
echo To Abort press 3
ECHO.
ECHO.
SET /p Option=Choice:
if "%Option%"=="1" GOTO Sub_MenuA
if "%Option%"=="2" GOTO Sub_MenuB
if "%Option%"=="3" GOTO Sub_MenuC
if "%Option%"=="quit" GOTO EOF
Goto Start
:Sub_MenuA
echo Hi There!
pause
Goto Start
:Sub_MenuB
echo tatas !
pause
Goto Start
:Sub_MenuC
echo Aborted
Pause
Goto Start
:EOF