How do you subtract a number from a variable in a batch file?

I can't figure out how to make a lives system for my game and I need to know how.

Here is my code for the lives;

SET lives=5

:Scene1
CLS
ECHO  o       Woof!
ECHO /0\   ,###@'
ECHO / \     /   \
ECHO #########################################
ECHO.
ECHO You are walking along the dirt
ECHO road with your backpack and trusty dog Steve.
ECHO You have !lives! lives.
PAUSE
CLS

. . .

:WinFight1

SET /a lives-=1
CLS

ECHO  o
ECHO /0\    ,###@                      w   \__,.  \__,.
ECHO / \      /   \                        3--`~  /--,^  /--,^
ECHO #########################################
ECHO.
ECHO You won the fight!
ECHO You now have !lives! lives.
PAUSE
GOTO Scene2

Open in new window



I expected it to output 'You have 5 lives.' in the first section, and 'You now have 4 lives.' in the second part, but instead, I got 'You have !lives! lives and 'You now have !live! lives.'
Henry KertauferpauferAsked:
Who is Participating?
 
Kyle AbrahamsSenior .Net DeveloperCommented:
In order to do the ! you need the command:
setlocal enabledelayedexpansion

Open in new window

0
 
Kyle AbrahamsSenior .Net DeveloperCommented:
SET lives=5

:Scene1
CLS
ECHO  o       Woof!
ECHO /0\   ,###@'
ECHO / \     /   \
ECHO #########################################
ECHO.
ECHO You are walking along the dirt
ECHO road with your backpack and trusty dog Steve.
ECHO You have %lives% lives.
PAUSE
CLS

. . .

:WinFight1

SET /a lives-=1
CLS

ECHO  o
ECHO /0\    ,###@                      w   \__,.  \__,.
ECHO / \      /   \                        3--`~  /--,^  /--,^
ECHO #########################################
ECHO.
ECHO You won the fight!
ECHO You now have %lives% lives.
PAUSE
GOTO Scene2

Open in new window

0
 
Bill PrewCommented:
There are two ways to refer to variables in command line and BAT scripts.  One uses %var% format, the other uses !var! format.  The first is the "default" mode if you will, and variables are resolved before the script executes, when the interpreter reads it.  The second is known as delayed expansion, and rather than resolving the value of the variable during parsing, it waits until execution.  This is typically needed when variables are updated inside a loop, so that the new value can be obtained.  Additional expanation available here:


You will also want to add the following as the first line of the BAT script, so that you don't see a lot of extra information while it runs.

@echo off


»bp
0
 
Ben Personick (Previously QCubed)Lead Network EngineerCommented:
I sent you an Email on this as well, hope we might be able to collaboratively work on your game, it seems fun.

 Here is an example of how you might modularize the code so you can minimize the amount of different Text and Animation draws you need to maintain.

  I also updated it slightly verses the version I emailed you, and thoguht I'd share it here. :)

REM Script: YourGame.cmd
REM Version: 0.2.0
@(
	REM Script Begins Here
	SETLOCAL ENABLEDELAYEDEXPANSION
	ECHO OFF
	SET "_Lives=5"
	SET "_eLvl=0"
	SET "_DogName=Steve"
	CALL :Initialize_Draws
	CALL :Initialize_Text
)

REM This calls the Main function
CALL :Main

(
	REM Script Ends Here
	ENDLOCAL
	EXIT /B %_eLvl%
)

:Main
	CALL :Scene1
	CALL :Scene2
REM This ends the Main Function
GOTO :EOF


:Scene1
	SET "_Monster=Dog"
	SET "_MonsterAction=Bite"
	SET "_Action=Fight"
	SET "_Draw=1"
	SET "_Text=1"
	SET "_Outcome="
	CALL :Loop_Action
REM End Scene 2
GOTO :EOF

:Scene2
	SET "_Monster=Dog"
	SET "_MonsterAction=Bite"
	SET "_Action=Fight"
	SET "_Draw=1"
	SET "_Text=1"
	SET "_Outcome="
	CALL :Loop_Action
REM End Scene 2
GOTO :EOF

:Loop_Action
		CLS
		CALL :Print_Anim %_Monster% %_Action% !_Draw!
		CALL :Print_Text %_Monster% %_Action% !_Text!
		REM Call some logic to determine what Draws and text to display.
		CALL :%_Action%Logic !_Draw! !_Text!
		PAUSE
	IF NOT DEFINED _Outcome GOTO :Loop_Action
REM End Scene Loop
GOTO :EOF

:FightLogic
	REM Some logic could go here to pic Draws and text.
	REM  This basic hold-in allows us to decide win/loss and which Draws pair with which text next.
	REM  For now we'll just make a mock battle
	SET "_Damage=0"
	REM IF /I "%_Action%" EQU "_Fight" (
		IF /I "%_Draw%" EQU "%_Text%" (
			SET /A "_Text+=1"
		) ELSE (
			SET /A "_Draw+=1"
			SET /A "_Text+=1"
		)
		IF /I "%_Draw%" EQU "2" (
			SET "_Damage=1"
		)
		SET /A "_Lives-=!_Damage!"
		IF /I "!_Draw!" EQU "3" (
			SET "_Action=Win"
			SET "_Draw=1"
			SET "_Text=1"
		)
	REM ) ELSE (
		REM SET "_Outcome=!_Action!"
	REM )
