Batch RPG : Fight Loop Broken - batch-file

So, couple of problems I'm having.
When the TutorialFight runs, it works almost as I want it, except that the hero never gets hit.
When choosing Magic or Run, the if statements do not display the echos, and goes to the TutorialError.
Note: %stat% is the hero's stat, while %estat% is the enemy's stat.
:TutorialIntro
title Tutorial^^!
cls
set /a ehealth=15
set /a emana=15
set /a ebstat=5
set /a eostat=5
set /a ecstat=5
set /a elevel=1
set /a health=15
set /a mana=15
set /a bstat=5
set /a ostat=5
set /a cstat=5
set /a level=1
echo You have run into a
echo Level %elevel% Sock Puppet.
echo -I made this from a combination of a sock, glue, and some paper.
echo If you lose to this thing, I'm not looking you in the eye again.
echo You know, if I could actually look at you in the first place.
echo.
echo Level %level% Hero
echo %health% HP
echo %mana% MP
echo %bstat% Brawn
echo %ostat% Obscurity
echo %cstat% Cowardice
pause
goto Tutorial
:Tutorial
title Fight^^!
cls
if %ehealth% leq 0 goto TutorialWin
if %health% leq 0 goto TutorialLoss
echo Level %elevel% Sock Puppet.
echo (%ehealth% HP)
echo.
echo V.S.
echo.
echo Level %level% Hero
echo %health% HP
echo %mana% MP
echo %bstat% Brawn
echo %ostat% Obscurity
echo %cstat% Cowardice
echo.
set /p answer= Fight(1), Magic(2), Run(3)
if %answer%==1 goto TutorialFight
if %answer%==2 echo Sorry. You don't know magic yet.
if %answer%==3 echo No. You are not going to run from a sock.
goto TutorialError
:TutorialFight
set /a loss=0
set /a eloss=0
set /a num=%random% * ((%cstat%-%ecstat%) - 1 + 1) / 32768 + 1
if %num% lss (%ecstat%/2) set /a loss=%random% * (%ebstat% - (%ebstat%/2) + 1) / 32768 + (%ebstat%)/2)
if %num% geq (%ecstat%/2) set /a eloss=%random% * (%bstat% - (%bstat%/2) + 1) / 32768 + (%bstat%)/2)
set /a health=(%health% - %loss%)
set /a ehealth=(%ehealth% - %eloss%)
goto Tutorial
:TutorialError
title Huh?
cls
echo Try that again. I believe in you.
pause
goto Tutorial
:TutorialWin
title Victory
cls
echo Yay^^!
echo Now I think you are ready for the big pond^^!
pause
goto Intro
:TutorialLoss
title ...
cls
echo ...
echo.
echo Let's forget that ever happened.
pause
goto Menu

Use an additional calculation:
Set/A halfecstat=ecstat / 2
Then change the line from:
if %num% lss (%ecstat%/2)
to:
If %num% Lss %halfecstat%
Also I've noted that the calculation which follows it has unbalanced parentheses so you may want to give that another careful look too.

Related

Programming error in Batch

