Batch RPG Game with Login Function - authentication

I'm creating a D&D style RPG game using batch files and I saw another person using a login feature that creates a batch file that returns you to where you left off. so I tried to replicate it. Almost everything works except for the fact that it won't create the batch file to allow you to go back. When you go through the process of creating a login it goes through it like normal and on the next screen under start even displays that your username is what you set it as but it won't create the batch file. Some of the code might be scattered because I'm still learning and some of it unfinished but this is what I have so far.
title Lost Mine of Phandelvor
#echo off
:entergame
cls
echo.
echo Welcome to Lost Mine of Phandelvor
echo -------------------
echo.
echo 1. Create Account
echo 2. Login
echo 3. Exit
echo.
set /p input=
if %input% EQU 1 goto createuser
if %input% EQU 2 goto login
if %input% EQU 3 exit
if %input% GEQ 4 goto entergame
:createuser
cls
echo.
echo What would you like your Username to be?
set /p username1=
set v1f=0
goto checkforspaces
:checkforspaces
set x=!v1f!
set Letter%v1f%=!username1:~%x%,1!
if "!Letter%v1f%!" EQU " " (
echo.
echo.
echo Sorry you can't use spaces in your Username.
pause>nul
goto entergame
)
if NOT "!Letter%v1f%!" EQU "" (
set /a v1f=%v1f%+1
)
echo.
echo What would you like your Password to be?
set /p password1=
goto DATA_VALUES
:login
cls
set /p name=Username:
if not exist "%name%.bat" (
echo That is not a valid Username.
pause>nul
goto entergame
)
set /p pass1=Password:
call %name1%.bat
if not %password1% EQU %pass1% (
echo That is not a valid Password.
pause>nul
goto entergame
)
goto create
:DATA_FILES
set lvl1=1
set exp1=0
set expmax1=300
set gp1=10
set hp1=12
set ac1=15
set profbonus1=2
set str1=4
set dex1=1
set con1=2
set int1=0
set wis1=2
set cha1=2
set destination=SAVE_GAME_FILES
set destination2=SAVE_GAME_FILES
goto SAVE_GAME_FILES
:SAVE_GAME_FILES
(
echo set username1=%username1%
echo set password1=%password1%
:DATA_VALUES
echo set lvl1=%lvl1%
echo set exp1=%exp1%
echo set expmax1=%expmax1%
echo set gp1=%gp1%
echo set hp1=%hp1%
echo set ac1=%ac1%
echo set profbonus1=%profbonus1%
echo set str1=%str1%
echo set dex1=%dex1%
echo set con1=%con1%
echo set int1=%int1%
echo set wis1=%wis1%
echo set cha1=%cha1%
echo set destination=%destination%
echo set destination2=%destination2%
)>%username1%.bat
goto start
:start
cls
echo.
echo Currently logged in as %username1%
echo.
echo Welcome to my fantasy style role playing game.
echo You will need to create a character.
echo.
echo Enjoy!
echo.
echo 1. Continue to Character Selection
echo 2. Exit
echo.
set /p input=
if %input% EQU 1 goto create
if %input% EQU 2 exit
if %input% GEQ 3 goto start
:create
cls
echo.
echo Welcome to Character Creation
echo.
echo Pick your race!
echo.
echo 1. Human
echo 2. Dwarf
echo 3. Elf
echo 4. Dragonborn
echo 5. Tiefling
echo.
set /p input=Choice:
if %input%==1 goto createHuman
if %input%==2 goto createDwarf
if %input%==3 goto createElf
if %input%==4 goto createDragonborn
if %input%==5 goto createTiefling
goto create
:createHuman
cls
echo.
echo You have chosen Human as your race!
echo.
echo Choose your class
echo.
echo 1. Fighter
echo 2. Ranger
echo 3. Rogue
echo 4. Wizard
echo.
set /p input=Choise
if %input%==1 goto humanFighter
if %input%==2 goto humanRanger
if %input%==3 goto humanRogue
if %input%==4 goto humanWizard
goto createHuman
:humanFighter
cls
echo.
echo You have chosen Fighter as your class!
echo.
echo Choose your weapon
echo.
echo 1. Battleaxe 1D8 Slashing
echo 2. Longsword 1D8 Slashing
echo 3. Rapier 1D8 Piercing
echo.
set /p input=choise
if %input%==1 goto humanFighter1
if %input%==2 goto humanFighter2
if %input%==3 goto humanFighter3
goto humanFighter
:humanfighter1
set lvl1=1
set exp1=0
set expmax1=300
set gp1=10
set hp1=12
set ac1=15
set profbonus1=2
set str1=4
set dex1=1
set con1=2
set int1=0
set wis1=2
set cha1=2
cls
echo.
echo To find your stats open your character sheet labeled humanfighter1_cs.txt
echo.
echo What's your name?
echo.
set /p name1=Enter:
goto hf1main
:hf1main
cls
echo.
echo %name1% Human Fighter
echo Lvl: %lvl1% Money:%gp1%
echo Hit Points: %hp1%/12
echo Armor: Breastplate Armor Class: %ac1%
echo Exp: %exp1%/%expmax1%
echo Weapon: Battleaxe 1D8 Slashing
echo Stat Modifiers:
echo Strength: +%str1%
echo Dexterity: +%dex1%
echo Constitution: +%con1%
echo Intelligence: +%int1%
echo Wisdom: +%wis1%
echo Charisma: +%cha1%
echo -------------------------------------
echo 1) Continue
echo 2) Exit
echo.
set /p input=Enter:
if %input%==1 goto hf1continue
if %input%==2 exit
I expect it to create the batch file after creating an account so that you can log in later.

