使用随机设置值并防止再次给出值?
我正在制作一个小脚本,将角色分配为一种应用程序。它要求的人数,然后随机运行,看看你是什么角色。 像这样:使用随机设置值并防止再次给出值?
:mrole
set/a player1=%random% * 4/32768 + 1
if %player1%==1 set 1role=Murderer
但如果我只希望人们一定比例获得了一定的作用是什么?说1:4是凶手。如果我为8名球员做这样的事情,如果他们中有6人是杀人犯呢?如果我想再次遇到8人的侦探角色呢?目前我所买的是29行!有没有比检查是否有太多时间更快的方法?而侦探检查也将会很长!
我有这么远低于这里是一个链接:http://pastebin.com/g2GfN7v9
@echo off
:new
set test=2
:main
cls
echo Trouble in Murder Town
echo --------------------------
echo.
echo 1. Start
echo 2. Tester Options
echo 3. Quit
echo.
set/p m=
if %m%==1 goto start
if %m%==2 goto testrat
if %m%==3 exit
goto main
:testrat
cls
echo Chance to have a tester
echo -----------------------
echo Currently a 1 in %test% chance to have a tester in a game
echo.
echo 1. Always
echo 2. Never
echo 3. 1/2 (default)
echo 4. 1/3
echo 5. 1/4
echo 6. 1/5
echo 7. Back
echo.
set/p t=
if %t%==1 set test=1
if %t%==2 set test=0
if %t%==3 set test=2
if %t%==4 set test=3
if %t%==5 set test=4
if %t%==6 set test=5
if %t%==7 goto options
goto testrat
:start
cls
echo How many players not including the one at the computer?
echo.
echo 1. 3
echo 2. 4
echo 3. 5
echo 4. 6
echo 5. 7
echo 6. 8
echo 7. Quit
echo.
set/p t=
if %t%==1 set players=3
if %t%==2 set players=4
if %t%==3 set players=5
if %t%==4 set players=6
if %t%==5 set players=7
if %t%==6 set players=8
if %t%==1 goto names
if %t%==2 goto names
if %t%==3 goto names
if %t%==4 goto names
if %t%==5 goto names
if %t%==6 goto names
if %t%==7 goto main
goto start
:names
cls
echo Please enter their names.
echo.
set/p player1=Player 1:
echo.
set/p player2=Player 2:
echo.
set/p player3=Player 3:
echo.
if %players%==8 (
set/p player4=Player 4:
echo.
set/p player5=Player 5:
echo.
set/p player6=Player 6:
echo.
set/p player7=Player 7:
echo.
set/p player8=Player 8:
goto role
) else if %players%==7 (
set/p player4=Player 4:
echo.
set/p player5=Player 5:
echo.
set/p player6=Player 6:
echo.
set/p player7=Player 7:
goto role
) else if %players%==6 (
set/p player4=Player 4:
echo.
set/p player5=Player 5:
echo.
set/p player6=Player 6:
goto role
) else if %players%==5 (
set/p player4=Player 4:
echo.
set/p player5=Player 5:
goto role
) else if %players%==4 (
set/p player4=Player 4:
goto role
) else goto role
:role
set 1role=0
set 2role=0
set 3role=0
set 4role=0
set 5role=0
set 6role=0
set 7role=0
set 8role=0
set murderers=0
set detectives=0
goto mrole
:mrole
set/a player1=%random% * 4/32768 + 1
if %player1%==1 set 1role=Murderer
if %player1%==1 set/a murderers=%murderers% + 1
if %player1%==1 set mcheck=y
if %player1% neq 1 set mcheck=n
if %mcheck%==y if %players% lss 8 goto drole
set/a player2=%random% * 4/32768 + 1
if %murderers%==1 if %players%==8 if %player2%==1 set 2role=Murderer
if %mcheck%==y if %players% lss 8 goto drole
set/a player3=%random% * 4/32768 + 1
if %murderers%==1 if %players%==8 if %player3%==1 set 3role=Murderer
if %mcheck%==y if %players% lss 8 goto drole
set/a player4=%random% * 4/32768 + 1
if %mcheck%==y if %players% lss 8 goto drole
if %murderers%==1 if %players%==8 if %player4%==1 set 4role=Murderer
set/a player5=%random% * 4/32768 + 1
if %mcheck%==y if %players% lss 8 goto drole
if %murderers%==1 if %players%==8 if %player5%==1 set 5role=Murderer
set/a player6=%random% * 4/32768 + 1
if %mcheck%==y if %players% lss 8 goto drole
if %murderers%==1 if %players%==8 if %player6%==1 set 6role=Murderer
set/a player7=%random% * 4/32768 + 1
if %mcheck%==y if %players% lss 8 goto drole
if %murderers%==1 if %players%==8 if %player7%==1 set 7role=Murderer
set/a player8=%random% * 4/32768 + 1
if %mcheck%==y if %players% lss 8 goto drole
if %murderers%==1 if %players%==8 if %player8%==1 set 8role=Murderer
if %murderers% lss 1 goto mrole
if %players%==8 if %murderers% lss 2 goto mrole
:drole
if %players%==8 (
) else if %players lss 8 goto irole
:irole
if 1role==0 set 1role=Innocent
if 2role==0 set 2role=Innocent
if 3role==0 set 3role=Innocent
if 4role==0 set 4role=Innocent
if 5role==0 set 5role=Innocent
if 6role==0 set 6role=Innocent
if 7role==0 set 7role=Innocent
if 8role==0 set 8role=Innocent
你要找的算法是一个洗牌。把你的角色想象成一副扑克牌 ,每张牌只有一个角色。如果你正在和别人玩游戏,你可以洗牌,然后把一张牌交给每个人。
研究下面的代码,它声明4张牌的牌组然后洗牌。 我已经从更传统的编程 语言中将数组的风格命名为数组,但它实际上只是一个约定。我可以用DECK.1, DECK.2, ...
的 表格或其他名称命名它。
我也将程序的部分分离成子程序。有一个子程序 生成一个随机数,打印一个“数组”,洗牌一个数组,并交换数组中的项目。当在批处理中使用数组式间接寻址时,如果不将事情分解为子例程,您将会遇到墙壁问题 。
@echo off
setlocal EnableDelayedExpansion
set "DECK[0]=1H"
set "DECK[1]=2S"
set "DECK[2]=3C"
set "DECK[3]=4D"
set "DECK_SIZE=4"
call :print_array "DECK" %DECK_SIZE%
call :shuffle "DECK" %DECK_SIZE%
echo -----
call :print_array "DECK" %DECK_SIZE%
goto :eof
REM Generate random number from %1 min through %2 max.
:rand
set /a RAND_NUM=%RANDOM% * (%~2 - %~1 + 1)/32768 + %~1
goto :eof
REM %1 Name of array to print
REM %2 Size of the array
:print_array
set /a LAST_INDEX=%~2-1
for /L %%a in (0, 1, %LAST_INDEX%) do (
echo %~1[%%a]: !%~1[%%a]!
)
goto :eof
rem To shuffle an array a of n elements (indices 0..n-1):
rem for i from n − 1 downto 1 do
rem j ← random integer with 0 ≤ j ≤ i
rem exchange a[j] and a[i]
REM %1 Name of array to shuffle
REM %2 Size of the array
:shuffle
set /a LAST_INDEX=%~2-1
for /L %%a in (0, 1, %LAST_INDEX%) do (
call :rand %%a %LAST_INDEX%
call :swap "%~1[%%a]" "%~1[!RAND_NUM!]"
)
goto :eof
REM %1 One of the variables to swap.
REM %2 The other variable to swap.
:swap
set "__tmp=!%~1!"
set "%~1=!%~2!"
set "%~2=!__tmp!"
goto :eof
所以要修改这个代码,你的程序,你想要的球员阵列和阵列 角色。播放器阵列保持不变,并且您洗牌角色数组。
例如,从这个代码
set "PLAYER[0]=Howard"
set "PLAYER[1]=Fred"
set "PLAYER[2]=Robin"
set "PLAYER[3]=Gary"
set PLAYER_SIZE=4
set "ROLE[0]=murderer"
set "ROLE[1]=innocent"
set "ROLE[2]=innocent"
set "ROLE[3]=detective"
set "ROLE_SIZE=4"
call :shuffle "ROLE" %ROLE_SIZE%
set /a ROLE_LAST_INDEX=%ROLE_SIZE%-1
for /L %%a in (0, 1, %ROLE_LAST_INDEX%) do (
echo Player !PLAYER[%%a]! is !ROLE[%%a]!.
)
一个输出样本会给你:
Player Howard is detective.
Player Fred is innocent.
Player Robin is murderer.
Player Gary is innocent.
@ECHO OFF
SETLOCAL
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
SET "roles=1234"
SET players=4
:setplayrole
SET /a player=1+(%RANDOM% %% %players%)
IF DEFINED $%player% GOTO setplayrole
SET $%player%=%roles:~-1%&SET "roles=%roles:~0,-1%"
IF DEFINED roles GOTO setplayrole
SET $
GOTO :EOF
下面是可能实现你的目标的一个片段。
但首先,有点商业 - 你必须在你的帖子TIS线:
if %player1%==1 set 1role=Murderer
庵 - 它是可能要做到这一点,但由于批量语法的一个非常,非常糟糕的主意。切勿使用数字启动变量名称。它有巨大的后果,没有一个是好的。
---回到我们的 - 呃,程序...
我不清楚你的困难是否分配角色给玩家的比例,但似乎要在每个角色的比例;保证没有'没有人扮演这个角色'。
对我来说,你要做的是分配一组roles
- 我只是使用1..4的均匀分布。您可能希望有10名玩家,角色分别为1..4和其他玩家,您可以通过将random
角色附加到所需角色的种子来构建roles
字符串。
在建立了游戏角色集之后,您将字符串中的每个角色分配给玩家,并在角色被分配时移除角色。
我使用标准clear out all variables with names starting "$"'
例程;然后分配所需的角色,(如你所愿追加任何额外的),然后循环很简单 - 选择一个随机玩家;如果该玩家已拥有指定的角色,请再次选择。如果不是,只需分配列表中的最后一个角色并删除最后一个角色条目。继续,直到roles
列表为空,并且全部完成...