PlantUMLで麻雀の状態遷移図を書いた

# はじめに

PlantUMLの使い方を勉強するために麻雀のルールの状態遷移図を書いたことがあったのですが、PC引っ越しの際に出てきたので供養のために記事にしておきます。

GA4を確認すると麻雀記事のアスセス数多めなので傾向を見るためにタイトルに麻雀いれときます。


# PlantUMLについて

PlantUMLはUMLを記述するツールですが、定番と思いますのでこの記事では説明しないです。
ネットで調べればインストール方法、記述ルールが多数ヒットします。

私はVS CODEにPlantUMLのプラグインを入れて使っています。
プレビュー表示がでるので作業しやすかったです。

あとsvgで出力できるので省サイズになってうれしい。


# 麻雀の状態について

４人で１局を回すための状態遷移をまとめます。

１つの開始状態から、複数の終了状態へ遷移する図になります。

終了状態を１つにまとめるとカオスになるので、分かりやすさ優先にしています。

図にしてみると結構複雑な図になったので、実装が面倒なのがよくわかりました。




# 状態遷移表

状態遷移図だけだと、各状態で何をするのか分からないので、説明の表も貼っておきます。


|状態|種類|説明|
|------|------|------|
|初期状態|開始|配牌|
|ツモ|ツモユーザー操作|手牌でツモ上がりするか|
|九種九牌|ツモユーザー操作|九種九牌するか|
|暗槓|ツモユーザー操作|暗槓するか|
|小明槓|ツモユーザー操作|小明槓するか|
|手牌切り|ツモユーザー操作|河に捨てる＋リーチするか|
|ロン|他ユーザー操作|捨て牌でロンするか|
|チー|他ユーザー操作|捨て牌でチーするか|
|ポン|他ユーザー操作|捨て牌でポンするか|
|大明槓|他ユーザー操作|捨て牌で大明槓するか|
|槍槓|他ユーザー操作|槍槓でロンするか|
|牌山取得|自動|牌山から取得する|
|嶺上牌取得|自動|嶺上牌から取得する|
|四風連打|自動|四風連打が成立したか|
|四槓流れ|自動|四槓流れが成立したか|
|四家立直|自動|四家立直が成立したか|
|流し満貫|自動|流し満貫が成立したか|
|流局|終了|流局|
|九種九牌流局|終了|流局|
|四風連打流局|終了|流局|
|四槓流れ流局|終了|流局|
|ツモ上がり|終了|ツモユーザーの上がり|
|ロン上がり|終了|ロンユーザーの上がり|
|槍槓上がり|終了|ロンユーザーの上がり|
|流し満貫上がり|終了|条件満たしたユーザーの上がり|


ルールの説明サイト見ながら整理したけど合ってる？
レアなルールは理解が怪しい。。。


# 作成した図