I just want to ask, where is problem in this script. Every time i try to open mns fight, it just crashes somewhere on if %lokace%==2 if %vyber2%==mns set lokace=3 set monstrum=1
(btw, it's Czech game, so just ignore names)
Whole code:
:hra
cls
if %lokace%==0 echo Vesnice-domov
if %lokace%==1 echo Vesnice-namesti
if %lokace%==2 echo DabluvLes
if %lokace%==3 goto boj
echo mas %zivoty% hp
echo -----------------------------------
echo Co chces udelat?
if %lokace%==0 echo Jit na namesti [1]
if %lokace%==1 echo Jit domu [0]
if %lokace%==1 echo Jit do lesa [2]
if %lokace%==2 echo Najit monstrum [mns]
if %lokace%==2 echo Jit do vesnice [1]
if %lokace%==0 echo Vyspat se [spt]
set /p vyber2=Vyber si:
if %lokace%==1 if %vyber2%==0 set lokace=0
if %lokace%==0 if %vyber2%==1 set lokace=1
if %lokace%==1 if %vyber2%==2 set lokace=2
if %lokace%==0 if %vyber2%==spt if %zivoty% LSS %maxzivoty% set /a zivoty=%zivoty%+1
if %lokace%==2 if %vyber2%==mns set lokace=3 set monstrum=1
if %lokace%==2 if %vyber2%==1 set lokace=1
goto hra
:boj
if %monstrum%==1 set monstrumdmg=1 set monstrumhp=10
if %monstrumhp%==0 set lokace=2 set monstrum=0 goto hra
if %zivoty%==0 set lokace=0 goto hra
if %monstrumhp% GTR 0 if %monstrum%==1 echo Pavouk
echo Monstrum ma %monstrumhp% hp
echo Mas %zivoty% hp
echo Boj. Mas utok %damage% [boj]
echo Utek [utk]
set /p fight=Vyber si:
if %fight%==boj if %monstrum%==1 set /a monstrumhp=%monstrumhp%-%damage% set /a zivoty=%zivoty%-%monstrumdmg%
if %fight%==utk set lokace=2 set monstrum=0 goto hra
goto boj
set lokace=3 set monstrum=1
should be
set lokace=3&set monstrum=1
otherwise, lokace is set to 3 set monstrum=1
(there seems to be a number of such errors in the code)
Your problem: set lokace=3 set monstrum=1 sets one variable named lokace with the value 3 set monstrum=1
Possible solutions:
a) concatenate commands with a &:
set lokace=3&set monstrum=1
(a better (safer) syntay (to avoid stray spaces) would be set "lokace=3" & set "monstrum=1")
b) use code blocks:
if %lokace%==2 if %vyber2%==mns (
set "lokace=3"
set "monstrum=1"
)
c) set /a can set several variables at the same time (pure set can't), but all values have to be integers:
if %lokace%==2 if %vyber2%==mns set /a lokace=3, monstrum=1
Same problem with for example set lokace=0 goto hra
Speaking about safety: you should enclose both sides of an if comparison in quotes to avoid syntax error with empty/undefined variables:
if "%lokace%"=="2" if "%vyber2%"=="mns" ...
Example for study:
:hra
ClS
If "%lokace%"=="3" GoTo boj
If "%lokace%"=="0" Echo Vesnice-domov
If "%lokace%"=="1" Echo Vesnice-namesti
If "%lokace%"=="2" Echo DabluvLes
Echo mas %zivoty% hp
Echo -----------------------------------
Echo Co chces udelat?
If "%lokace%"=="0" (Echo Jit na namesti [1]& Echo Vyspat se [spt])
If "%lokace%"=="1" (Echo Jit domu [0]& Echo Jit do lesa [2])
If "%lokace%"=="2" (Echo Najit monstrum [mns]& Echo Jit do vesnice [1])
Set /P "vyber2=Vyber si: "
If "%lokace%%vyber2%"=="10" Set "lokace=0"
If "%lokace%%vyber2%"=="01" Set "lokace=1"
If "%lokace%%vyber2%"=="12" Set "lokace=2"
If /I "%lokace%%vyber2%"=="0spt" If %zivoty% Lss %maxzivoty% Set /A zivoty+=1
If /I "%lokace%%vyber2%"=="2mns" Set /A lokace=3,monstrum=1
If "%lokace%%vyber2%"=="21" Set "lokace=1"
GoTo hra
:boj
If "%monstrum%"=="1" Set /A monstrumdmg=1,monstrumhp=10
If "%monstrumhp%"=="0" (Set /A lokace=2,monstrum=0 & GoTo hra)
If "%zivoty%"=="0" (Set "lokace=0" & GoTo hra)
If %monstrumhp% Gtr 0 If "%monstrum%"=="1" Echo Pavouk
Echo Monstrum ma %monstrumhp% hp
Echo Mas %zivoty% hp
Echo Boj. Mas utok %damage% [boj]
Echo Utek [utk]
Set /P "fight=Vyber si: "
If /I "%fight%%monstrum%"=="boj1" Set /A monstrumhp-=damage,zivoty-=monstrumdmg
If /I "%fight%"=="utk" (Set /A lokace=2,monstrum=0 & GoTo hra)
GoTo boj

CMD add every variable generated to a list

I know I can write an echo > C:/Folder/name.txt
But I have a generator to make 2 number for Cord and can't figure out a quick way to make a one line echo > with all the points
for shortness I'll simplify my code because the current code is not the issue
Echo off
Setlocal EnableDelayedExpansion
set R=1
set Number=1
:Loop
if %R% EQU 1 (set /p Max=How many Max Points? ) Else(
echo.)
set /p PX%number%=What is PointX%number%?
set /p PY%number%=What is PointY%number%?
if %Number% GEQ %Max% (goto :fin) Else(
set /a Number=%Number%+1 & set R=2 & Goto :loop)
This Is what Im trying to Optimize
:fin
echo (%PX1%,%PY1%),(%PX2%,%PY2%),(%PX3%,%PY3%) ... Ect >C:Folder/File.txt
Is there any way to make all the generated numbers on 1 line
Credit to Squashman for the Answer - Thank you!
Correct Code:
Echo off
Setlocal EnableDelayedExpansion
set R=1
set Number=1
set Line=Test
:Loop
if %R% EQU 1 (set /p Max=How many Max Points? ) Else (
echo.)
set /p PX%number%=What is PointX%number%?
set /p PY%number%=What is PointY%number%?
set line=%line%(!PX%number%!,!PY%number%!),
if %Number% GEQ %Max% (goto :fin) Else (
set /a Number=%Number%+1 & set R=2 & Goto :loop)
:fin
echo %Line:~0,-1% >C:Folder/File.txt
Credit to Squashman for the Answer - Thank you!
The logic is so much simpler if you get the max point count before the loop. And the FOR /L loop can auto increment your counter and eliminate the need for GOTO.
#echo off
setlocal enableDelayedExpansion
set /p "cnt=How many points? "
set "ln="
for /l %%N in (1 1 %cnt%) do (
echo(
set /p "PX%%N=What is PointX%%N? "
set /p "PY%%N=What is PointY%%N? "
set "ln=!ln!(!PX%%N!,!PY%%N!),"
)
echo(
echo !ln:~0,-1!

Batch file game trouble, missing operator error

I've been working on a batch file game for some time, but I am having trouble with the shop I am making. When I run the script and try to buy something in the shop it gives me "missing operator" and then displays the message for buying the item, but doesn't add the item to the player's inventory. Heres the code. Any help is much appreciated.
:w_shop
title Nova: In the Weapon Shop
:sword_screen
cls
echo.
echo You have %money% gold.
echo.
echo What will you buy?
echo 1) Wooden Sword: 500 gold
echo You own %sword1%
echo.
echo 2) Stone Sword: 1000 gold
echo You own %sword2%
echo.
echo 3) Iron Blade: 5000 gold
echo You own %sword3%
echo.
echo 4) Mythril Sabre: 7500 gold
echo You own %sword4%
echo.
echo 5) Mythril Longsword: 10000 gold
echo You own %sword5%
echo.
echo 6) Next
echo.
echo 7) Leave Shop
set/p sword_screen=
if %sword_screen% LEQ 0 goto sword_screen
if %sword_screen% GEQ 8 goto sword_screen
if %sword_screen% EQU 1 goto buy_sword1
if %sword_screen% EQU 2 goto buy_sword2
if %sword_screen% EQU 3 goto buy_sword3
if %sword_screen% EQU 4 goto buy_sword4
if %sword_screen% EQU 5 goto buy_sword5
if %sword_screen% EQU 6 goto gauntlet_screen
if %sword_screen% EQU 7 goto main_menu
:buy_sword1
set price=500
set att=100
if %money% LSS %price% goto lack_funds
set/a money=%money%-%price%
set/a %sword1%=%sword1%+1
echo.
echo You bought a Wooden Sword. This weapon has %att% attack.
pause>nul
goto sword_screen
:buy_sword2
set price=1000
set att=150
if %money% LSS %price% goto lack_funds
set /a money=%money%-%price%
set /a %sword2%=%sword2%+1
echo.
echo You bought a Stone Sword. This weapon has %att% attack.
pause>nul
goto sword_screen
:buy_sword3
set price=5000
set att=300
if %money% LSS %price% goto lack_funds
set /a money=%money%-%price%
set /a %sword3%=%sword3%+1
echo.
echo You bought a Iron Blade. This weapon has %att% attack.
pause>nul
goto sword_screen
:buy_sword4
set price=7500
set att=500
if %money% LSS %price% goto lack_funds
set /a money=%money%-%price%
set /a %sword4%=%sword4%+1
echo.
echo You bought a Mythril Sabre. This weapon has %att% attack.
pause>nul
goto sword_screen
:buy_sword5
set /a price=10000
set /a att=1000
if %money% LSS %price% goto lack_funds
set /a money=%money%-%price%
set /a %sword5%=%sword5%+1
echo.
echo You bought a Mythril Longsword. This weapon has %att% attack.
pause>nul
goto sword_screen
Just to be clear, the sword variables and the money variable are declared earlier on in the code
since you did not define money nor sword variables the lines
if %money% LSS %price% goto lack_funds
set/a %sword1%=%sword1%+1
expand to
if LSS 500 goto lack_funds
set/a =+1
which is wrong. Those are common mistakes. change the line like this:
if [%money%] LSS [%price%] goto lack_funds
set/a sword1=0%sword1%+1
Note that the variables are surrounded by square brackets so even if the variable is undefinde you'll get at least a valid line
Note that the left-param in the set-line must not have the %-signs and the right-param has an additional 0 so that if the variable is undefined you'll get 0+1 which is valid
btw, there is not lack_funds lable in your code snippet and also i recommend adding
echo off
set money=5000
at the beginning of the script

