Skip to content

Commit 79db75e

Browse files
authored
docs: add agari section to wiki, extend shanten section (#219)
* docs: add agari section to wiki, extend shanten section * address pr feedback * few more fixes * few more fixes
1 parent 7415637 commit 79db75e

File tree

3 files changed

+195
-9
lines changed

3 files changed

+195
-9
lines changed

.github/wiki/v2-Chinese.md

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,82 @@ print(result.yaku)
152152

153153
## 向听数计算
154154

155+
向听数表示手牌到达听牌(差一张即可和牌)所需的最少换牌次数。`0` 表示听牌,`-1` 表示手牌已经和牌(完成形)。
156+
157+
`calculate_shanten` 会计算一般形、七对子和国士无双三种形式的向听数,并返回最小值。也可以单独计算每种形式的向听数。
158+
155159
```python
156160
from mahjong.shanten import Shanten
157161
from mahjong.tile import TilesConverter
158162

163+
# 一般形,2向听
159164
tiles = TilesConverter.string_to_34_array(man='13569', pin='123459', sou='443')
160-
result = Shanten.calculate_shanten(tiles)
165+
print("一般形向听数:", Shanten.calculate_shanten(tiles))
166+
167+
# 听牌(0向听,差一张即可和牌)
168+
tiles = TilesConverter.string_to_34_array(sou='111345677', pin='11', man='567')
169+
print("听牌:", Shanten.calculate_shanten(tiles))
170+
171+
# 和牌形(-1向听,已经完成)
172+
tiles = TilesConverter.string_to_34_array(sou='111234567', pin='11', man='567')
173+
print("和牌形:", Shanten.calculate_shanten(tiles))
174+
175+
# 单独计算特定形式的向听数
176+
tiles = TilesConverter.string_to_34_array(sou='114477', pin='114477', man='76')
177+
print("七对子向听数:", Shanten.calculate_shanten_for_chiitoitsu_hand(tiles))
178+
179+
tiles = TilesConverter.string_to_34_array(sou='129', pin='19', man='19', honors='1234567')
180+
print("国士无双向听数:", Shanten.calculate_shanten_for_kokushi_hand(tiles))
181+
```
182+
183+
输出:
184+
185+
```
186+
一般形向听数: 2
187+
听牌: 0
188+
和牌形: -1
189+
七对子向听数: 0
190+
国士无双向听数: 0
191+
```
192+
193+
## 和牌判定
194+
195+
和牌判定检查给定的手牌是否构成完成形(4面子1雀头、七对子或国士无双)。此功能仅验证牌的组合结构,不判断役种或点数。该方法比检查向听数是否为`-1`更快,因此当只需判断手牌是否完成时,建议使用`Agari.is_agari()`
196+
197+
```python
198+
from mahjong.agari import Agari
199+
from mahjong.tile import TilesConverter
200+
201+
# 完成形:123s 456s 789s 123p 33m
202+
tiles = TilesConverter.string_to_34_array(sou='123456789', pin='123', man='33')
203+
print("一般形:", Agari.is_agari(tiles))
204+
205+
# 未完成形:123s 456s 789s 12345p
206+
tiles = TilesConverter.string_to_34_array(sou='123456789', pin='12345')
207+
print("未完成形:", Agari.is_agari(tiles))
208+
209+
# 七对子:1133557799s 1199p
210+
tiles = TilesConverter.string_to_34_array(sou='1133557799', pin='1199')
211+
print("七对子:", Agari.is_agari(tiles))
212+
213+
# 国士无双:19s 19p 199m 1234567z
214+
tiles = TilesConverter.string_to_34_array(sou='19', pin='19', man='199', honors='1234567')
215+
print("国士无双:", Agari.is_agari(tiles))
161216

162-
print(result)
217+
# 包含副露(杠子):1111m 123456789p 22s
218+
tiles = TilesConverter.string_to_34_array(man='1111', pin='123456789', sou='22')
219+
open_set = [0, 0, 0, 0] # 一万的杠子(34牌格式中索引为0)
220+
print("包含副露(杠子):", Agari.is_agari(tiles, [open_set]))
163221
```
164222

165223
输出:
166224

167225
```
168-
2
226+
一般形: True
227+
未完成形: False
228+
七对子: True
229+
国士无双: True
230+
副露手(杠子): True
169231
```
170232

171233
## 青天井规则

.github/wiki/v2-English.md

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,20 +153,82 @@ Output:
153153

154154
## Shanten calculation
155155

156+
Shanten number indicates the minimum number of tile exchanges still required for the hand to reach tenpai (one tile away from winning). A value of `0` means tenpai, and `-1` means the hand is already complete (agari).
157+
158+
`calculate_shanten` returns the minimum shanten across regular hand, chiitoitsu (seven pairs), and kokushi (thirteen orphans) forms. You can also calculate shanten for each form individually.
159+
156160
```python
157161
from mahjong.shanten import Shanten
158162
from mahjong.tile import TilesConverter
159163

164+
# regular hand, 2 shanten
160165
tiles = TilesConverter.string_to_34_array(man='13569', pin='123459', sou='443')
161-
result = Shanten.calculate_shanten(tiles)
166+
print("Regular hand shanten:", Shanten.calculate_shanten(tiles))
167+
168+
# tenpai (0 shanten, one tile away from winning)
169+
tiles = TilesConverter.string_to_34_array(sou='111345677', pin='11', man='567')
170+
print("Tenpai hand:", Shanten.calculate_shanten(tiles))
171+
172+
# complete hand (-1 shanten, already winning)
173+
tiles = TilesConverter.string_to_34_array(sou='111234567', pin='11', man='567')
174+
print("Complete hand:", Shanten.calculate_shanten(tiles))
175+
176+
# calculate shanten for specific hand forms
177+
tiles = TilesConverter.string_to_34_array(sou='114477', pin='114477', man='76')
178+
print("Chiitoitsu shanten:", Shanten.calculate_shanten_for_chiitoitsu_hand(tiles))
179+
180+
tiles = TilesConverter.string_to_34_array(sou='129', pin='19', man='19', honors='1234567')
181+
print("Kokushi shanten:", Shanten.calculate_shanten_for_kokushi_hand(tiles))
182+
```
183+
184+
Output:
185+
186+
```
187+
Regular hand shanten: 2
188+
Tenpai hand: 0
189+
Complete hand: -1
190+
Chiitoitsu shanten: 0
191+
Kokushi shanten: 0
192+
```
193+
194+
## Agari (winning hand detection)
195+
196+
Agari check determines whether the given tiles form a complete hand structure (4 melds + 1 pair, seven pairs, or thirteen orphans). It only validates the tile arrangement, not yaku or scoring. It is faster than checking if the shanten number is `-1`, so prefer `Agari.is_agari()` when you only need to know whether a hand is complete.
197+
198+
```python
199+
from mahjong.agari import Agari
200+
from mahjong.tile import TilesConverter
201+
202+
# complete hand: 123s 456s 789s 123p 33m
203+
tiles = TilesConverter.string_to_34_array(sou='123456789', pin='123', man='33')
204+
print("Regular hand:", Agari.is_agari(tiles))
205+
206+
# incomplete hand: 123s 456s 789s 12345p
207+
tiles = TilesConverter.string_to_34_array(sou='123456789', pin='12345')
208+
print("Incomplete hand:", Agari.is_agari(tiles))
209+
210+
# seven pairs (chiitoitsu): 1133557799s 1199p
211+
tiles = TilesConverter.string_to_34_array(sou='1133557799', pin='1199')
212+
print("Seven pairs:", Agari.is_agari(tiles))
213+
214+
# thirteen orphans (kokushi): 19s 19p 199m 1234567z
215+
tiles = TilesConverter.string_to_34_array(sou='19', pin='19', man='199', honors='1234567')
216+
print("Kokushi:", Agari.is_agari(tiles))
162217

163-
print(result)
218+
# open hand with kan meld: 1111m 123456789p 22s
219+
tiles = TilesConverter.string_to_34_array(man='1111', pin='123456789', sou='22')
220+
open_set = [0, 0, 0, 0] # kan of 1m (tile index 0 in 34-tile format)
221+
print("Open hand with kan:", Agari.is_agari(tiles, [open_set]))
164222
```
165223

166224
Output:
167225

168226
```
169-
2
227+
Regular hand: True
228+
Incomplete hand: False
229+
Seven pairs: True
230+
Kokushi: True
231+
Open hand with kan: True
170232
```
171233

172234
## Aotenjou scoring rules

.github/wiki/v2-Japanese.md

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,82 @@ print(result.yaku)
152152

153153
## シャンテン数計算
154154

155+
シャンテン数はテンパイ(あと1枚で和了)に到達するまでに必要な最小の牌交換回数を示します。`0` はテンパイ、`-1` は既に和了形(完成形)であることを意味します。
156+
157+
`calculate_shanten` は一般形、七対子、国士無双の3つの形のシャンテン数を計算し、最小値を返します。各形のシャンテン数を個別に計算することもできます。
158+
155159
```python
156160
from mahjong.shanten import Shanten
157161
from mahjong.tile import TilesConverter
158162

163+
# 一般形、2シャンテン
159164
tiles = TilesConverter.string_to_34_array(man='13569', pin='123459', sou='443')
160-
result = Shanten.calculate_shanten(tiles)
165+
print("一般形シャンテン数:", Shanten.calculate_shanten(tiles))
166+
167+
# テンパイ(0シャンテン、あと1枚で和了)
168+
tiles = TilesConverter.string_to_34_array(sou='111345677', pin='11', man='567')
169+
print("テンパイ:", Shanten.calculate_shanten(tiles))
170+
171+
# 和了形(-1シャンテン、既に完成)
172+
tiles = TilesConverter.string_to_34_array(sou='111234567', pin='11', man='567')
173+
print("和了形:", Shanten.calculate_shanten(tiles))
174+
175+
# 各形のシャンテン数を個別に計算
176+
tiles = TilesConverter.string_to_34_array(sou='114477', pin='114477', man='76')
177+
print("七対子シャンテン数:", Shanten.calculate_shanten_for_chiitoitsu_hand(tiles))
178+
179+
tiles = TilesConverter.string_to_34_array(sou='129', pin='19', man='19', honors='1234567')
180+
print("国士無双シャンテン数:", Shanten.calculate_shanten_for_kokushi_hand(tiles))
181+
```
182+
183+
出力:
184+
185+
```
186+
一般形シャンテン数: 2
187+
テンパイ: 0
188+
和了形: -1
189+
七対子シャンテン数: 0
190+
国士無双シャンテン数: 0
191+
```
192+
193+
## 和了判定
194+
195+
和了判定は、与えられた手牌が完成形(4面子1雀頭、七対子、国士無双)かどうかを判定します。牌の構成のみを検証し、役や点数の判定は行いません。シャンテン数が`-1`かどうかを確認するよりも高速なため、手牌が完成形かどうかだけを確認したい場合は`Agari.is_agari()`を使用してください。
196+
197+
```python
198+
from mahjong.agari import Agari
199+
from mahjong.tile import TilesConverter
200+
201+
# 完成形:123s 456s 789s 123p 33m
202+
tiles = TilesConverter.string_to_34_array(sou='123456789', pin='123', man='33')
203+
print("一般形:", Agari.is_agari(tiles))
204+
205+
# 未完成形:123s 456s 789s 12345p
206+
tiles = TilesConverter.string_to_34_array(sou='123456789', pin='12345')
207+
print("未完成形:", Agari.is_agari(tiles))
208+
209+
# 七対子:1133557799s 1199p
210+
tiles = TilesConverter.string_to_34_array(sou='1133557799', pin='1199')
211+
print("七対子:", Agari.is_agari(tiles))
212+
213+
# 国士無双:19s 19p 199m 1234567z
214+
tiles = TilesConverter.string_to_34_array(sou='19', pin='19', man='199', honors='1234567')
215+
print("国士無双:", Agari.is_agari(tiles))
161216

162-
print(result)
217+
# 副露あり(槓子):1111m 123456789p 22s
218+
tiles = TilesConverter.string_to_34_array(man='1111', pin='123456789', sou='22')
219+
open_set = [0, 0, 0, 0] # 一萬の槓子(34牌形式のインデックス0)
220+
print("副露あり(槓子):", Agari.is_agari(tiles, [open_set]))
163221
```
164222

165223
出力:
166224

167225
```
168-
2
226+
一般形: True
227+
未完成形: False
228+
七対子: True
229+
国士無双: True
230+
副露手(槓子): True
169231
```
170232

171233
## 青天井ルール

0 commit comments

Comments
 (0)