So I've started getting familiar with Batch for the last year off and on, all self taught, and I've made a few little dinky projects here and there but I'm wanting to find out the best way to go about expanding my code. Using other programs for inspiration I've learned just the tip of the icebergs for "FOR loops" and using functions and small macro processes. I want to know if there is anything I should do differently in terms of architecture and planning so I can one day make amazing Batch programs like T3RROR (little weird but I'm a big fan and your my batch idol).
Below is my most complex batch code I've written and a template for future games, please add any tip or advice.
@echo off
SETLOCAL EnableDelayedExpansion
title crafting micro
color 2
:://///////////////////////////////////////////////////////////////////////
:pre_start
::initializes at the start of the program
set /a display_message=0
set /a inv_fiber=1
set /a fiber_qty=100
set /a inv_rope=0
set /a rope_qty=0
set /a inv_stick=1
set /a stick_qty=100
set /a inv_stone=1
set /a stone_qty=100
set /a inv_sharpened_stone=0
set /a sharpened_stone_qty=0
set /a inv_spear=0
set /a spear_qty=0
set /a inv_handaxe=0
set /a handaxe_qty=0
set /a inv_hammer=0
set /a hammer_qty=0
:://///////////////////////////////////////////////////////////////////////
:start
cls
echo ----------------------------------------------------
echo Crafting Menu
echo ----------------------------------------------------
echo.
echo Raw materials
echo -------------
if %inv_fiber%==1 echo Fiber: x%fiber_qty%
if %inv_stick%==1 echo Stick: x%stick_qty%
if %inv_stone%==1 echo Stone: x%stone_qty%
echo.
echo Refined Materials
echo -----------------
if %inv_rope%==1 echo Rope: x%rope_qty%
if %inv_sharpened_stone%==1 echo Sharpened Stone: x%sharpened_stone_qty%
echo.
echo Tools
echo -----
if %inv_spear%==1 echo Spear: x%spear_qty%
if %inv_handaxe%==1 echo Handaxe: x%handaxe_qty%
if %inv_hammer%==1 echo Hammer: x%hammer_qty%
::sets visibility
echo.
echo ----------------------------------------------------
echo.
echo What do you wanna craft?
echo 1. Rope (x3 Fiber)
echo 2. Sharpened Stone (x2 Stones)
echo 3. Spear (x1 Rope, x1 Stick, x1 Sharpened Stone )
echo 4. Handaxe (x2 Rope, x2 Stick, x1 Sharpened Stone)
echo 5. Hammer (x2 Rope, x2 Stick, x1 Stone)
echo.
choice /c 12345
echo.
echo.
if %errorlevel%==1 (
set item=Rope
::item being crafted
set /a req1=%fiber_qty%
::1st required item
set /a min1=3
:: minimum amount needed to craft
set /a req2=0
set /a min2=0
set /a req3=0
set /a min3=0
set var1=fiber
::passes a string to be use for a vavriable
set var2=
set var3=
set var4=rope
)
if %errorlevel%==2 (
set item='Sharpened Stone'
set /a req1=%stone_qty%
set /a min1=2
set /a req2=0
set /a min2=0
set /a req3=0
set /a min3=0
set var1=stone
set var2=
set var3=
set var4=sharpened_stone
)
if %errorlevel%==3 (
set item=Spear
set /a req1=%rope_qty%
set /a min1=1
set /a req2=%stick_qty%
set /a min2=1
set /a req3=%sharpened_stone_qty%
set /a min3=1
set var1=rope
set var2=stick
set var3=sharpened_stone
set var4=spear
)
if %errorlevel%==4 (
set item=Handaxe
set /a req1=%rope_qty%
set /a min1=2
set /a req2=%stick_qty%
set /a min2=2
set /a req3=%sharpened_stone_qty%
set /a min3=1
set var1=rope
set var2=stick
set var3=sharpened_stone
set var4=handaxe
)
if %errorlevel%==5 (
set item=Hammer
set /a req1=%rope_qty%
set /a min1=2
set /a req2=%stick_qty%
set /a min2=2
set /a req3=%stone_qty%
set /a min3=1
set var1=rope
set var2=stick
set var3=stone
set var4=hammer
)
::////////////////////////////////////////////////////////////////////////////////////
:craftable_check
if %req1% GEQ %min1% (
if %req2% GEQ %min2% (
if %req3% GEQ %min3% (
::checks minimum requried material inventory for crafting
set /a %var1%_qty=!%var1%_qty!-%min1%
set /a %var2%_qty=!%var2%_qty!-%min2%
set /a %var3%_qty=!%var3%_qty!-%min3%
::uses all the required inventory for crafting
set /a %var4%_qty=!%var4%_qty! 1
::creates the crafted item
set /a inv_%var4%=1
::makes the new item is visible
if %req1% LEQ 0 (
set inv_%var1%=0
)
if %req2% LEQ 0 (
set inv_%var2%=0
)
if %req3% LEQ 0 (
set inv_%var3%=0
)
::makes the items ivisible if there is no inventory
set /a display_message=1
set message='You have successfully created a %item%!'
goto message
)
)
)
set /a display_message=1
set message=You dont have enough material for this
goto message
:://///////////////////////////////////////////////////////////////////////////////////
:message
cls
if %display_message%==1 (
echo %message%
pause
set /a display_message=0
goto start
)
::General Settings ------------------------------------------------------------------------------
@echo off
title Game Template
color 02
cd "%userprofile%\desktop"
::Game Settings ---------------------------------------------------------------------------------
:game_settings
cls
goto welcome
::Welcome Screen --------------------------------------------------------------------------------
:welcome
cls
echo Welcome to this Game!
echo/
echo Please select one of the options below
echo 1. New Game
echo 2. Load Game
echo 3. Credits
choice /c 123
if %errorlevel%==1 goto back_story
if %errorlevel%==2 goto load_game
if %errorlevel%==3 goto credits
goto welcome
::Save Game -------------------------------------------------------------------------------------
:save_game
cls
(
echo %location%
echo %player_name%
)>"GameSave.txt"
echo Game saved...
pause
goto :eof
::Load Game -------------------------------------------------------------------------------------
:load_game
cls
(
set /p location=
set /p player_name=
)<"GameSave.txt"
pause
goto %location%
::Back Story ------------------------------------------------------------------------------------
:back_story
cls
echo Backstory...
pause >nul
goto character_creation
::Character Creation ----------------------------------------------------------------------------
:character_creation
cls
echo What is your name?
set /p player_name=
if /i "%player_name%"=="" (
echo Player name can not be blank.
pause >nul
goto character_creation
)
goto start
::Game Start ------------------------------------------------------------------------------------
:start
cls
set location=start
echo %player_name%
echo %location%
echo/
echo 1. Pause Menu
choice /c 1
if %errorlevel%==1 goto pause_menu
goto start
::Pause Menu ------------------------------------------------------------------------------------
:pause_menu
cls
echo 1. Save Game
echo 2. Return
echo 3. Quit
choice /c 123
if %errorlevel%==1 call :save_game
if %errorlevel%==2 goto %location%
if %errorlevel%==3 goto exit
goto pause_menu
::Credits ---------------------------------------------------------------------------------------
:credits
cls
echo credits...
pause >nul
goto welcome
CodePudding user response:
if %req3% GEQ %min3% (
::checks minimum requried material inventory for crafting
set /a %var1%_qty=!%var1%_qty!-%min1%
won't work properly - ::
comments are actually broken labels (labels that cannot be reached with a goto
) and break code blocks (parenthesised series of statements)
Reserve a prefix character for any variable that you may want to save to a file for reloading later. EG #
set #>filename
saves all of the variables that start #
to the file in the form #whatever=something
.
Reload with
for /f "delims=" %%e in (filename) do set "%%e"
Equally, you can set up scenario files by choosing another prefix character.
Clearing the current values of variables-beginning-# is
for/f "delims==" %%e in ('set # 2^>nul') do set "%%e="
which you do just before loading from file.
Use set "var=value"
for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \
, Space or "
- build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value"
is used, then the quotes become part of the value assigned.
set up a menu subroutine using choice
:menu
set "choices="
set /a choicecount=0
cls
:menu_next
set /a choicecount =1
if defined choicetext[%choicecount%] echo %choicecount%. choicetext[%choicecount%]&set "choices=%choices%%choicecount%"
if %choicecount% lss 9 goto menunext
echo Q. Quit
choice /c q%choices% /N /M "%~1"
goto :eof
This way, you can set up the available choices in choicetext[?]
(and clear them with
for/f "delims==" %%e in ('set choicetext[ 2^>nul') do set "%%e="
) then display the menu by executing
call :menu "Some message"
When `:menu" returns, you can then
GOTO Someplace%errorlevel%
which will goto someplace2
etc. Note that because q
is always the first character of the choices
, then q
will always return errorlevel 1
, hence the label :whatever1
will mean q was pressed
. That way, you don't need to alter the quit
code should you extend the menu.
(X for eXit works, too.)