How to do math in batch-file

I have been having troubles with batch-codes that I would expect to work, but don't...
Below is what I have written...
#echo off
cls
:loop
set /p "input=Input a number: "
set /a "number=%input%" 2>nul
REM check if input valid
if "%input%" NEQ "%number%" (
cls
Echo Please Enter a valid number! &Echo.&Echo.
goto :loop
)
Set /a Even=number%%2
if %Even% EQU 0 (
Echo Substituting Even Number in: x / 2
Echo set /p"=(%number%) / 2 = "
set /a answer=number/2
) Else (
Echo Substituting Odd Number in: 3x - 1
<nul set /p"=3(%number%)-1 = "
set /a answer=number*3
set /a answer=answer-1
)
Echo %answer%
Echo.
Echo.
goto :loop
Echo Unexpected Error . . .
pause
Exit
Whenever I input a number into the console, it does the math, like I want it to, but prints the number -1, and every time i input another number, the number goes to -2, -3, -4, so on.
Put a setlocal enableextensions at the beginning after the #echo off, e.g.
#echo off
setlocal enableextensions
cls
Also, I think you would also need to use delayed variable expansion (usually denoted by !var!), which would change your script above to something like this:
#echo off
setlocal enableextensions enabledelayedexpansion
cls
:loop
set /p "input=Input a number: "
set /a number=!input! 2>nul
REM check if input valid
if "!input!" NEQ "!number!" (
cls
Echo Please Enter a valid number!
Echo.
Echo.
goto :loop
)
REM Make sure that it is an integer put in (just in case)
set /a int=!number! %% 1
if "!input!" NEQ "!int!" (
cls
Echo Please Enter a valid number!
Echo.
Echo.
goto :loop
)
Set /a Even=!number! %% 2
if !Even! EQU 0 (
Echo Substituting Even Number in: x / 2
set /a answer=!number! / 2
) Else (
Echo Substituting Odd Number in: 3x - 1
set /a answer=!number! * 3 - 1
)
Echo !answer!
Echo.
Echo.
goto :loop
I also would like to point out that I also fixed a few other bugs (set /p isn't of any use in this script at all, especially in where it is used, and also you need the modulus to find even/odd).

set not expected at this time, batch?

OK so I have this little game I am writing on this Windows XP computer in batch. I get "set was not expected at this time" when I run the following code(sorry it's real long I just haven't made it smaller yet. NOTE I didn't ask for you to make my code smaller, so please DO NOT do it):
#echo off
set str=0
set int=0
set agi=0
set dex=0
goto chrselect
:chrselect
cls
echo Character select!
echo.
echo 1) mage
echo.
echo 2) swords man
echo.
echo 3) archer
set /p start=-
if %start%==1 goto skillsetupm
if %start%==2 goto skillsetups
if %start%==3 goto skillsetupa
:skillsetupm
set health=50
set mana=100
set str=3
set int=6
set agi=5
set dex=4
set chr=m1
goto skillsee
:skillsetups
set health=100
set mana=50
set str=6
set int=4
set agi=3
set dex=5
set chr=s1
goto skillsee
:skillsetupa
set health=75
set mana=75
set str=3
set int=4
set agi=6
set dex=5
set chr=a1
goto skillsee
:skillsee
cls
echo Skills as is:
echo.
echo Strength: %str%
echo Intelligence: %int%
echo Agility: %agi%
echo Dexterity: %dex%
echo.
echo 1) Choose new character
echo.
echo 2) Continue to see how stats influence combat!
set /p start=-
if %start%==1 goto chrselect
if %start%==2 goto skillc
:skillc
set /a handattk=3+%str%
set /a magicattk=2+%str%+%dex%
set /a block=%agility%+%dex%
set /a blockchnc=%block%*5
set /a bowattk=3+%str%+%dex%
set /a swrdattk=4+%str%+%dex%
set /a slowchnc=%str%*4
if %chr%==m1 goto skillcinf
if %chr%==s1 goto skillcinf
if %chr%==a1 goto skillcinf
:skillcinf
cls
echo Skill stuff!
echo.
echo Hand attack: %handattk%
echo.
echo Block chance: %blockchnc% %
echo.
echo Slow chance: %slowchnc% %
echo.
if %chr%==m1 echo Magic attack: %magicattk%
if %chr%==s1 echo Sword attack: %swrdattk%
if %chr%==a1 echo Bow attack: %bowattk%
echo.
echo 1) Choose new character(last chance)
echo.
echo 2) Start game
set /p start=-
if %start%==1 goto chrselect
if %start%==2 goto menue
:menue
cls
set bossh=500
set exp=0
set playcount=0
echo Health:///%health%///
echo Mana:////%mana%////
echo Experience:////%exp%/////
echo Play count: %playcount%
echo Battle?(y/n)
set /p start=-
if %start%==y goto battle
if %start%==n goto menue
:battle
set /a playcount=%playcount%+1
cls
echo Health:///%health%///
echo Mana:////%mana%////
echo Experience:////%exp%/////
echo Play count: %playcount%
echo Attack Dragon(Health:%bossh%) with?
echo.
echo 1-Hand(%handattk% damage)
echo.
echo 2-Block(%blockchnc% % chance of blocking)
echo.
if %chr%==m1 echo 3-Magic attack(%magicattk% damage)
if %chr%==s1 echo 3-Sword Attack(%swrdattack% damage)
if %chr%==a1 echo 3-Bow Attack (%bowattk% damage)
set /p start=-
pause >nul
if %start%==1 set /a bossh=%bossh%-%handattk%
if %start%==2 set /a blockrandm=%random% %%100
goto battle2
if %start%==3 goto spclattk
:spclattk
cls
if %chr%==m1 set /a bossh=%bossh%-%magicattk%%
if %chr%==s1 set /a bossh=%bossh%-%swrdattk%
if %chr%==a1 set /a bossh=%bossh%-%bowattk%
goto battle2
:battle2
if %bossh% leq 0 goto win
set /a bossd=%random% %%5
if %blockrandm%==%blockchnc% set bossd=0
set /a health=%health%-%bossd%
cls
echo Health:///%health%///
echo Mana:////%mana%////
echo Experience:////%exp%/////
echo Play count: %playcount%
echo Attack Dragon(Health:%bossh%) with?
echo.
echo 1-Hand(%handattk% damage)
echo.
echo 2-Block(%blockchnc% % chance of blocking)
echo.
if %chr%==m1 echo 3-Magic attack(%magicattk% damage)
if %chr%==s1 echo 3-Sword Attack(%swrdattack% damage)
if %chr%==a1 echo 3-Bow Attack (%bowattk% damage)
set /p start=-
if %start%==1 set /a bossh=%bossh%-%handattk%
if %start%==2 set /a blockrandm=%random% %%100
if %start%==3 goto battleattk
goto battle2
Anytime I get to the :battle screen and press an option I get set was not expected at this time.
Your variable %blockrandm% isn't initialised when you get to :battle2 so the comparison in line 148 reads
if ==0 set bossd=0
which obviously is invalid syntax. You can avoid it by quoting both sides of the comparison (which is a great idea in practically all cases when writing such code).
For future reference: Remove the echo off and you at least see what line is responsible and often also why it fails.

Resources