好的,我正在为学校批量创建一个数学游戏(因为我认为这样会更容易)我在使用 if 语句时遇到了一个奇怪的问题。所以,基本上当我在命令行中输入 2 时,它会转到 if 语句中间的一行,而这个 if 语句位于另一个 if 语句中,它甚至不应该进入这个行。
@echo off
setlocal enabledelayedexpansion
:Start
@echo start game(1) or join game(2) note:game must be started for P2 to join
set /p YN=
IF %YN%==1 (
@echo creating files...
if not exist quizFiles (
md "quizFiles"
)
@echo P1> quizFiles/gameState.txt
@echo 48> quizFiles/cards.txt
@echo.0> quizFiles/P1Score.txt
@echo.0> quizFiles/P2Score.txt
@echo false> quizFiles/P2Joined.txt
set /a gameMode=%RANDOM% %%4
@echo.!gameMode!> quizFiles/gameMode.txt
IF "!gameMode!"=="0" (
set gameMode=LCM
) ELSE IF "!gameMode!"=="1" (
set gameMode=GCF
) ELSE IF "!gameMode!"=="2" (
set gameMode=Muliplication of fractions
) ELSE IF "!gameMode!"=="3" (
set gameMode=Division of fractions
)
@echo.!gameMode!
timeout /t 1 /nobreak > NUL
@echo waiting for other player to join...
set dot="2"
:WP2
set /p P2Joined=<quizFiles/P2Joined.txt
IF NOT "!P2Joined!"=="true" (
timeout /t 2 /nobreak > NUL
@echo waiting...
GOTO WP2
)
@echo joined
:P1G
set /p cardsRemaining=<quizFiles/cards.txt
@echo cards left: !cardsRemaining!
set /p P1Score=<quizFiles/P1Score.txt
@echo P1 has: !P1Score! cards
set /p P2Score=<quizFiles/P2Score.txt
@echo P2 has: !P2Score! cards
set /p currentPlayer=<quizFiles/gameState.txt
@echo It is now !currentPlayer!'s turn
@echo 4 cards chosen
set /p gameMode=<quizFiles/gameMode.txt
IF "!gameMode!"=="0" (
set /a card1=%RANDOM% %%96
set /a card2=%RANDOM% %%96
set /a card3=%RANDOM% %%96
set /a card4=%RANDOM% %%96
)
@echo card1: !card1!
@echo card2: !card2!
@echo card3: !card3!
@echo card4: !card4!
IF "!gameMode!"=="0" (
@echo choose your first card(1-4)
set /p chosenCard1=
@echo choose your second card(1-4)
set /p chosenCard2= <<<< leaks here
@echo what is the LCM of these two cards
set /p userAnswer=
)
GOTO P1G
) ELSE IF %YN%==2 (
@echo joining game...
@echo true> quizFiles/P2Joined.txt
timeout /t 1 /nobreak > NUL
@echo joined
)
PAUSE
答案1
您的脚本中存在一些错误,例如(可能不完整):
(1)如果用户只是ENTER在响应时点击set /p YN=
?,请使用双引号,如下所示IF "%YN%"=="1" (
,或考虑切换到CHOICE
命令它允许从键盘捕获单个按键动作。
(2)为什么用同一个变量gameMode
来存储如此不同的东西?
(3 -重要的echo choose your second card(1-4)
)在带括号的代码块中使用右括号会将其关闭。将其转义为echo … card(1-4^)
或使用其他形式的括号,例如方括号echo … card [1-4]
。
(4 -最重要的)绝不在括号内的命令块内使用:label
nor 。:: label-like comment
()
创建和调用子程序相反,你可以goto
在这样的程序主体中随意发挥。
(5)%RANDOM%
在括号中的命令块中()
计算结果为相同的数字。因此,以下代码片段中的所有、 和card1
都是card2
相同的:card3
card4
IF "!gameMode!"=="0" (
set /a card1=%RANDOM% %%96
set /a card2=%RANDOM% %%96
set /a card3=%RANDOM% %%96
set /a card4=%RANDOM% %%96
)
此外,即使使用!RANDOM!
代替 也%RANDOM%
无法保证不同的值。比较:dragNthCard
下面的过程。
有用的 Dbenham 的评论启发了我玩一下你的代码。这是一份原始草稿(在某种意义上可以工作,但不能完全满足你的目标)。已实施LCM
并GCF
作为发起者的一轮测验P1并加入P2:同样的任务,不同的卡组。
@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
:Start
@echo note:game must be started for P2 to join
CHOICE /C 12Q /M "start game (1) or join game (2) or quit game (Q)"
set "YN=%errorlevel%"
IF errorlevel 3 goto :eof
IF errorlevel 2 (
@echo joining game...
@echo true> quizFiles/P2Joined.txt
timeout /t 1 /nobreak > NUL
@echo joined
) ELSE (
@echo creating files...
if not exist quizFiles md "quizFiles"
@echo P1> quizFiles/gameState.txt
@echo 48> quizFiles/cards.txt
@echo.0> quizFiles/P1Score.txt
@echo.0> quizFiles/P2Score.txt
@echo false> quizFiles/P2Joined.txt
set /a gameMode=%RANDOM% %%4
echo gameMode !gameMode!
@echo.!gameMode!> quizFiles/gameMode.txt
timeout /t 1 /nobreak > NUL
@echo waiting for other player to join...
call :waitToJoin
)
rem commont part for both initiator P1 and joined P2
call :dragCards
REM currently implemented only one round game
REM
REM set /p cardsRemaining=<quizFiles/cards.txt
REM @echo cards left: !cardsRemaining!
REM set /p P1Score=<quizFiles/P1Score.txt
REM @echo P1 has: !P1Score! cards
REM set /p P2Score=<quizFiles/P2Score.txt
REM @echo P2 has: !P2Score! cards
REM set /p currentPlayer=<quizFiles/gameState.txt
REM @echo It is now !currentPlayer!'s turn
REM
@echo 4 cards chosen
set /p gameMode=<quizFiles/gameMode.txt
IF "!gameMode!"=="0" (
set gameModeText=LCM
) ELSE IF "!gameMode!"=="1" (
set gameModeText=GCF
) ELSE IF "!gameMode!"=="2" (
set gameModeText=Multiplication of fractions
) ELSE IF "!gameMode!"=="3" (
set gameModeText=Division of fractions
)
echo gameMode !gameMode! !gameModeText!
set "rightAnswer=nonsens"
IF "!gameMode!"=="0" (
call :Choose2Cards
call :%gameModeText% !chosenCard1! !chosenCard2!
)
IF "!gameMode!"=="1" (
call :Choose2Cards
call :%gameModeText% !chosenCard1! !chosenCard2!
)
IF "!gameMode!"=="3" call :Choose2Cards & rem not implemented yet
IF "!gameMode!"=="4" call :Choose2Cards & rem not implemented yet
IF "%rightAnswer%"=="nonsens" (
echo not implemented yet: %gameModeText%
) else (
If "%userAnswer%"=="%rightAnswer%" (
echo %userAnswer% is right
) ELSE (
echo %userAnswer% is wrong; right answer = %rightAnswer%
)
)
rem PAUSE
:::::::::::::::::::::::::::::::
:::
::: Your script continues here: save score, loop next round etc.
:::
:::::::::::::::::::::::::::::::
ENDLOCAL
goto :eof
:LCM
rem Least common multiple usage: call :lcm <input1> <input2>
rem by https://rosettacode.org/wiki/Least_common_multiple#Batch_File
set "_aux1=%1"
set "_aux2=%2"
:lcmSub
if %2 equ 0 (
set /a rightAnswer = %_aux1%*%_aux2%/%1
rem echo rightAnswer = !rightAnswer!
goto :EOF
)
set /a res = %1 %% %2
call :lcmSub %2 %res%
goto :eof
:GCF
rem Greatest common factor / divisor
rem by https://rosettacode.org/wiki/Greatest_common_divisor#Batch_File
if %2 equ 0 (
set rightAnswer=%1
rem echo rightAnswer = !rightAnswer!
goto :eof
)
set /a res = %1 %% %2
call :gcf %2 %res%
goto :eof
:Muliplication
goto :eof
:Division
goto :eof
:waitToJoin
set dot="2"
:WP2
set /p P2Joined=<quizFiles/P2Joined.txt
IF NOT "!P2Joined!"=="true" (
timeout /t 2 /nobreak > NUL
@echo waiting...
GOTO WP2
)
@echo joined
goto :eof
:dragCards
:P1G
for /L %%N in (1,1,4) do (
call :dragNthCard %%N
echo card%%N: !card%%~N!
)
goto :eof
:Choose2Cards
CHOICE /C 1234 /M "choose your first card "
set "chosenCard1=!card%errorlevel%!"
:Choose2CardsDifferent
CHOICE /C 1234 /M "choose your second card "
set "chosenCard2=!card%errorlevel%!"
If %chosenCard1% EQU %chosenCard2% goto :Choose2CardsDifferent
echo what is the %gameModeText% of these two cards: %chosenCard1% and %chosenCard2%
set /p "userAnswer=%gameModeText%( %chosenCard1%, %chosenCard2%) = "
goto :eof
:dragNthCard
set "_cardNo=%~1"
set /A _cardMax=%_cardNo% - 1
:dragNthAgain
set /a card%_cardNo%=%RANDOM% %%96
for /L %%G in (1,1,%_cardMax%) do (
if !card%_cardNo%! EQU !card%%G! (
timeout /t 1 /nobreak > NUL
goto :dragNthAgain
)
)
rem echo CARD%_cardNo%: !card%_cardNo%!
goto :eof