```plantuml

@startuml 麻雀状態遷移図

title 麻雀状態遷移図

skinparam stateBorderColor #Black

'開始状態
state 初期状態 #White

'ツモユーザー操作状態
state ツモ #LightBlue
state 九種九牌 #LightBlue
state 暗槓 #LightBlue
state 小明槓 #LightBlue
state 手牌切り #LightBlue

'他ユーザー操作状態
state ロン #LightGreen
state チー #LightGreen
state ポン #LightGreen
state 大明槓 #LightGreen
state 槍槓 #LightGreen

'自動で分岐、遷移する状態
state 牌山取得 #Pink
state 嶺上牌取得 #Pink
state 四風連打 #Pink
state 四槓流れ #Pink
state 四家立直 #Pink
state 流し満貫 #Pink

'終了状態(流局)
state 流局 #LightGray
state 九種九牌流局 #LightGray
state 四風連打流局 #LightGray
state 四槓流れ流局 #LightGray
state 四家立直流局 #LightGray

'終了状態(上がり)
state ツモ上がり #OrangeRed
state ロン上がり #OrangeRed
state 槍槓上がり #OrangeRed
state 流し満貫上がり #OrangeRed

初期状態-[#Black]->牌山取得 : auto

' 特殊なパターンなので矢印長めで配置
牌山取得-[#Black]--> 流し満貫 : NG(empty)
牌山取得-[#Black]-> ツモ : OK

流し満貫-[#Black]-> 流局 : NO
流し満貫-[#Black]-> 流し満貫上がり : YES

ツモ-[#Black]-> ツモ上がり : YES
ツモ-[#Black]-> 九種九牌 : NO

九種九牌-[#Black]-> 九種九牌流局 : YES
九種九牌-[#Black]-> 暗槓: NO

暗槓-[#Black]->四槓流れ : YES
暗槓-[#Black]->小明槓 : NO

小明槓-[#Black]->槍槓 : YES
小明槓-[#Black]->手牌切り : NO

嶺上牌取得-[#Black]->ツモ : auto

手牌切り-[#Black]->ロン : 捨て牌
手牌切り-[#Black]->四家立直 : 立直(+捨て牌)

四家立直-[#Black]->四家立直流局 : YES
四家立直-[#Black]->ロン : NO

ロン-[#Black]->ロン上がり : YES
ロン-[#Black]->チー : NO

チー-[#Black,thickness=3]->手牌切り : YES<b>(+ツモユーザー切り替え)</b>
チー-[#Black]->ポン : NO

ポン-[#Black,thickness=3]->手牌切り : YES<b>(+ツモユーザー切り替え)</b>
ポン-[#Black]->大明槓 : NO

大明槓-[#Black,thickness=3]->四槓流れ : YES<b>(+ツモユーザー切り替え)</b>
大明槓-[#Black]->四風連打 : NO

四風連打-[#Black,thickness=3]->牌山取得 : NO<b>(+ツモユーザー切り替え)</b>
四風連打-[#Black]->四風連打流局 : YES

槍槓-[#Black]->槍槓上がり : YES
槍槓-[#Black]->四槓流れ : NO

四槓流れ-[#Black]->四槓流れ流局 : YES
四槓流れ-[#Black]->嶺上牌取得 : NO

note right of 初期状態 #White
処理の開始
end note

note top of 牌山取得 #White
山がなくなるまで繰り返し
end note

note top of 手牌切り #White
１つ選択して切る。
立直の有無もここで行う。
end note

note top of 流し満貫 #White
全員の河を確認する
end note

note right of 四風連打 #White
全員の河を確認する
end note

note left of 四槓流れ #White
全員の槓の回数を判定
end note

note right of 四家立直 #White
全員の立直を判定
end note

@enduml


```


状態遷移図の色|説明|
|------|------|
|while|開始|
|LightGray|流局|
|OrangeRed|上がり|
|LightBlue|ツモユーザー操作|
|LightGreen|他ユーザー操作|
|Pink|自動判定、自動遷移|


- 線のコメントに遷移の条件を記載

- 太線はツモユーザーを変更して状態遷移


## PlantUMLのソース

難しいことしてないので解説は載せませんが、PlantUMLのソースを貼っておきます。


