모듈:Random
둘러보기로 이동
검색으로 이동
난수를 다루는 lua함수를 모아둔 모듈입니다.
리버티위키를 비롯한 미디어위키 사이트는 구문분석기 캐싱이 허용되어 있기에 별도의 설정을 거치지 않으면 아무리 새로고침을 해도 같은값이 나오게끔 되어있습니다.
해당 모듈을 래핑하는 틀을 만들거나 {{#invoke:random}}
를 사용하는 문서에 {{캐싱방지}}를 추가해주세요.
rand
- 이 부분의 본문은 틀:rand입니다.
choose
- 이 부분의 본문은 틀:choose입니다.
lotto
{{#invoke:random|lotto|a|b}}일 때, 1부터 b까지의 자연수 중 a개를 중복 없이 추출합니다.
사용법
파라미터별 설명
{{#invoke:random|lotto|추출할 표본수|전체갯수|추출할 보너스 갯수|표본 구분자|보너스 구분자|정렬 여부}}
파라미터 기본값
{{#invoke:random|lotto|6|45|1|, | + |true}}
예시
기본 예시
code_blocks 코드
{{#invoke:random|lotto}}
code
description 결과
1, 3, 10, 12, 28, 39 + 2
보너스를 추출하지 않는 예시
code_blocks 코드
{{#invoke:random|lotto|||0}}
code
description 결과
3, 8, 10, 18, 36, 40
0부터 10까지 숫자를 랜덤나열한 예시
code_blocks 코드
{{#invoke:random|lotto|10|10|0|-||false}}
code
description 결과
5-6-10-1-9-3-7-4-8-2
sample
가중치를 설정할 수 없고 문자열로 구분 가능한 choose입니다.
사용법
파라미터별 설명
{{#invoke:random|sample|텍스트|구분할 문자열}}
파라미터 기본값
{{#invoke:random|sample||,}}
예시
기본 예시
code_blocks 코드
{{#invoke:random|sample|1,2,3,4,5}}
code
description 결과
3
구분자를 변경하는 예시
code_blocks 코드
{{#invoke:random|sample|1-2-3-4-5|-}}
code
description 결과
2
특정 분류의 랜덤 게임을 출력하는 예시
code_blocks 코드
{{#invoke:random|sample|{{#dpl:|category=함정 피하기 게임|namespace|format=,%PAGE%//}}|//}}
code
description 결과
위 설명은 모듈:Random/설명문서의 내용을 가져와 보여주고 있습니다. (편집 | 역사) 이 모듈에 대한 수정 연습과 시험은 연습장 (만들기 | 미러)과 시험장 (만들기)에서 할 수 있습니다. 분류는 /설명문서에 넣어주세요. 이 모듈에 딸린 문서. |
local p = {}
function p.randomseed()
return math.floor(os.time() * os.clock() % 1000000)
end
function p._rand(m, n, o)
local seed, key
if type(m) == "table" then
seed = tonumber(m.seed)
key = tonumber(m.key)
m = nil
n = nil
elseif type(n) == "table" then
seed = tonumber(n.seed)
key = tonumber(n.key)
m = tonumber(m)
n = nil
elseif type(o) == "table" then
seed = tonumber(o.seed)
key = tonumber(o.key)
m = tonumber(m)
n = tonumber(n)
else
m = tonumber(m)
n = tonumber(n)
end
if (seed or 0) == 0 then
seed = p.randomseed()
elseif (key or 0) ~= 0 then
seed = seed * (key or p.randomseed())
end
math.randomseed(seed)
return math.random(unpack{m, n})
end
function p.rand(frame)
return p._rand(frame.args[1], frame.args[2], frame.args)
end
function p._choose(frame)
local len = 0
for index, value in ipairs(frame.args) do
len = index
end
return frame.args[p._rand(len, frame.args)]
end
function p.choose(frame)
return p._choose(frame:getParent())
end
-- 테이블을 문자열로 변환
function p.str_join(list, delimiter)
local len = #list
if len == 0 then
return ""
end
local string = list[1]
for i = 2, len do
string = string .. delimiter .. list[i]
end
return string
end
-- 테이블의 일부를 추출
function p.table_slice(arr,start,stop)
local res = {}
local n = #arr
start = start or 1
stop = stop or n
-- 음수
if start < 0 then
start = n + start + 1
end
if stop < 0 then
stop = n + stop + 1
end
-- start보다 stop이 큰 경우
if stop < start then
stop = start
end
-- 루프
for i = start, stop, 1 do
res[#res+1] = arr[i]
end
return res
end
-- n개의 숫자를 무작위로 뽑아서 반환
function p._sampling(n, total)
local numbers = {}
for i = 1, total do
numbers[i] = i
end
-- 숫자를 무작위로 섞기
math.randomseed(p.randomseed())
for i = total, 1, -1 do
local r = math.random(i)
numbers[i], numbers[r] = numbers[r], numbers[i]
end
-- 처음 n개 숫자 선택
local sampled = {}
for i = 1, n do
table.insert(sampled, numbers[i])
end
return sampled
end
-- {{#invoke:random|lotto}}
function p.lotto(frame)
local n = tonumber(frame.args[1]) or 6
local total = tonumber(frame.args[2]) or 45
local bonus = tonumber(frame.args[3]) or 1
local sep = frame.args[4] or ", "
local bonusSep = frame.args[5] or " + "
local sort = frame.args[6] or "true"
if n and total and n <= total and n > 0 then
local allNums = p._sampling(n + bonus, total)
-- 추출한 숫자들 중 n개 추출 및 정렬
local nums = p.table_slice(allNums, 1, n)
if sort == "true" then
table.sort(nums)
end
-- bonus만큼 추출
local bonusNums = p.table_slice(allNums, n + 1, n + bonus)
if sort == "true" then
table.sort(bonusNums)
end
-- 문자열로 변환
local result = p.str_join(nums, sep)
-- 보너스 번호가 있으면 추가
if bonus > 0 then
result = result .. bonusSep .. p.str_join(bonusNums, sep)
end
return result
else
return "{{색깔|Error: 파라미터가 올바르지 않습니다. 1 <= n <= total를 만족해야 합니다.|red}}"
end
end
-- text에서 sep로 구분된 문자열 중 하나를 무작위로 반환합니다. 각 항목의 앞뒤 공백은 제거됩니다.
function p.sample(frame)
local text = frame.args[1] or ""
local sep = frame.args[2] or "," -- 기본 구분자는 콤마입니다.
-- sep로 문자열을 분할하여 테이블로 변환하고 앞뒤 공백 제거
local items = {}
for item in mw.text.gsplit(text, sep, true) do
local trimmedItem = mw.text.trim(item) -- 앞뒤 공백 제거
table.insert(items, trimmedItem)
end
-- 테이블에서 무작위로 하나의 항목을 선택하여 반환
local index = p._rand(1, #items)
return items[index]
end
return p