GOTO :EOF

:WinLogic
	SET "_Outcome=!_Action!"
GOTO :EOF

:LossLogic

GOTO :EOF

:EndGameLogic

GOTO :EOF

:Print_Anim
	FOR /L %%L IN (1,1,5) DO (
		CALL CALL ECHO.%%_Draw_!_Monster!_!_Action!_!_Draw!_Line%%L%%
	)
GOTO :EOF

:Print_Text
	FOR /L %%L IN (1,1,5) DO (
		CALL CALL ECHO.%%_Text_!_Monster!_!_Action!_!_Text!_Line%%L%%
	)
GOTO :EOF

:Initialize_Draws
	SET /A "_TmpCount=0"
	(
		SET /A "_TmpCount+=1"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line1= "
		SET "_Draw_Dog_Fight_!_TmpCount!_Line2=   o         ~{Woof!}"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line3=  /0\     ,###@'"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line4=  / \       /   \"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line5= #########################################"

		SET /A "_TmpCount+=1"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line1= "
		SET "_Draw_Dog_Fight_!_TmpCount!_Line2=   o         ~{Woof! Woof!}"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line3=  /0\     ,###@'   %%_Monster%% %%_MonsterAction%%s you for %%_Damage%%"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line4=  / \       /   \"
		SET "_Draw_Dog_Fight_!_TmpCount!_Line5= #########################################"
	)
	
	SET /A "_TmpCount=0"
	(
		SET /A "_TmpCount=1"
		SET "_Draw_Dog_Win_!_TmpCount!_Line1= "
		SET "_Draw_Dog_Win_!_TmpCount!_Line2=   o"
		SET "_Draw_Dog_Win_!_TmpCount!_Line3=  /0\     ,###@                      w   \__,.  \__,."
		SET "_Draw_Dog_Win_!_TmpCount!_Line4=  / \       /   \                        3--`~  /--,^  /--,^"
		SET "_Draw_Dog_Win_!_TmpCount!_Line5= #########################################"
	)
:Initialize_Text

ECHO.
ECHO You won the fight!
ECHO You now have !lives! lives.

	SET /A "_TmpCount=0"
	(
		SET /A "_TmpCount+=1"
		SET "_Text_Dog_Fight_!_TmpCount!_Line1= "
		SET "_Text_Dog_Fight_!_TmpCount!_Line2= You are walking along the dirt"
		SET "_Text_Dog_Fight_!_TmpCount!_Line3= road with your backpack and trusty dog %%_DogName%%."
		SET "_Text_Dog_Fight_!_TmpCount!_Line4= "
		SET "_Text_Dog_Fight_!_TmpCount!_Line5= You have %%_Lives%% lives."

		SET /A "_TmpCount+=1"
		SET "_Text_Dog_Fight_!_TmpCount!_Line1= "
		SET "_Text_Dog_Fight_!_TmpCount!_Line2= Your Dog %%_DogName%% Notices a Rogue %%_Monster%%"
		SET "_Text_Dog_Fight_!_TmpCount!_Line3= It looks Hungry!  Prepare to fight!"
		SET "_Text_Dog_Fight_!_TmpCount!_Line4= "
		SET "_Text_Dog_Fight_!_TmpCount!_Line5= You have %%_Lives%% lives."
		
		SET /A "_TmpCount+=1"
		SET "_Text_Dog_Fight_!_TmpCount!_Line1= "
		SET "_Text_Dog_Fight_!_TmpCount!_Line2= The Rogue %%_Monster%% %%_MonsterAction%%s you!"
		SET "_Text_Dog_Fight_!_TmpCount!_Line3= It Deals %%_Damage%% Damage"
		SET "_Text_Dog_Fight_!_TmpCount!_Line4= "
		SET "_Text_Dog_Fight_!_TmpCount!_Line5= You have %%_Lives%% lives."
	)
	
	SET /A "_TmpCount=0"
	(
		SET /A "_TmpCount=1"
		SET "_Text_Dog_Win_!_TmpCount!_Line1= "
		SET "_Text_Dog_Win_!_TmpCount!_Line2= You won the fight!"
		SET "_Text_Dog_Win_!_TmpCount!_Line3= "
		SET "_Text_Dog_Win_!_TmpCount!_Line4= "
		SET "_Text_Dog_Win_!_TmpCount!_Line5= You have %%_Lives%% lives."
	)
	
	SET /A "_TmpCount=0"
	(
		SET /A "_TmpCount=1"
		SET "_Text_Dog_Loss_!_TmpCount!_Line1= "
		SET "_Text_Dog_Loss_!_TmpCount!_Line2= You Lost the fight!"
		SET "_Text_Dog_Loss_!_TmpCount!_Line3= "
		SET "_Text_Dog_Loss_!_TmpCount!_Line4= "
		SET "_Text_Dog_Loss_!_TmpCount!_Line5= You have %%_Lives%% lives."
	)
GOTO :EOF

Open in new window

0
 
Ben Personick (Previously QCubed)Lead Network EngineerCommented:
What a shame the OP has not responded, I really got carried away getting into how he could enhance this a lot further
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.