```

@startuml 麻雀状態遷移図

title 麻雀状態遷移図

skinparam stateBorderColor #Black

'開始状態
state 初期状態 #White

'ツモユーザー操作状態
state ツモ #LightBlue
state 九種九牌 #LightBlue
state 暗槓 #LightBlue
state 小明槓 #LightBlue
state 手牌切り #LightBlue

'他ユーザー操作状態
state ロン #LightGreen
state チー #LightGreen
state ポン #LightGreen
state 大明槓 #LightGreen
state 槍槓 #LightGreen

'自動で分岐、遷移する状態
state 牌山取得 #Pink
state 嶺上牌取得 #Pink
state 四風連打 #Pink
state 四槓流れ #Pink
state 四家立直 #Pink
state 流し満貫 #Pink

'終了状態(流局)
state 流局 #LightGray
state 九種九牌流局 #LightGray
state 四風連打流局 #LightGray
state 四槓流れ流局 #LightGray
state 四家立直流局 #LightGray

'終了状態(上がり)
state ツモ上がり #OrangeRed
state ロン上がり #OrangeRed
state 槍槓上がり #OrangeRed
state 流し満貫上がり #OrangeRed

初期状態-[#Black]->牌山取得 : auto

' 特殊なパターンなので矢印長めで配置
牌山取得-[#Black]--> 流し満貫 : NG(empty)
牌山取得-[#Black]-> ツモ : OK

流し満貫-[#Black]-> 流局 : NO
流し満貫-[#Black]-> 流し満貫上がり : YES

ツモ-[#Black]-> ツモ上がり : YES
ツモ-[#Black]-> 九種九牌 : NO

九種九牌-[#Black]-> 九種九牌流局 : YES
九種九牌-[#Black]-> 暗槓: NO

暗槓-[#Black]->四槓流れ : YES
暗槓-[#Black]->小明槓 : NO

小明槓-[#Black]->槍槓 : YES
小明槓-[#Black]->手牌切り : NO

嶺上牌取得-[#Black]->ツモ : auto

手牌切り-[#Black]->ロン : 捨て牌
手牌切り-[#Black]->四家立直 : 立直(+捨て牌)

四家立直-[#Black]->四家立直流局 : YES
四家立直-[#Black]->ロン : NO

ロン-[#Black]->ロン上がり : YES
ロン-[#Black]->チー : NO

チー-[#Black,thickness=3]->手牌切り : YES<b>(+ツモユーザー切り替え)</b>
チー-[#Black]->ポン : NO

ポン-[#Black,thickness=3]->手牌切り : YES<b>(+ツモユーザー切り替え)</b>
ポン-[#Black]->大明槓 : NO

大明槓-[#Black,thickness=3]->四槓流れ : YES<b>(+ツモユーザー切り替え)</b>
大明槓-[#Black]->四風連打 : NO

四風連打-[#Black,thickness=3]->牌山取得 : NO<b>(+ツモユーザー切り替え)</b>
四風連打-[#Black]->四風連打流局 : YES

槍槓-[#Black]->槍槓上がり : YES
槍槓-[#Black]->四槓流れ : NO

四槓流れ-[#Black]->四槓流れ流局 : YES
四槓流れ-[#Black]->嶺上牌取得 : NO

note right of 初期状態 #White
処理の開始
end note

note top of 牌山取得 #White
山がなくなるまで繰り返し
end note

note top of 手牌切り #White
１つ選択して切る。
立直の有無もここで行う。
end note

note top of 流し満貫 #White
全員の河を確認する
end note

note right of 四風連打 #White
全員の河を確認する
end note

note left of 四槓流れ #White
全員の槓の回数を判定
end note

note right of 四家立直 #White
全員の立直を判定
end note

@enduml


```


見やすくする記載のコツが知りたい。。。



# PlantUMLの感想

PlantUMLは、覚えることも少なく、すぐに実用できそうです。

テキストで記述できるのでgitなどでバージョン管理できるのは魅力があります。

細かい配置の調整ができないみたいですが、そのあたりは割り切って使っていくのが合理的と思います。

使った印象としては以下で運用するのがよいと思いました。

- ざっくりとした内部的な設計はPlantUML

有料のastahなら無料のPlantUMLでよいと思う

- プレゼン用のきれいな設計資料を作るなら有償のツールを利用する

以前は[Visio](https://www.microsoft.com/ja-jp/microsoft-365/visio/visio-in-microsoft-365)を使っていましたが、最近はあまり聞かないですね。
ExcelでUML書くのは勘弁してほしい。


# おわりに

最近麻雀やってないからの細かいルールを忘れています。
昨年末に、妻の実家で妻、妻母、妻父、自分でコタツ麻雀やりましたがグダグダでした。(妻父にまくられて、2位でした)

記憶が怪しいところはネットでルールを確認しながら図にしてみましたが、間違っていたらごめんなさい。


# 麻雀開発シリーズ

[麻雀やるより麻雀プログラムを考えるほうがが好き](https://qiita.com/magiclib/items/d1d2dbcde71f6c5f796f)