Исходное решение Aacini эффективно, однако оно может поддерживать максимум 31 возможное значение, потому что FOR / F не может читать более 31 токенов. EDIT - его второе решение устранило ограничение.
Ниже приведено аналогичное понятие, которое использует постоянную ширину для чисел в списке. Это позволяет мне легко использовать операции подстроки для извлечения случайно выбранных значений и для удаления каждого значения из списка.
Как написано, это решение поддерживает значения от 0 до 9999 с максимальным количеством возможных значения & lt; = 1354.
Я использовал очень похожую стратегию для управления случайным размещением продуктов в моей игре SNAKE.BAT . Мне нужно было отслеживать все пустые места в игровом поле и случайным образом выбирать новое расположение продуктов из этого списка.
@echo off
setlocal enableDelayedExpansion
:: This script has the following limitations:
:: RND_MIN >= 0
:: RND_MAX <= 9999
:: ((RND_MAX - RND_MIN + 1) / RND_INTER) <= 1354
::
set "RND_MIN=1"
set "RND_MAX=10"
set "RND_INTER=1"
set "RND_TOTAL=8"
set /a cnt=(RND_MAX - RND_MIN + 1) / RND_INTER
:: Define a string containing a space delimited list of all possible values,
:: with each value having 10000 added
set "pool="
set /a "beg=RND_MIN+10000, end=RND_MAX+10000, cnt=(RND_MAX-RND_MIN+1)/RND_INTER"
for /l %%N in (%beg% %RND_INTER% %end%) do set "pool=!pool!%%N "
:: Build the randomly sequenced array of numbers
for /l %%N in (1 1 %RND_TOTAL%) do (
%= Randomly select a value from the pool of all possible values =%
%= and compute the index within the string, as well as the index =%
%= of the next value =%
set /a "loc=(!random!%%cnt)*6, next=loc+6"
%= Transfer the index values to FOR variables =%
for %%A in (!loc!) do for %%B in (!next!) do (
%= Assign the selected value to the output array =%
set /a "RND_NUM[%%N]=!pool:~%%A,5!-10000"
%= Remove the value from the pool =%
set "pool=!pool:~0,%%A!!pool:~%%B!"
set /a cnt-=1
)
)
:: Display the results
for /l %%N in (1 1 %RND_TOTAL%) do echo !RND_NUM[%%N]!