cg memo

備忘録をまとめるブログ

piece of Procedural - men tan pin

プロシージャルモデリングの習作

メンタンピン

プロシージャル配置の作例(?)としてご紹介してみます。
麻雀用語が多めで申し訳ないです。

メンタンピンの定義(ざっくり):
  1. メンゼンリーチである …牌が全て並んでいる
  2. タンヤオである …1と9と字牌が無い
  3. ピンフである …シュンツで構成されている(シュンツ…1,2,3のような並び)

今回は「局」や「他家」、リーチ棒などは考慮しない事にしました。

手続きの流れ

まずは牌そのものの代わりにpoint群を用意しました。
Attribute Wrangle でどかっと作り、同時に牌の種別を表すアトリビュートを付与します。(m1=マンズの1)
"polyline"で接続されている理由は後ほど説明します。
f:id:satyk:20180822005605p:plain

各牌は4枚づつ存在するので、点群を複製し、同時に残り枚数を表すアトリビュートも付与します。
f:id:satyk:20180822005614p:plain

polylineで接続されているpointの中から、シュンツの「中央」になる可能性のあるpointを抜粋します。
タンヤオなので1と9は除かれます。2と8もシュンツの中央には来ないので除かれます。
f:id:satyk:20180822005622p:plain

point群の中から、1つのpointをランダムで選択します。これが1つ目のシュンツの「中央」の牌です。
f:id:satyk:20180822005629p:plain

ランダムなpointを1つ選ぶ方法は、今回は Sort SOPを使用しました。ソート方法を「Random」にして、次に繋いだGroup SOP で「0」番のpointを選択しています。
ランダムシードは別のノードに一括でまとめています。
f:id:satyk:20180822011432p:plain

候補牌を抜粋する前のpoint群に対して Group Transfer SOP でシュンツの「中央」を教えてやり、
Find Shortest Path SOP で両隣のpointを取得します。このために polylineで繋いでみました。
これでシュンツが1つ決まりました!
f:id:satyk:20180822005641p:plain

Attribute Wrangle で残り牌をカウントダウンし、シュンツのグループは残り数の小さいほうに移動します。
なぜかというと、polylineで繋ぎなおすのが面倒だから、というだけです。
f:id:satyk:20180822005654p:plain

1つ目のシュンツはpoint群から split し、また次のシュンツ候補の中から、同様の処理でシュンツを選んでいきます。
f:id:satyk:20180822005702p:plain

ただし、同じシュンツは3回以上選択されないように小細工をする必要があります。
同じシュンツが2つなら一盃口になりますが、同じシュンツが3つになると三暗刻になってしまい、メンタンピンではなくなるからです(たぶん…)。
f:id:satyk:20180822005710p:plain

最後に雀頭を取得します。
雀頭は、1と9以外で、かつ2枚以上残っている牌からランダムで選択します。
f:id:satyk:20180822005718p:plain

これで全ての牌が選ばれ split されたので、それらを全て Merge します。
f:id:satyk:20180822022106p:plain

見やすいようにリーパイ(ソート)したら…
f:id:satyk:20180822022151p:plain

事前に作成しておいた牌と差し替えて、メンタンピン完成です!
f:id:satyk:20180822022249p:plain

ランダムシードは$Fベースですが、早すぎてデバッグできない…!:D
f:id:satyk:20180822023354g:plain


画像は「麻雀の雀龍.com」の無料麻雀牌画をお借りしました。
麻雀牌画・無料素材(フリー画像)のダウンロード可能! - 麻雀の雀龍.com