모듈:마작패

설명문서 [편집] [역사] [새로고침]

이 모듈은 문서 내에 마작패 이미지를 쉽게 넣기 위해 만들어졌습니다. 마작패 이미지는 그 특성상 여러 이미지를 연달아 이어넣어야 하는데, 미디어위키의 이미지 삽입 문법을 이용해 하나하나 넣게 되면 오류가 발생하기 쉽고, 수정하기 힘들며 위키텍스트를 보았을 때 그 의미를 한 눈에 알아보기 쉽지 않습니다. 이 모듈은 이러한 문제점을 해결하기 위해, 사용자 친화적인 방식으로 마작패 이미지를 넣도록 해 줍니다.

마작패 모듈에는 크게 두 가지 메인 함수와 나머지 보조 함수가 있습니다. 메인 함수 두 가지는 '파싱' 함수와 '출력' 함수입니다.

마작 자체에 대한 자세한 설명은 마작 문서를 참고합니다.이 틀의 상세한 예는 리치마작 문서에서 확인할 수 있으며, 이 틀의 설명 문서를 수정하려면 모듈:마작패/설명문서 문서를 수정합니다.

간단한 사용법[원본 편집]

{{#invoke:마작패|파싱|123456789만}}

마작-1만.png마작-2만.png마작-3만.png마작-4만.png마작-5만.png마작-6만.png마작-7만.png마작-8만.png마작-9만.png

'파싱' 이라는 함수 이름 뒤에 구분자 기호 |를 넣고, 그 뒤에 표기법대로 원하는 마작패를 쓰면 됩니다.

마작패 모듈의 표기법[원본 편집]

모듈:마작패 에서는 간결한 표기를 위해 각 마작패의 이름에서 한글자씩을 따와 대표어로 사용합니다. 특수한 기호를 대표어 앞에 넣어 추가적인 기능을 사용할 수도 있습니다.

수패
만수패는 '만', 통수패는 '통', 삭수패는 '삭' 이라는 대표어를 씁니다. 대표어 앞에 숫자를 1부터 9까지 쓰며, 숫자 사이에 대표어를 쓸 필요는 없습니다.
111222333444만
자패
자패는 바람패와 삼원패를 각각 '동남서북백발중' 이라는 대표어로 대신합니다.
적도라
적도라는 수패 5에만 있으며, '적5'라는 대표어를 적어 표시합니다.
1234적56789통
뒷면
깡 등으로 인해 뒷면을 표기해야 할 때는 '뒤'라는 대표어를 적어 표시합니다.
뒤22만뒤
'치', '펑' 등으로 인해 가로로 눕힌 패의 표기
눕혀서 표기해야 하는 패 바로 앞에 - 기호를 적어 표기합니다.
북북-북
소명깡(가깡)을 표기하기 위한 이중 표기
눕혀진 패 두 개가 겹쳐져서 표기해야 하는 패 바로 앞에 / 기호를 적어 표기합니다.
/222삭

파싱 함수[원본 편집]

파싱 함수는 연속된 마작패 이미지를 출력합니다. '파싱'이라는 함수명 뒤에 구분자를 적고, 표기법에 따라 마작패를 적어줍니다. 중간에 띄어쓰기가 있어도 무시하게 됩니다. 다음은 각 상황에 대한 사용법의 예시입니다.

수패 및 적도라
{{#invoke:마작패|파싱|234적5678삭}}
마작-2삭.png마작-3삭.png마작-4삭.png마작-적5삭.png마작-6삭.png마작-7삭.png마작-8삭.png
자패
{{#invoke:마작패|파싱|동남서북백발중}}
마작-동.png마작-남.png마작-서.png마작-북.png마작-백.png마작-발.png마작-중.png
가로로 눕힌 패
입력한 값 실제 표시되는 모습
{{#invoke:마작패|파싱|-345통}}
마작-3통-누움.png마작-4통.png마작-5통.png
{{#invoke:마작패|파싱|발발 -발}}
마작-발.png마작-발.png마작-발-누움.png
가깡을 위한 이중 표기
입력한 값 실제 표시되는 모습
{{#invoke:마작패|파싱|/345통}}
마작-3통-누움.png
마작-3통-누움.png
마작-4통.png마작-5통.png
{{#invoke:마작패|파싱|발발 /발}}
마작-발.png마작-발.png
마작-발-누움.png
마작-발-누움.png
표기법 조합
입력한 값 실제 표시되는 모습
{{#invoke:마작패|파싱|999 123통}}
마작-9통.png마작-9통.png마작-9통.png마작-1통.png마작-2통.png마작-3통.png
{{#invoke:마작패|파싱|북 123만 중}}
마작-북.png마작-1만.png마작-2만.png마작-3만.png마작-중.png
{{#invoke:마작패|파싱|123만적589삭2통}}
마작-1만.png마작-2만.png마작-3만.png마작-적5삭.png마작-8삭.png마작-9삭.png마작-2통.png
{{#invoke:마작패|파싱|999 99 9만}}
마작-9만.png마작-9만.png마작-9만.png마작-9만.png마작-9만.png마작-9만.png

출력 함수[원본 편집]

출력 함수는 파싱 함수의 확장으로, 여러 패를 구분해서 입력해야 하는 경우에 사용합니다. 특히, 펑이나 치, 깡 등을 간단하게 입력하는 데에 최적화되어 있습니다. 파싱 함수와 동일한 요령으로 여러 표기법을 제한없이 적다가, 패의 구분이 필요할 때에 구분 기호 | 를 사용하여 입력하면 됩니다. 표기법 중간에 공백이 입력되면 단순히 무시합니다.

출력 함수에서는 #마작패 모듈의 표기법에 있는 표기법 외에도 펑이나 치, 깡을 위한 추가적인 표기법을 사용할 수 있습니다. 그러나 추가 표기법은 반드시 구분 기호로 분리하여 적어야 합니다.

펑 표기법
'펑'이라는 대표어 뒤에 가져온 패를 적고, 바로 이어서 소괄호 안에 누구에게 가져왔는지(상가, 대가 또는 하가) 적습니다.
{{#invoke:마작패|출력|펑4만 (대가)}}
마작-4만.png마작-4만-누움.png마작-4만.png
치 표기법
'치'라는 대표어 뒤에 가져온 패를 적고, 나머지 두 패를 소괄호 안에 적습니다.
{{#invoke:마작패|출력|치 8삭(79삭)}}
마작-8삭-누움.png마작-7삭.png마작-9삭.png
깡 표기법
'깡'이라는 대표어 뒤에 가져온 패를 적습니다. 안깡인 경우에는 그대로 두고, 타가에게서 받아온 경우에는 펑과 마찬가지로 소괄호 안에 적습니다.
{{#invoke:마작패|출력|깡 발}}
마작-뒤.png마작-발.png마작-발.png마작-뒤.png
{{#invoke:마작패|출력|깡중(하가)}}
마작-중.png마작-중.png마작-중.png마작-중-누움.png
가깡 표기법
파싱 함수의 이중 표기와 유사한 표기법을 사용하며, '펑' 또는 '깡' 대표어 뒤에 / 기호를 사용합니다.
{{#invoke:마작패|출력|펑 /8통 (상가)}}
마작-8통-누움.png
마작-8통-누움.png
마작-8통.png마작-8통.png
{{#invoke:마작패|출력|깡/서(하가)}}
마작-서.png마작-서.png
마작-서-누움.png
마작-서-누움.png
표기법 조합
출력 함수는 표기법을 조합해서 구분자 기호를 사용해 여러 패를 동시에 적을 수 있습니다. 물론, 추가된 펑/치/깡 표기법을 사용하지 않아도 됩니다.
입력한 값 실제 표시되는 모습
{{#invoke:마작패|출력|567만|8888통|백백| 깡 발(상가) |중}}
마작-5만.png마작-6만.png마작-7만.png
 
마작-8통.png마작-8통.png마작-8통.png마작-8통.png
 
마작-백.png마작-백.png
 
마작-발-누움.png마작-발.png마작-발.png마작-발.png
 
마작-중.png
{{#invoke:마작패|출력|깡 동|남남 / 남|깡 서 (대가)|뒤북북뒤|11통}}
마작-뒤.png마작-동.png마작-동.png마작-뒤.png
 
마작-남.png마작-남.png
마작-남-누움.png
마작-남-누움.png
 
마작-서.png마작-서-누움.png마작-서.png마작-서.png
 
마작-뒤.png마작-북.png마작-북.png마작-뒤.png
 
마작-1통.png마작-1통.png
{{#invoke:마작패|출력|깡4만(대가)|123 만|9 통|펑 /4만(상가)}}
마작-4만.png마작-4만-누움.png마작-4만.png마작-4만.png
 
마작-1만.png마작-2만.png마작-3만.png
 
마작-9통.png
 
마작-4만-누움.png
마작-4만-누움.png
마작-4만.png마작-4만.png
{{#invoke:마작패|출력|938삭 726만|깡 9통(하가)}}
마작-9삭.png마작-3삭.png마작-8삭.png마작-7만.png마작-2만.png마작-6만.png
 
마작-9통.png마작-9통.png마작-9통.png마작-9통-누움.png

기타 옵션[원본 편집]

옵션 값을 통해 출력 결과물을 조정하거나 기타 정보를 추가할 수 있습니다. 옵션의 순서는 무관하며, {옵션 이름} = {옵션 값} 형식으로 적습니다.

게임과 자리 표기법
현재 게임의 국 수와 자리를 옵션으로 표기할 수 있습니다. 옵션은 '게임'과 '자리'라는 이름을 사용합니다.
{{#invoke:마작패|출력|23만|444555666통|북북|게임=동1국|자리=남}}
(동1국 남가) 
마작-2만.png마작-3만.png
 
마작-4통.png마작-4통.png마작-4통.png마작-5통.png마작-5통.png마작-5통.png마작-6통.png마작-6통.png마작-6통.png
 
마작-북.png마작-북.png
{{#invoke:마작패|출력|서서|백백백|자리=서|999삭|234만|55통}}
(서가) 
마작-서.png마작-서.png
 
마작-백.png마작-백.png마작-백.png
 
마작-9삭.png마작-9삭.png마작-9삭.png
 
마작-2만.png마작-3만.png마작-4만.png
 
마작-5통.png마작-5통.png
도라와 쯔모, 론패 표기법
각각 '도라'와 '쯔모', '론'이라는 옵션을 사용합니다. 옵션의 순서는 무관합니다. 쯔모와 론 옵션은 동시에 사용할 수 없습니다.
{{#invoke:마작패|출력|서서|북북북|999만|345통|55통|자리=서|쯔모=적5통}}
(서가) 
마작-서.png마작-서.png
 
마작-북.png마작-북.png마작-북.png
 
마작-9만.png마작-9만.png마작-9만.png
 
마작-3통.png마작-4통.png마작-5통.png
 
마작-5통.png마작-5통.png
  쯔모
마작-적5통.png
{{#invoke:마작패|출력|1통|111만|999만|111삭|999삭|론=1통|도라=19만19삭|자리=동|게임=남4국}}
(남4국 동가) 
마작-1통.png
 
마작-1만.png마작-1만.png마작-1만.png
 
마작-9만.png마작-9만.png마작-9만.png
 
마작-1삭.png마작-1삭.png마작-1삭.png
 
마작-9삭.png마작-9삭.png마작-9삭.png
  론
마작-1통.png
 도라
마작-1만.png마작-9만.png마작-1삭.png마작-9삭.png
이미지 크기 조절

size 옵션을 사용하여 이미지의 가로 크기를 조정할 수 있습니다. 현재 업로드된 이미지는 가로 66px, 세로 90px의 이미지로서 이미지의 왜곡이 발생하지 않게 하기 위해서는 소수점이 발생하지 않는 11의 배수로 입력해야 합니다 (반드시 그래야 하는 것은 아닙니다). 기본값은 33입니다.

  • {{#invoke:마작패|출력|123-456만|size=22}}
    마작-1만.png마작-2만.png마작-3만.png마작-4만-누움.png마작-5만.png마작-6만.png
  • {{#invoke:마작패|출력|123-456만|size=37}}
    마작-1만.png마작-2만.png마작-3만.png마작-4만-누움.png마작-5만.png마작-6만.png
  • {{#invoke:마작패|출력|123-456만|size=44}}
    마작-1만.png마작-2만.png마작-3만.png마작-4만-누움.png마작-5만.png마작-6만.png

보조 함수들[원본 편집]

보조 함수는 위 파싱 함수와 출력 함수의 단축키 역할을 합니다. 일반적으로 많이 사용될 것으로 예상되는 형태의 패를 미리 설정해 두었습니다.

입력한 값 실제 표시되는 모습
{{#invoke:마작패|만수패}}
마작-1만.png마작-2만.png마작-3만.png마작-4만.png마작-5만.png마작-6만.png마작-7만.png마작-8만.png마작-9만.png
{{#invoke:마작패|통수패}}
마작-1통.png마작-2통.png마작-3통.png마작-4통.png마작-5통.png마작-6통.png마작-7통.png마작-8통.png마작-9통.png
{{#invoke:마작패|삭수패}}
마작-1삭.png마작-2삭.png마작-3삭.png마작-4삭.png마작-5삭.png마작-6삭.png마작-7삭.png마작-8삭.png마작-9삭.png
{{#invoke:마작패|바람패}}
마작-동.png마작-남.png마작-서.png마작-북.png
{{#invoke:마작패|삼원패}}
마작-백.png마작-발.png마작-중.png
{{#invoke:마작패|자패}}
마작-동.png마작-남.png마작-서.png마작-북.png마작-백.png마작-발.png마작-중.png
연습장이나 사용자 문서에서 틀의 사용이나 수정을 연습할 수 있습니다.
분류는 /설명문서에 넣어주세요.

--[[
--   token 변수는 실제 사용자로부터 입력받는 글자, 또는 화면에 출력되는 글자를
--   정의합니다. 만약 이 모듈을 포크해서 다른 위키로 가져가는 경우 이 부분을 필
--   요에 따라 다르게 수정하면 됩니다.
--]]
local token = {
-- mw 파일 표기 prefix--
	file_header = '파일:마작-',
	img_side = '-누움',
	ext = '.png',

-- 수패 --
	man = '만', pin = '통', sou = '삭',

-- 자패 --
	E = '동', S = '남', W = '서', N = '북',
	white = '백', green = '발', red = '중',

-- 꽃패 --
	f1 = '춘', f2 = '하', f3 = '추', f4 = '동',
	f5 = '매', f6 = '난', f7 = '국', f8 = '죽',

-- 펑, 치, 깡 --
	pon = '펑', chi = '치', kan = '깡',
	left = '상가', face = '대가', right = '하가',

-- 뒷면 --
	back = '뒤',

-- 특수표기 --
	dora = '적',
	side = '-',
	double = '/',

-- 쯔모, 론, 도라, 게임 등의 옵션들 --
	tsumo_ = '쯔모',
	ron_ = '론',
	dora_ = '도라',
	wind_ = '자리',
	side_ = '가',
	game_ = '게임',

-- 에러메시지 --
	error = {
		default = "에러가 발생했습니다. 구문을 확인해주세요",
		nofunct = "알 수 없는 함수가 호출되었습니다",
		body = "패가 잘못되었습니다. 구문을 확인해주세요",
		dir = "알 수 없는 방향입니다. 구문을 확인해주세요",
		braket = "괄호가 없거나 잘못되었습니다. 구문을 확인해주세요"
	},

-- 공백 --
	space = ' '
}

-- 이미지 기본값 --
local image_default_size = 33
local image_real_width = 66
local image_real_height = 90

--[[ 헬퍼 함수들 ]]--
local ustring = mw.ustring
local image_ratio = function (x) return math.floor(x * image_real_height / image_real_width) end

-- switch-case 문을 위한 함수 --
-- from http://lua-users.org/wiki/SwitchStatement --
local function switch (t)
	t.case = function (self, x)
		local f = self[x] or self.default
		if f then
			if type(f) == "function" then
				f(x, self)
			else
				error(tostring(x) .. ":" .. token.error.nofunct)
			end
		end
	end
	return t
end

-- mw용 이미지 문법을 생성해주는 함수 --
local function toImg ( data, width )
	width = '|' .. width .. 'px'
	local result = '[[' .. token.file_header .. data .. token.ext .. width ..'|link=|bottom]]'
	return result
end

-- 에러 출력용 함수 --
local function err ( message, pos, func )
	func = (func ~= nil) and '['..func..'] ' or ''
	pos = (pos ~= nil) and 'p'..pos..': ' or ''
	error(func..pos..message)
end

-- 펑/깡을 위한 방향 체크 --
local pon_dir = {
	[token.left] = 1,
	[token.face] = 2,
	[token.right] = 3
}
local kan_dir = {
	[token.left] = 1,
	[token.face] = 2,
	[token.right] = 4
}

-- forward declaration --
local pre_option
local post_option

--[[ 입력받은 값을 분석하는 메인 함수 ]]--
local function single_parse ( data, options )
	if (data == nil) then err(token.error.default) end

	local result = ""

	-- parser variable --
	local index = 0
	local stack = {}
	local pre = ""
	local side = ""
	local wrapper = false

	clean_stack = function () index = 0 ; stack = {} end
	clean_state = function () pre = "" ; side = "" ; wrapper = false end

	local size = options.size or image_default_size

	local token_parse = {
		default = function (x) return true end
	}

	-- 특수표기 --
	token_parse[token.dora] = function (x) pre = x end
	token_parse[token.side] = function (x) side = token.img_side end
	token_parse[token.double] = function (x) wrapper = true ; side = token.img_side end

	-- 숫자 --
	for i = 1, 9 do
		token_parse[tostring(i)] = function (x)
			index = index + 1
			stack[index] = {}

			-- 필요한 값들을 스택에 넣는다
			stack[index].main = x
			stack[index].pre = pre
			stack[index].side = side
			stack[index].wrapper = wrapper
			clean_state()
		end
	end

	-- 수패 --
	local function numbers (x)
		for i = 1, index do
			local width =  (stack[i].side ~= '') and image_ratio(size) or size
			local caption = (stack[i].pre or '') .. stack[i].main .. x .. (stack[i].side or '')

			if (stack[i].wrapper) then -- 이중 처리
				result = result .. '<div style="display: inline-block;">'
								.. '<div>' .. toImg( caption, width ) .. '</div>'
								.. toImg( caption, width )
								.. '</div>'
			else
				result = result .. toImg( caption, width )
			end
		end
		clean_stack() ; clean_state()
	end
	token_parse[token.man], token_parse[token.pin], token_parse[token.sou] = numbers, numbers, numbers

	-- 자패, 뒷면 --
	local function strings (x)
		local width = (side ~= '') and image_ratio(size) or size

		if (wrapper) then -- 이중 처리
			result = result .. '<div style="display: inline-block;">'
							.. '<div>' .. toImg( x..side, width ) .. '</div>'
							.. toImg( x..side, width )
							.. '</div>'
		else
			result = result .. toImg( x..side, width )
		end
		clean_stack() ; clean_state()
	end
	token_parse[token.E] = strings
	token_parse[token.S] = strings
	token_parse[token.W] = strings
	token_parse[token.N] = strings
	token_parse[token.white] = strings
	token_parse[token.green] = strings
	token_parse[token.red] = strings
	token_parse[token.back] = strings

	-- 꽃패 --
	token_parse[token.f1] = strings
	token_parse[token.f2] = strings
	token_parse[token.f3] = strings
	token_parse[token.f4] = strings
	token_parse[token.f5] = strings
	token_parse[token.f6] = strings
	token_parse[token.f7] = strings
	token_parse[token.f8] = strings
	
	-- switch 문 구성 --
	token_parse = switch(token_parse)

	-- utf8 문자별로 루프 진행 --
	local pos = 0
	while #data > 0 do
		local c = ustring.match(data, ".")
		data = data:sub(#c+1) ; pos = pos + 1

		token_parse:case(c) -- 위 select-case 문에 따라 처리
	end

	return '<div class="majong" style="display:inline-block;">'..result..'</div>'
end

local function parse ( frame ) -- '파싱' 함수 entry point
	return pre_option(frame.args) .. single_parse( frame.args[1]:match("^%s*(.-)%s*$"), frame.args ) .. post_option(frame.args) -- trim
end

local function single_print ( data, options )
	if (data == nil) then err(token.error.default) end
	local pos = 1

	local op = ustring.match(data, ".") or ''
	pos = pos + #op
	local caption = ''

	-- 치 --
	if (op == token.chi) then
		data = data:sub(#op+1)
		local body = ustring.match(data, "%s*(%d?.)") or ''
		if (#body == 0) then err(token.error.body, pos, token.chi) end
		pos = pos + #body

		local tail = ustring.match(data, ".*%((.-)%)") or '' -- 괄호 부분 체크
		if (#tail == 0) then err(token.error.braket, pos, token.chi) end
		pos = pos + #tail

		caption = token.side .. body .. tail -- 치는 반드시 상가에게만 받게됨

	-- 펑 --
	elseif (op == token.pon) then
		data = data:sub(#op+1)
		local body = ustring.match(data, "%s*(/?%d?.)") or ''
		if (#body == 0) then err(token.error.body, pos, token.pon) end
		pos = pos + #body

		local tail = ustring.match(data, ".*%((.-)%)") or '' -- 괄호 부분 체크
		if (#tail == 0) then err(token.error.braket, pos, token.pon) end
		pos = pos + #tail

		-- 가깡 처리 --
		local selector = token.side
		if (body:sub(1, 1) == '/') then
			body = body:sub(2)
			selector = token.double
		end

		-- 방향에 맞게 캡션 처리 --
		local dir = pon_dir[tail] or -1
		if (dir == -1) then err(token.error.dir, pos, token.pon) end
		for i = 1, 3 do
			if (i == dir) then caption = caption .. selector end
			caption = caption .. body
		end

	-- 깡 --
	elseif (op == token.kan) then
		data = data:sub(#op+1)
		local body = ustring.match(data, "%s*(/?%d?.)") or ''
		if (#body == 0) then err(token.error.body, pos, token.kan) end
		pos = pos + #body

		local tail = ustring.match(data, "%s*%((.-)%)") or '' -- 괄호 부분 체크
		pos = pos + #tail

		-- 안깡 --
		if (#tail == 0) then
			caption = token.back .. body .. body .. token.back

		-- 가깡 --
		elseif (body:sub(1, 1) == '/') then
			local dir = pon_dir[tail] or -1
			if (dir == -1) then err(token.error.dir, pos, token.kan) end
			body = body:sub(2)

			for i = 1, 3 do
				if (i == dir) then caption = caption .. token.double end
				caption = caption .. body
			end

		-- 대명깡 --
		else
			local dir = kan_dir[tail] or -1
			if (dir == -1) then err(token.error.dir, pos, token.kan) end

			for i = 1, 4 do
				if (i == dir) then caption = caption .. token.side end
				caption = caption .. body
			end
		end

	-- 기타 --
	else
		caption = data
	end

	return single_parse(caption, options)
end

local function print ( frame ) -- '출력' 함수 entry point
	local result = ''
	local data = {}

	for k, line in pairs(frame.args) do -- 옵션값을 제외한 나머지 입력값들을 data에 모음
		if (type(k) == "number") then data[k] = line end
	end

	for i = 1, #data do
		result = result .. single_print( data[i]:match("^%s*(.-)%s*$"), frame.args ) -- trim
		if (i ~= #data) then result = result .. token.space end
	end

	return pre_option(frame.args) .. result .. post_option(frame.args)
end

--[[ 옵션 출력을 위한 보조 함수 ]]--
pre_option = function (options)
	local result = ''

	-- 게임 옵션 출력 --
	if  (options[token.game_] ~= nil) then
		result = options[token.game_]
	end

	-- 자리 출력 --
	if (options[token.wind_] ~= nil) then
		if (result ~= '') then result = result .. token.space end
		result = result .. options[token.wind_] .. token.side_
	end

	if (result ~= '') then result = '(' .. result .. ')' .. token.space end

	return '<div class="majong-group" style="white-space:nowrap;overflow-x:auto;">' .. result
end

post_option = function (options)
	local result = ''

	-- 화료패 출력 --
	if (options[token.tsumo_] ~= nil) then
		result = token.space .. token.tsumo_ .. single_parse(options[token.tsumo_], options)
	elseif (options[token.ron_] ~= nil) then
		result = token.space .. token.ron_ .. single_parse(options[token.ron_], options)
	end

	-- 도라패 출력 --
	if (options[token.dora_] ~= nil) then
		if (result ~= '') then result = result .. token.space end
		result = result .. token.dora_ .. single_parse(options[token.dora_], options)
	end

	if (result ~= '') then result = token.space .. result end

	return result .. '</div>'
end

return {
	['파싱'] = parse,
	['출력'] = print,

-- 자주 쓰이는 함수들 --
	['만수패'] = function (f) return single_parse( "123456789만", f.args ) end,
	['통수패'] = function (f) return single_parse( "123456789통", f.args ) end,
	['삭수패'] = function (f) return single_parse( "123456789삭", f.args ) end,
	['자패'] = function (f) return single_parse( "동남서북백발중", f.args ) end,
	['바람패'] = function (f) return single_parse( "동남서북", f.args ) end,
--  ['꽃패'] = function (f) return single_parse( "춘하추동매난국죽", f.args ) end,
	['삼원패'] = function (f) return single_parse( "백발중", f.args ) end
}