当我运行它时,这个卡片组脚本总是从同一张卡片开始,但是其余的则会随机播放。如何调整它以便第一张卡片总是不同?
@echo off
title
setlocal enabledelayedexpansion
set a=0
set e=52
set f=0
for %%a in (2 3 4 5 6 7 8 9 10 J Q K A) do call :a "%%a"
goto c
:a arg1
set b= %~1
for %%b in (%~1D%b%C%b%H%b%S) do call :b "%%b"
exit /b 0
:b arg1
set /a a=a+1
set Card%a%=%~1
exit /b 0
:c
set /a c=%random%*%e%/32768+1
set d=!Card%c%!
set /a f=%f%+1
echo Card #%f%: %d%
echo.
pause
cls
set Card%c%=!Card%e%!
set /a e=%e%-1
if %e% neq 0 goto c
exit
答案 0 :(得分:2)
尝试
setlocal EnableDelayedExpansion
set d=!Card%c%!
你会想要写一些像%Card%c %%的东西,但这显然不起作用,因为你将得到(不存在的)变量'Card'的内容,一个常量'c'和一个不变 '%'。
!
是%
的替代,用于表示变量。它用于“延迟扩展”。这基本上导致在执行时而不是解析时评估变量。这里有更详细的解释:http://ss64.com/nt/delayedexpansion.html
现在,延迟不是 重要,因为解析器可以从内到外评估变量。但问题是它不知道%符号表示内部变量。它只是认为它是变量'Card'的结束。因此,通过使用两个不同的字符,您可以帮助解析器了解正在发生的事情。
但要实现这一点,您需要启用延迟扩展,这就是第一行所做的。
答案 1 :(得分:2)
我不会使用数组来表示卡片。相反,我会使用一个包含空格分隔的卡片列表的变量。然后通过子串操作和随机位置编号轻松选择随机卡。每次选择卡片时都会缩短卡座。通过这种方式,总是可以从那些仍然可用的卡中随机挑选一张随机卡。
这里有一些简单的例程来构建一副牌,然后将牌组洗牌。套装和值是参数化的,因此很容易构建各种类型的套牌。应该很容易添加例程来处理手牌,抽牌等等。
@echo off
setlocal enableDelayedExpansion
call :buildDeck "D C H S" "2 3 4 5 6 7 8 9 J Q K A"
echo deck=%deck%
call :shuffleDeck
echo shuffledDeck=%deck%
exit /b
:buildDeck suitList valueList
set "deck="
set "deckSize=0"
for %%S in (%~1) do for %%C in (%~2) do (
set "deck=!deck!%%C%%S "
set /a deckSize+=1
)
exit /b
:shuffleDeck
setlocal
set "shuffled="
for /l %%N in (%deckSize% -1 1) do (
set /a "pos=!random! %% %%N * 3, rest=pos+3"
for /f "tokens=1,2" %%A in ("!pos! !rest!") do (
set "shuffled=!shuffled!!deck:~%%A,3!"
set "deck=!deck:~0,%%A!!deck:~%%B!"
)
)
endlocal & set "deck=%shuffled%"
exit /b
更新(现已调试)
Woops - 我忘了10.正如OP建议的那样,我可以使用T代表10,但这并不理想。我可以使用10,然后根据需要添加额外的空格,让每张卡片代表4个字符而不是3个,但我选择恢复为初始卡片定义的数组,然后是洗牌的牌组和牌的字符串。我还添加了处理,丢弃和绘制卡片的例程。要将它变成功能性游戏还有很多工作要做,但这足以让你朝着正确的方向前进。
@echo off
setlocal enableDelayedExpansion
:: Define and shuffle deck and show result
echo Shuffle deck
call :defineCards "D C H S" "2 3 4 5 6 7 8 9 10 J Q K A"
call :shuffleDeck
echo deck=%deck%
echo(
pause
echo(
:: Deal 5 cards to 4 players
echo deal
call :deal "player1 player2 player3 player4" 5
:: show result
set player
echo deck=%deck%
echo(
pause
echo(
:: Have player1 discard the 1st and 3rd cards by value.
:: First get the list of cards to discard programatically, but it could be via user input
for /f "tokens=1,3" %%A in ("!player1!") do set "discard=%%A %%B"
:: Now discard the cards and show the result
echo Player1 discards %discard%
call :discard player1 "%discard%"
set player
echo deck=%deck%
echo(
pause
echo(
:: Have player1 draw 2 cards and show result
echo Player1 draws 2 cards
call :draw player1 2
set player
echo deck=%deck%
echo(
echo That's all for now :-)
exit /b
:defineCards suitList valueList
for %%S in (%~1) do for %%C in (%~2) do (
set /a card.count+=1
set "card.!card.count!=%%C%%S"
)
exit /b
:shuffleDeck
setlocal
set "deck="
for /l %%N in (%card.count% -1 1) do (
set /a "R=!random! %% %%N + 1, card.count-=1"
for %%I in (!R!) do set "deck=!deck! !card.%%I!"
for /l %%I in (!R! 1 !card.count!) do (
set /a "J=%%I+1"
for %%J in (!J!) do set "card.%%I=!card.%%J!"
)
)
endlocal & set "deck=%deck%"
exit /b
:deal playerList cardCount
for /l %%N in (1 1 %2) do for %%P in (%~1) do (
for /f "tokens=1*" %%A in ("!deck!") do (
set "%%P=!%%P! %%A"
set "deck=%%B"
)
)
exit /b
:discard player cardList
for %%C in (%~2) do set "%1=!%1: %%C=!"
exit /b
:draw player cardCount
for /l %%N in (1 1 %2) do for /f "tokens=1*" %%A in ("!deck!") do (
set "%1=!%1! %%A"
set "deck=%%B"
)
- 样本输出 -
Shuffle deck
deck= JC 2C 9H 9S QC 5C 4S AC KD 7S 8C 10D 10H 5S 3S 3C AD 10C 10S 4H 7C 4C AH QS 2H QH 7D KH 6H KC 4D 6D 8S 9C 8D JD 6C JS 7H 3H 3D 2S JH KS 9D 6S AS 5H 2D 5D 8H QD
Press any key to continue . . .
deal
player1= JC QC KD 10H AD
player2= 2C 5C 7S 5S 10C
player3= 9H 4S 8C 3S 10S
player4= 9S AC 10D 3C 4H
deck=7C 4C AH QS 2H QH 7D KH 6H KC 4D 6D 8S 9C 8D JD 6C JS 7H 3H 3D 2S JH KS 9D 6S AS 5H 2D 5D 8H QD
Press any key to continue . . .
Player1 discards JC KD
player1= QC 10H AD
player2= 2C 5C 7S 5S 10C
player3= 9H 4S 8C 3S 10S
player4= 9S AC 10D 3C 4H
deck=7C 4C AH QS 2H QH 7D KH 6H KC 4D 6D 8S 9C 8D JD 6C JS 7H 3H 3D 2S JH KS 9D 6S AS 5H 2D 5D 8H QD
Press any key to continue . . .
Player1 draws 2 cards
player1= QC 10H AD 7C 4C
player2= 2C 5C 7S 5S 10C
player3= 9H 4S 8C 3S 10S
player4= 9S AC 10D 3C 4H
deck=AH QS 2H QH 7D KH 6H KC 4D 6D 8S 9C 8D JD 6C JS 7H 3H 3D 2S JH KS 9D 6S AS 5H 2D 5D 8H QD
That's all for now :-)
答案 2 :(得分:1)
如果这些命令:
set /a c=%random%*52/32768+1
set d=!Card%c%!
放在for
循环或if
命令中,然后你必须使用:
set /a c=!random!*52/32768+1
for %%c in ("!c!") do set d=!Card%%~c!
与上一个答案中给出的原因相同......
答案 3 :(得分:1)
试图让第一张卡随机?试试这个......
@echo off
title
rem %random%
setlocal enabledelayedexpansion
set a=0
set e=52
set f=0
for %%a in (2 3 4 5 6 7 8 9 10 J Q K A) do call :a "%%a"
goto c
:a arg1
set b= %~1
for %%b in (%~1D%b%C%b%H%b%S) do call :b "%%b"
exit /b 0
:b arg1
set /a a=a+1
set Card%a%=%~1
exit /b 0
:c
set /a c=%random%*%e%/32768+1
set d=!Card%c%!
set /a f=%f%+1
echo Card #%f%: %d%
echo.
pause
cls
set Card%c%=!Card%e%!
set /a e=%e%-1
if %e% neq 0 goto c
exit
我只是输入“rem%random%”。瞧。