For your menus, I would like to introduce you to choice.exe as an alternative to Set /P. It is far better to use it when input must be any one of a small set of known values. Set /P allows the end user to enter nothing or anything, and in order to maintain control you need to build in some input verification mechanism. To find out how choice.exe works, open a cmd.exe window and enter choice /? at the prompt.
Here is a rewritten example snippet of your script, (lines 1-43) to hopefully explain why:
#Echo Off
Title Lost Mine of Phandelvor
:EnterGame
ClS
Echo(
Echo Welcome to Lost Mine of Phandelvor
Echo ----------------------------------
Echo(
Echo 1. Create Account
Echo 2. Login
Echo 3. Exit
Echo(
Choice /C 123
If ErrorLevel 3 Exit /B
If ErrorLevel 2 GoTo Login
:CreateUser
ClS
Echo(
Set "username1="
Set /P "username1=What would you like your Username to be? "
If Not Defined username1 GoTo CreateUser
:CheckForSpaces
If Not "%username1: =%"=="%username1%" (
Echo Sorry you can not use spaces in your Username.
Choice /M "Is %username1: =%" okay"
If ErrorLevel 2 GoTo CreateUser
)
If Exist "%username1%.bat" GoTo :Login
Echo(
Set "password1="
Set /P "password1=What would you like your Password to be? "
However, before you continue with your script, based upon what I said about using Set /P. The end user can currently enter anything they want as username1. We've already checked for no entry and for spaces, but you're also saving the name as a filename too, %name%.bat. Along with the decimal character codes 0 through 31, Windows filenames cannot contain any of the following characters, \/:*?"<>|, so you'd need to incorporate further verification of username1. This verification procedure would need to be implemented before line 31 of the code above.
Before you do so however, you may want to consider changing your methodology and not saving the Username to the name of a file. The reason for this is that you'd also be wise not to use filenames ending with a ., or any named CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9 either. So you would further need to include those verification checks of the input too.
Don't forget, you'll probably want to include a verification method for input entries to the %password1% prompt too!
Given the complexity involved with user input and Set /P you can see why I have recommended choice.exe as a control measure for your menus.

Ooh - so many errors!
First, add an extra line setlocal enabledelayedexpansion directly after the #echo off line. This has two effects - first, when your batch ends, your environment is restored to its original condition so that you don't get confused with variables that have been established by prior runs. second, it turns on delayed expansion mode - which is where the !variable! syntax you are using is activated, otherwise ! is simply an ordinary character.
Next, having accepted input from the ketboard with a set /p, you have no idea whether the user entered. In your validation if statements, use if "%var%"=="value" which overcomes most input problems.
Next, the syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned.
And a little tip for games that need a save/restore feature:
If you reserve a character as a prefix for variables-you-want-to-save (eg all variables I want to save/reload start with #) then all you need to save a game is
set #>"mygamefile.txt"
and all you need to reload a game is
for /f "usebackqdelims=" %%a in ("mygamefile.txt") do set "%%a"
To zap all # variables (useful before reloading a game) use
for /f "delims==" %%a in ('set # 2^>nul') do set "%%a="
You should look at the thousands of code examples here on SO to find out how to use subroutines - you appear to be using "spaghetti code".
This code may help with your password-checking:
for /f "tokens=1,2" %%a in (passwordfilename) do if "%%a"=="%playername%" set "playerpass=%%b"
if "%playerpass%"=="%enteredpass%" goto gameon
This uses a single password file of the form
player1 password1
player2 password2
If player1 changes password, then append the new data to the file like this:
player1 password1
player2 password2
player1 newpassword
and the above for /f construct will then set playerpass to the last occurrence of player1 found.
This should provide you with a start and obviate your need for a subsidiary batch file. You'll have enough on your plate implementing these suggestions, but you should be able then to see the wood for the trees.
And implement changes one at a time, then test and debug them. Small steps will make the process a lot easier.

I'm using the same thing in my game. You need 2 functions, 1 to load and 1 to save. The save function should look something like this:
:: My save thing
:save
(
echo %var1%
echo %var2%
) > save.sav
and the loading portion should look something like this:
< save.sav (
set /p var1=
set /p var2=
)
also, one major recommendation, put all your scripts into separate files and folders. Like a normal game, example:
- MainGame
- Launcher.bat
- Resources
- Scripts
- Save.bat
- Load.bat
- Fight.bat
- Assets
- Title.txt
this is a similar structure to what I used in my game.

Related

"if" statements in batch: file crashes when the input is supposed to be a number, but instead has words with spaces

So, I have a set /p thing in a batch file. For the user to proceed, they must type "2". I can't seem to find my specific problem anywhere.
#echo off
echo "What is 1+1"
set /p oneplusone=Type Answer Here:
if %oneplusone%==2 goto correct
if %oneplusone% neq 2 goto incorrect
:correct
cls
echo Correct!
pause
goto youranswer
:incorrect
cls
echo Wrong.
pause
goto youranswer
:youranswer
cls
echo You answered: %oneplusone%
Now, if the user types a number/word with no spaces, everything works out, and it shows your answer as wanted.
However, say if you type something like "hi there" with a space, the batch file closes immediately. This only happens when the answer needs to be a number, and you type something that involves a space.
Any help?
Thanks in advance.
You can check if your answer is a number using this:
set /a test=%oneplusone%*1
if %test%==0 goto notValid
and have another label, making your code this
#echo off
echo "What is 1+1"
set /p oneplusone=Type Answer Here:
set /a test=%oneplusone%*1
if %test%==0 goto notValid
if %oneplusone%==2 goto correct
if %oneplusone% neq 2 goto incorrect
:correct
cls
echo Correct!
pause
goto youranswer
:incorrect
cls
echo Wrong.
pause
goto youranswer
:notValid
cls
echo Your input is not valid
pause
goto youranswer
:youranswer
cls
echo You answered: %oneplusone%

Batch - Passing variable from subroutine to subroutine error

Main_Control is the parent batch.
It calls batches named DEFAULT, SETOPTIONS AND USEROPTIONS.
DEFAULT sets a variable %def_set% to either 1 or 2. %def_set% is used in USEROPITONS to set some other variables which are used in SETOPITONS. After DEFAULT, in the MAIN_CONTROL, a test of %def_set% returns error "'1' (or '2') is not recognized as an internal or external command, program or batch" for both %def_set%=1 or 2. It doesn't seem to pass the variable correctly. What have I done wrong?
------------------------CODE-------------------------
"Main_Control" = batch1
#ECHO off
CLS
MODE CON:cols=130 lines=75
REM This particular file is the control script which CALLs the subroutines to perform the back or restore of settings.
:skipintro
REM 1. Get backup location and subroutine location/names.
REM 2. Clear screen
REM 3. Display the notes text file in the window (must be paused).
REM 4. Pause to read notes
REM 4. Get user name
REM 6. "START1" label. Start point if the user wants to rerun backup/restore in same session.
REM 7. Ask if user wants to backup or restore
REM 8. Ask what settings to backup/restore
REM 9. Ask if the user wants to use default settings
REM 10. If user wants to change default settings, provide options to change.
REM 11. Set the options to use throughout the backup/restore.
CALL "%~DP0"_BackupLocation_Subroutines.bat
CLS
TYPE %NOTES%
Timeout /t 30
CALL %GETUSERNAME%
:START1
CALL %B_R_OPTION%
CALL %MENU%
CALL %DEFAULTS%
rem test1
echo before & %def_set% & pause
rem END TEST1
CALL %USEROPTIONS%
REM TEST2
echo after & %def_set% & pause
REM END TEST2
CALL %SETOPTIONS%
Echo You are back in %~n0.
Echo You chose action: %ACTION%
Echo You chose to %ACTION%: %SELECTION%
Timeout /T 5
:: Create (for backups) or verify existence (for restores) the Main Backup and Registry Folders.
SETLOCAL ENABLEDELAYEDEXPANSION
SET FOLDERS= ^
%BACKUP_FOLDER% ^
%REGISTRY_FOLDER%
IF %ACTION%==Backup CALL %CREATE%
IF %ACTION%==Restore CALL %VERIFY%
ETC ETC ETC
%DEF_set% has to pass from DEFAULTS to USEROPTIONS and SETOPTIONS. But it is not.
DEFAULTS batch
#echo off
REM Name: DEFAULTS
REM Asks user to use defaults and have no more prompts or to be prompted for inputs.
:def_input
CLS
ECHO Would you like to use default values?
ECHO Backup location: %Backup_Folder% (cannot modify at this time)
ECHO Overwrite previous backup: No
ECHO Rename previous backup with date/time: Yes
ECHO Prompt to overwrite files: No (no option to change)
ECHO Prompt to delete files: No
ECHO Generate a log: Yes
ECHO Overwrite or append to an existing log: Overwrite
ECHO Log file located in backup location: Yes (no option to change)
ECHO.
ECHO 1. Yes
ECHO 2. No
ECHO.
Set /P Def_SET= Choose:
ECHO.
FOR %%w in (1 2) DO IF #%Def_SET%==#%%w (
ECHO You selected: %Def_SET%
Timeout /T 5
Exit /b
)
REM USER ERROR
REM If the user types something other than 1 or 2, the FOR/DO/IF statement won't run indicating user error.
REM The routine will continue here, letting the user know there is an error.
ECHO Error
ECHO Select 1 or 2 & GOTO :def_input
After this, TEST1 in Main_control batch returns this error "'1' is not recognized as an internal or external command, program or batch".
USEROPTIONS batch
#echo off
REM Name: USEROPTIONS
ECHO %~no & %def_set% & pause
IF %def_set%==1 GOTO :defopts
IF %def_set%==2 GOTO :askopts
:defopts
:: Overwrite previous backup
SET OW_BU=1
:: Generate a log
SET ONLog=1
:: Overwrite the log
SET OWLog=1
:: Prompt to delete files
SET Del_P=1
GOTO :EOF
:askopts
:: Questions to Users
:: Overwrite Backup Question
:: Rename the previous backup if user does not want it overwritten.
:OW_Backup
IF NOT EXIST %BACKUP_FOLDER%\ GOTO :skipOWQ
REM If previous backup does not exist, skip question to overwrite it.
ECHO.
ECHO Do you want to OVERWRITE the previous backup. Choose:
ECHO 1. Do not overwrite old backup,then rename it with its "created" date.
ECHO 2. Overwrite old backup.
ECHO.
SET /P OW_BU= Make a selection...
FOR %%u in (1 2) DO IF #%OW_BU%==#%%u (
ECHO You selected: %OW_BU%
GOTO SkipError1
)
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :OW_Backup
:SkipError1
:skipOWQ
:: Generate Robocopy Log
:GenLog
ECHO.
ECHO Do you want to GENERATE a Robocopy log?
ECHO It will be located in %Backup_Folder%.
ECHO 1. Yes
ECHO 2. No
ECHO.
SET /P ONLog= Make a selection...
FOR %%v in (1 2) DO IF #%ONLog%==#%%v (
ECHO You selected: %ONLog%
GOTO SkipError2
)
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :GenLog
:SkipError2
:: Overwrite or Append Robocopy Log
IF %ONLog%==2 GOTO :Del_Prompt
:OW_RLog
ECHO.
ECHO Do you want to OVERWRITE the Robocopy log?
ECHO.
ECHO 1. Yes - Overwrite
ECHO 2. No - Append to Log
ECHO.
SET /P ONLog= Make a selection...
FOR %%v in (1 2) DO IF #%ONLog%==#%%v (
ECHO You selected: %ONLog%
GOTO SkipError3
)
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :OW_Rlog
:SkipError3
:: Prompt to Delete Decision
:Del_Prompt
ECHO.
ECHO.
ECHO The restoration will delete default files that are not in your backup in order to restore your VDI to the way you had it.
ECHO Do you want confirmations to delete files?
ECHO 1. No confirmations to delete files.
ECHO 2. Review and confirm to delete files.
ECHO.
SET /P Del_P= Make a selection...
ECHO.
FOR %%x in (1 2) DO IF #%Del_P%==#%%x (
ECHO You selected: %Del_P%
GOTO SkipError4
)
REM Error
ECHO.
ECHO.
ECHO *********Error*************
ECHO Select 1 or 2 & GOTO :Del_Prompt
:SkipError4
Exit /b
Back to Main_Control batch, then call SETOPTIONS
SETOPTIONS batch
#echo off
REM Name: SETOPTIONS
ECHO Currenlty running: %~nx0
pause
:: Set Options
ECHO Backup location is: %Backup_Folder%
REM Test
echo OnLog %Onlog%
echo Overwrite %Overwrite%
echo Del_P %del_P%
pause
::///////////////////////// Robocopy options /////////////////////////////
IF %ONLog%==1 (
IF %OWLog%==1 SET LOG=/LOG:%BACKUP_FOLDER%\Robocopy_Log.txt
IF %OWLog%==2 SET LOG=/LOG+:%BACKUP_FOLDER%\Robocopy_Log.txt
) else (
SET LOG=
)
SET R_OPT=/Z /MIR %LOG%
REM Removed /copyall
::///////////////////// Overwrite Backup Code ////////////////////////////////
IF NOT EXIST %BACKUP_FOLDER%\ GOTO :skipOWC
IF %Overwrite%== 1 (
ECHO.
ECHO %BACKUP_FOLDER% will be RENAMED.
TIMEOUT /T 2
Call %RENAME%
)
IF %Overwrite%== 2 (
Echo %BACKUP_FOLDER% will be OVERWRITTEN.
ECHO Close this window if you've changed your mind.
TIMEOUT /T 10
)
REM Nothing to do to overwrite old backup. It will do it on its own with /MIR option.
:skipOWC
::///////////////////// Prompt to Delete Code ////////////////////////////////
IF %Del_P%== 1 SET Del_Opt_Prompt=/Q
IF %Del_P%== 2 SET DEL_Opt_Prompt=/P
DEL_OPT=/F /S %Del_Opt_Prompt%
REM Test
echo OnLog %Onlog%
echo Overwrite %Overwrite%
echo Del_P %del_P%
pause
EXIT /b
And back to Main_Control batch.
Escape the & ampersand character (this one to be displayed) using a ^ caret as follows:
echo before ^& %def_set% & pause
rem END TEST1
CALL %USEROPTIONS%
REM TEST2
echo after ^& %def_set% & pause
The & ampersand is one of a few with special meaning in a Window CLI and/or batch.
Read also Syntax : Escape Characters, Delimiters and Quotes.
So many errors and typos.
In trying to figure out why the called batches weren't working, I added more errors in my attempts to test it.
The tests in Main_Control contained ampersands.
echo before & %def_set% & pause
USEROPTIONS crashed because of a typo - letter "o" instead of zero "0" in:
ECHO %~no & %def_set% & pause
SETOPTIONS crashed because I forgot what variables I was using. %overwrite% doesn't describe anything and doesn't exist in the line:
echo Overwrite %Overwrite%
It should have been :
echo Overwrite backup OW_BU = %OW_BU%
echo Overwrite log OWlog = %OWlog%
SET was ommitted from the beginning of the line:
DEL_OPT=/F /S %Del_Opt_Prompt%
And i think that solved all my problems. What a waste of yesterday staring at this all day. In short, the calls worked & the variables were being passed from subroutine to subroutine. The errors were all typos initially and made even worse when I introduced more typos into my attempts to tests and trap errors. I'm tired of this project.

Print a text and set it to a variable BATCH

I'm making a program that allows you to register from the software. I have tryied a lot of commands but no one does what I want. In the example below I'm only making the USER EXAMPLE:
:REGISTER
set/p USR=Set your new user:
echo.>"USER.txt"
break>"USER.txt"
#echo %USR% > USER.txt
:LOGIN
set/p LOGUSER=Enter your user:
[I want to compare %LOGUSER% with the text in USER.txt] --> then goto OK.
Thank you!!
PS: Excuse me about my spelling mistakes!
if your user.txt contains only one line (your code overwrites it three times), it's quite simple:
set /p textuser=<USER.txt
if /i "%loguser%"=="%textuser%" goto ok
PS:
#echo %USR% > USER.txt
writes an unintended space to the output, which makes comparing difficult. Better write:
#echo %USR%>USER.txt
:REGISTER
#echo off
set/p USR=Set your new user:
echo.>"USER.txt"
break>"USER.txt"
#echo %USR%>USER.txt
:LOGIN
set/p LOGUSER=Enter your user:
:::: -- HERE'S THE MAIN THING -- ::::
<"USER.txt" set /p line=
if "%line%" EQU "%LOGUSER%" goto :OK
::::::::::::::::::::::::::::::::::::::::
echo not ok
exit /b 1
:ok
echo ok

Create a database within a bat file

I am trying to create a bat file that is in essence a database. I want to be able to enter information that is tied to a single record. When I enter a record, I want to be able to look up the record by the card number assigned to it. The code I have now doesn't really work due to the fact that the variables are not being stored properly.
This is my code:
Color 5F
#echo off
:start
cls
echo ==========================================
echo Gift Card
echo ==========================================
echo.
echo What would you like to do?
echo.
echo 1 Add Card
echo 2 Check Information
echo 3 Edit Card Balance
echo 4 Delete Card
echo.
set /p choice=Please enter choice:
if /I %choice%==1 goto 1
if /I %choice%==2 goto 2
:1
echo.
set /p var=Enter Card Number:
set /p val=Enter Amount:
set /p fname=Enter First Name:
set /p lname=Enter Last Name:
set /p cbal=Enter Current Balance:
set /p diss=Enter Date issued:
#echo set %var%=%val%=%fname%=%lname%=%cbal%=%diss% > %var%.bat
echo.
echo The data has been stored!
pause
goto start
:2
echo.
set /p var=Please enter card number:
setlocal enabledelayedexpansion
call %var%.bat
echo !%fname%! !%lname%!'s !%var%! card has $!%cbal%! on it as of !%diss%!!
pause > nul
goto start
I have tried to send the variables separately and altogether and none have worked. I am thinking it is because I do not have the delayed expansion sytax correct.
Any help is very appreciated!
Your problem seems to lie where you generate the batch file to fill the variables... You generate only one line, which does not actually assign anything to any of the variables you need.
Try changing
#echo set %var%=%val%=%fname%=%lname%=%cbal%=%diss% > %var%.bat
to be
#echo set var=%var% > %var%.bat
#echo set val=%val% >> %var%.bat
#echo set fname=%fname% >> %var%.bat
#echo set lname=%lname% >> %var%.bat
#echo set cbal=%cbal% >> %var%.bat
#echo set diss=%diss% >> %var%.bat
This should allow your variables to be loaded back properly.
Also, change
echo !%fname%! !%lname%!'s !%var%! card has $!%cbal%! on it as of !%diss%!!
to read
echo %fname% %lname%'s %var% card has $%cbal% on it as of %diss%!
You should never use both ! and % to surround variables in a batch file, only one or the other. % should be used in most cases; ! should be used when you need to read a variable inside a multi-line "code block" (for example, the result of an if statement or the body of a for loop) which is surrounded by parentheses.
Some more advice:
You can put setlocal delayedexpansion just once in the beginning of the file, right after #echo off. However, you are not doing anything in this program (yet, at least) to need delayed expansion. Delayed expansion is used to enable accessing variables with the ! symbol and is only useful inside multi-line statement bodies surrounded by parentheses. Because of that, you should get rid of it completely unless/until you actually need it, as it can cause other problems.
There is no need for the "#" symbol in any command after you call #echo off (but it won't break anything). The # symbol simply suppresses echoing of the command which it precedes, but it is redundant because all commands are silenced by default after you call echo off. For this reason, it is important to only use it on the first line when calling #echo off, so that the user does not see that command echoed.

save the result of a operation into a variable within a .BAT file

I have the following BAT file working ok:
it connects to an specific sql server and select getdate()
what I really wanted is to test whether the server is connectable.
I would like something like:
set is_connectable = call sqlcmd.exe %%SERVITORE%%
is there any way I could achieve this?
thanks and regards
marcelo
#echo off
color fc
cls
echo.
#ECHO --- BEGIN THE SCRIPT 1 ----
echo.
#echo the SERVITORE is "%1"
echo.
echo.
if "%1"=="" GOTO USAGE
set SERVITORE=-Stcp:%1% -Q " USE MASTER select getdate() "
call sqlcmd.exe %%SERVITORE%%
color 6
GOTO THE_END
:USAGE
echo.
echo USAGE:
echo.
ECHO the first parameter is the SERVITORE server.
echo example 1 SERVITORE108
echo.
ECHO the second parameter is optional
echo but if not supplied the default is \\SERVITORE\folder2$
echo.
echo ATB
echo.
:THE_END
color 8
It is easy to run a query and set the result to a DOS environment variable. For instance, you can do the following to get the date/time from the SQL Server instance (SQL Server is running locally in my instance):
for /f "skip=2 delims=" %%i in ('sqlcmd -S localhost -E -Q "set nocount on; select getdate() as [Now]"') do set is_connectable=%%i
However, the is_connectable environment variable set in this example will have an arbitrary value, which will make it hard to evaluate. Since you are just trying to verify that the SQL Server is there, alive, and responsive, you should run a query that creates a more predictable output, like this:
#echo off
:: Make sure the variable is undefined to start with
set is_connectable=
:: Make the connection and run a query that should always return '1'
for /f "skip=2 delims= " %%i in ('sqlcmd -S localhost -E -Q "set nocount on; select 1 as [Rows] into #temp; select ##rowcount as [Rows]; drop table #temp"') do set is_connectable=%%i
:: Verify if SQL Server is avaialble
if not defined is_connectable goto NotFound
if "%is_connectable%"=="1" goto Found
goto UnknownError
:Found
echo SQL Server was found and returned '1' as expected...
goto TheEnd
:NotFound
echo SQL Server was not found...
goto TheEnd
:UnknownError
echo SQLServer was found, but the return value was '%is_connectable%' instead of '1'...
goto TheEnd
:TheEnd