オーラス麻雀ゲーム開発日記構想から現在までの開発記録を、公開順にまとめています。

前回までの進捗
前回は、自分の席や目標順位、本場、供託リーチ棒を入力できるようにした。
これで、
- 現在の持ち点
- 自分の席
- 目標順位
- 本場
- 供託
という、条件計算に必要そうな情報がひと通りそろった。
今回は、いよいよこのアプリの中心になる処理に着手する。
まずはロンの場合に、誰から何点アガれば目標順位を達成できるのかを計算してみる。
単純な点差だけでは決められない
最初は、現在の点差を見れば必要な点数を出せると思っていた。
たとえば、自分が23,000点で相手が26,000点なら、差は3,000点。
それなら3,000点以上アガれば逆転できそうに見える。
ただし、相手からロンした場合は、
- 自分の点数が増える
- 放銃した相手の点数が減る
という二つの変化が同時に起こる。
2,000点をロンした場合でも、自分と相手の差は合計4,000点縮まる。
さらに、放銃者が誰なのかによって、ほかの人との順位関係も変わる。
本場や供託があれば、実際に増減する点数も変わる。
単純に「上の人との点差」を計算するだけでは足りなさそうだった。
実際に点数を動かして確かめる
そこで今回は、必要な点数を数式だけで求めるのではなく、候補となる点数を一つずつ試す方法にした。
処理の流れは、だいたいこんな感じ。
- 放銃者を一人選ぶ
- 候補となるロン点を低い順に試す
- ロン後の点数を計算する
- ロン後の順位を計算する
- 目標順位を達成できたか確認する
- 最初に達成できた点数を必要点数とする
少し力技にも見えるけれど、候補となる点数の数はそれほど多くない。
複雑な条件を無理に一つの式へまとめるより、実際の点数移動を再現して確認する方が分かりやすいと判断した。
和了点の候補を用意する
麻雀のロン点は、100点ずつ自由に増えるわけではない。
そこで、実際に使われる代表的な点数を配列として用意した。
const childRonPoints = [
1000,
1300,
1600,
2000,
2300,
2600,
2900,
3200,
3900,
5200,
7700,
8000,
12000,
];
実際の配列にはもう少し細かく候補を入れている。
自分が親の場合は点数が変わるため、親用と子用で別の候補を持たせることにした。
現在の試作では南4局を想定し、北家を親として固定している。
そのため、自分の席が北家かどうかで、使用する点数候補を切り替える。
放銃者ごとに条件を探す
ロンの場合は、誰からアガるかが重要になる。
たとえば、トップを目指しているときにトップから直撃できれば、少ない点数で逆転できる可能性がある。
一方、4着の相手からロンしても、トップとの差は自分の加点分しか縮まらない。
そこで、自分以外の3人を放銃者として、それぞれ必要な点数を探す。
イメージとしては、次のような処理になる。
for (const loser of seats) {
if (loser === selfSeat) {
continue; // 自分の場合はスキップ
}
for (const points of ronPointCandidates) {
// ロン時の点数を試算
const nextScores = applyRon(
scores,
selfSeat,
loser,
points,
honba,
kyotaku,
);
// 順位を算出
const ranking = calculateRanking(nextScores);
if (isGoalAchieved(ranking, selfSeat, goal)) {
// この放銃者からは、この点数で条件を達成
break;
}
}
}
コードとしては少し長くなったけれど、やっていること自体は単純。
低い点数から順番に試し、目標を達成できた時点で探索を止める。
これで、放銃者ごとの最低条件を出せる。
本場と供託も反映する
ロンの場合、本場があると放銃者の支払いが増える。
実際の支払い = ロン点 + 本場 × 300点
供託リーチ棒がある場合は、アガった人に1本あたり1,000点が加算される。
本場と供託が多ければ、同じ基本点でも目標順位に届く可能性がある。
前回追加した入力項目が、ここでようやく計算に使われるようになった。
入力欄を作った時点では画面に数字が増えただけだったけれど、計算結果に影響するようになると、少しアプリらしく感じる。
ちょうどの点数が存在しない場合
たとえば計算上は3,500点あれば逆転できるとしても、ロン点として3,500点という候補はない。
その場合は、3,500点以上で最初に見つかる実際の和了点を表示する必要がある。
候補を低い順に試す方式なら、ここも自然に処理できる。
3,500という数字をそのまま表示するのではなく、実際に条件を満たせる3,900点などを結果として返す。
今回この方式にした一番大きな理由は、こういった麻雀特有の点数の飛び方を扱いやすかったから。
今回できたこと
今回の進捗は以下のとおり。
- 親と子でロン点候補を分けた
- ロン後の点数を計算できるようにした
- 放銃者ごとに必要な点数を探索した
- ロン後の順位から目標達成を判定した
- 本場と供託を必要点数の計算に反映した
- 実際に存在する和了点から最低条件を表示した
点数入力や順位表示だけだった画面に、「誰から何点」という情報を出せるようになった。
ようやく、作りたかったオーラス条件確認アプリらしい機能が一つできたと思う。
ただ、ロン条件だけではまだ不十分。
麻雀ではツモによる逆転もあるし、親と子で支払い方も変わる。
次はツモの場合について、ほかの3人からの支払いを反映しながら必要点数を探していく。
前回までと合わせて画面はこんな感じ。

まだまだゲームどころかアプリにすらなってないけど、
次にツモの場合を作って、その次くらいに対局結果(誰が何点でアガったか)入力と
リザルト表示になる想定。
そこまでいけば、点数シミュレーションアプリくらいの体裁にはなるだろうか。
牛一。
コメント