2014-08-29 32 views
2

我正在製作一個小腳本,將角色分配爲一種應用程序。它要求的人數,然後隨機運行,看看你是什麼角色。 像這樣:使用隨機設置值並防止再次給出值?

: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 

回答

1

你要找的算法是一個洗牌。把你的角色想象成一副撲克牌 ,每張牌只有一個角色。如果你正在和別人玩遊戲,你可以洗牌,然後把一張牌交給每個人。

研究下面的代碼,它聲明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. 
0
@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列表爲空,並且全部完成...