Проблема со связанными if-операторами в Batch - PullRequest
0 голосов
/ 23 июня 2019

Я работаю над воссозданием The Elder Scrolls III: Morrowind в Batch, и в настоящее время я программирую создание персонажа, которое включает определение базовой статистики игрока по расе и полу. Я последовательно соединял операторы if, чтобы требовать двух условий, которые должны быть выполнены при выборе атрибута. Однако каждый раз, когда выбираются раса и пол, второе условие всегда игнорируется, и атрибут устанавливается, как и должно быть, если персонаж является мужчиной. Я полагаю, что я могу совершить простую ошибку где-то здесь (как я часто делаю). Вот полный код на случай, если я допустил ошибки где-то неожиданно:

@echo off
:start
title Morrowind Build 6-21-19
echo Choose your character's race.
echo.
echo 1. Altmer
echo 2. Argonian
echo 3. Bosmer
echo 4. Breton
echo 5. Dunmer
echo 6. Imperial
echo 7. Khajiit
echo 8. Nord
echo 9. Orc
echo 10. Redguard
set /p p.race=
if %p.race%==1 set p.race=altmer
if %p.race%==2 set p.race=argonian
if %p.race%==3 set p.race=bosmer
if %p.race%==4 set p.race=breton
if %p.race%==5 set p.race=dunmer
if %p.race%==6 set p.race=imperial
if %p.race%==7 set p.race=khajiit
if %p.race%==8 set p.race=nord
if %p.race%==9 set p.race=orc
if %p.race%==10 set p.race=redguard
cls
echo Choose your character's gender.
echo.
echo 1. Male
echo 2. Female
choice /c 12 /n
if errorlevel 2 set p.sex=f
if errorlevel 1 set p.sex=m
if %p.race%==altmer if %p.sex%==m set /a p.strength=30
if %p.race%==altmer if %p.sex%==f set /a p.strength=30
if %p.race%==argonian if %p.sex%==m set /a p.strength=40
if %p.race%==argonian if %p.sex%==f set /a p.strength=40
if %p.race%==bosmer if %p.sex%==m set /a p.strength=30
if %p.race%==bosmer if %p.sex%==f set /a p.strength=30
if %p.race%==breton if %p.sex%==m set /a p.strength=40
if %p.race%==breton if %p.sex%==f set /a p.strength=30
if %p.race%==dunmer if %p.sex%==m set /a p.strength=40
if %p.race%==dunmer if %p.sex%==f set /a p.strength=40
if %p.race%==imperial if %p.sex%==m set /a p.strength=40
if %p.race%==imperial if %p.sex%==f set /a p.strength=40
if %p.race%==khajiit if %p.sex%==m set /a p.strength=40
if %p.race%==khajiit if %p.sex%==f set /a p.strength=30
if %p.race%==nord if %p.sex%==m set /a p.strength=50
if %p.race%==nord if %p.sex%==f set /a p.strength=50
if %p.race%==orc if %p.sex%==m set /a p.strength=45
if %p.race%==orc if %p.sex%==f set /a p.strength=45
if %p.race%==redguard if %p.sex%==m set /a p.strength=50
if %p.race%==redguard if %p.sex%==f set /a p.strength=40
if %p.race%==altmer if %p.sex%==m set /a p.intelligence=50
if %p.race%==altmer if %p.sex%==f set /a p.intelligence=50
if %p.race%==argonian if %p.sex%==m set /a p.intelligence=40
if %p.race%==argonian if %p.sex%==f set /a p.intelligence=50
if %p.race%==bosmer if %p.sex%==m set /a p.intelligence=40
if %p.race%==bosmer if %p.sex%==f set /a p.intelligence=40
if %p.race%==breton if %p.sex%==m set /a p.intelligence=50
if %p.race%==breton if %p.sex%==f set /a p.intelligence=50
if %p.race%==dunmer if %p.sex%==m set /a p.intelligence=40
if %p.race%==dunmer if %p.sex%==f set /a p.intelligence=40
if %p.race%==imperial if %p.sex%==m set /a p.intelligence=40
if %p.race%==imperial if %p.sex%==f set /a p.intelligence=40
if %p.race%==khajiit if %p.sex%==m set /a p.intelligence=40
if %p.race%==khajiit if %p.sex%==f set /a p.intelligence=40
if %p.race%==nord if %p.sex%==m set /a p.intelligence=30
if %p.race%==nord if %p.sex%==f set /a p.intelligence=30
if %p.race%==orc if %p.sex%==m set /a p.intelligence=30
if %p.race%==orc if %p.sex%==f set /a p.intelligence=40
if %p.race%==redguard if %p.sex%==m set /a p.intelligence=30
if %p.race%==redguard if %p.sex%==f set /a p.intelligence=30
echo Strength: %p.strength%
echo Intelligence: %p.intelligence%
pause
goto start

Ответы [ 2 ]

0 голосов
/ 23 июня 2019

Как правило, if errorlevel ... строки должны быть в порядке убывания.sst уже указал причину:

Условие, если число уровня ошибки будет выполнено, когда значение уровня ошибки равно или больше, чем число.Таким образом, выполнено условие, если errorlevel 2 также будет удовлетворен, если errorlevel 1

Хотя в этом особом случае проще просто инвертировать этот порядок:

choice /c 12 /n
if errorlevel 1 set "p.sex=m"
if errorlevel 2 set "p.sex=f"

Когда вы нажимаете 1, первый if выполняется, а переменная установлена ​​на m.Второй не выполняется, поэтому переменная остается m.
Когда вы нажимаете 2, выполняется первый if и переменная устанавливается на m.Второй также выполняется, поэтому переменная изменяется на f

Примечание: я изменил синтаксис set на рекомендованную форму, чтобы избежать пробелов (трудно обнаружить в коде, но это может привести кнеожиданное поведение (и некоторая головная боль при устранении неполадок) в других частях кода)

Еще одно предложение: для читабельности вы можете заменить

if %p.race%==altmer if %p.sex%==m 

на

if "%p.race%-%p.sex%"=="altmer-m"

и set /a может установить несколько переменных, поэтому вы можете сократить свой код с помощью:

if "%p.race%-%p.sex%"=="altmer-m" set /a p.strength=30, p.intelligence=50

и - когда у мужчин и женщин одинаковые свойства - вы можете сделать их в одной строке (хотя могут быть причиныне делать этого - например, оставить возможность изменить свойства позже, не слишком сильно изменяя код):

if "%p.race%"=="altmer" set /a p.strength=30, p.intelligence=50
0 голосов
/ 23 июня 2019

Проблема заключается в том, что вы проверили значение errorlevel после команды chioce:

choice /c 12 /n
if errorlevel 2 set p.sex=f
if errorlevel 1 set p.sex=m

Условие if errorlevel number будет выполнено, если значение errorlevel равно , равному или превышающему число. Таким образом, удовлетворенное условие if errorlevel 2 также удовлетворит if errorlevel 1

Вам необходимо исключить последующие условия из оценки с помощью конструкции if...else и начать проверку errorlevel от наивысшего до наименьшего значения.

choice /c 12 /n
if errorlevel 2 (
    set p.sex=f
) else if errorlevel 1 (
    set p.sex=m
) else (
   REM user canceled the choice by pressing CTRL-C
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...