Project Plateau
Project Plateau: four glass plates, one living valley, and the road back to camp.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Reach on SANMA — ブラウザだけで遊べる三人麻雀。通信なし・1ファイル・打ち筋の違う5人のCPU(覗き見なし)
Loading the full README. The saved excerpt is shown below.
Reach on SANMA — ブラウザだけで遊べる三人麻雀 インストール不要・通信なし・依存ライブラリなしの三人麻雀(サンマ)です。 app/index.html をブラウザで開くだけで遊べます。ファイルをローカルに置いたまま(file://)でも、 静的ホスティングに置いても動きます。 • 紹介ページ: • ゲーム本体: • 1 ファイル版: app/standalone.html(約 110 KB。これ 1 つで配布できます) 打ち筋の違う 5 人の CPU(半荘ごとに 2 人が卓に着く)と 3 段階の強さ。北抜き・ツモ損ありの三麻ルール。 CPU は他家の手牌・山・裏ドラを一切見ていません(tests/audit.js で検証)。 名前はリーチ(reach)と、三麻=秋刀魚の駄洒落から。アイコンは炭火の秋刀魚と北の牌です。Read the full README ↗
インストール不要・通信なし・依存ライブラリなしの三人麻雀(サンマ)です。
app/index.html をブラウザで開くだけで遊べます。ファイルをローカルに置いたまま(file://)でも、
静的ホスティングに置いても動きます。
app/standalone.html(約 260 KB。顔アイコンも埋め込み済みで、これ 1 つで配布できます)対戦相手は猫街三部作(猫街ろまん/猫が消えた街/街と、その白い壁)の 6 人。ナオ・フミ・マキ・チカ・タコ大王・イカ女王から
半荘ごとに 2 人が卓に着き、ひとりずつ打ち筋が違います。和了や優勝のときは顔アイコンとひとことで喜び、
あなたが和了ると放銃した人がくやしがります。強さは 3 段階。北抜き・ツモ損ありの三麻ルール。
CPU は他家の手牌・山・裏ドラを一切見ていません(tests/audit.js で検証)。
名前はリーチ(reach)と、三麻=秋刀魚の駄洒落から。アイコンは炭火の秋刀魚と北の牌です。
Reach on SANMA is a three-player riichi mahjong (sanma) game that runs entirely in the browser.
No install, no sign-up, no network traffic, no dependencies. Open app/index.html and play,
or grab the single-file build app/standalone.html (~260 KB) and play offline.
node tests/audit.js plays 300 hands with a guard that throws on any access to hidden tiles, and reports zero violations.The name is a pun: reach (riichi) and sanma, which means both "three-player mahjong" and "Pacific saury" — hence the grilled fish on the icon.
reach-on-sanma/
├── index.html 紹介ページ(GitHub Pages のトップ)
├── assets/ 紹介ページ用(site.css・アイコン)
├── make_icon.py アイコンの生成スクリプト
└── app/ ゲーム本体(ここが実体)
├── index.html これを開く
├── standalone.html 1 ファイル版(build.js が生成)
├── build.js index.html に CSS/JS を埋め込むビルドスクリプト
├── css/style.css
├── js/
│ ├── tiles.js 牌の定義・山・ドラ・表記
│ ├── faces.js 登場人物の顔アイコン(tools/make_faces.py が生成)
│ ├── hand.js シャンテン数・和了判定・待ち・受け入れ
│ ├── yaku.js 役判定・符計算・点数計算
│ ├── ai.js CPU の思考ルーチン
│ ├── game.js 局進行のステートマシン
│ └── ui.js 描画と操作
└── tests/
├── test.html ブラウザで開くセルフテスト
├── run.js `node tests/run.js` で実行
├── audit.js CPU が覗き見していないことの検証
└── characters.js キャラクター別の成績を再測定
ソースを編集したあとは app/ で node build.js を実行すると standalone.html が作り直されます。
app/index.html をダブルクリック)。画面上部のボタン:
| ボタン | 内容 |
|---|---|
| 敵 | CPU の強さ(やさしい/ふつう/つよい) |
| ヒント | 自分の手牌のシャンテン数/待ちと残り枚数を表示 |
| 速度 | CPU の打牌速度(遅/普/速/瞬) |
| 新規 | 顔ぶれを選んで最初からやり直す。あなたのキャラ(名なしも可)と対戦相手を 6 人から選ぶ。選んだ順に下家・上家、選ばなかった席はおまかせ。選んだ顔ぶれはブラウザに保存 |
| ルール | 採用ルールの一覧 |
iPhone Air(CSS ピクセルで 420 × 912)を基準にした固定レイアウトです。 捨て牌や副露が増えても他の要素がずれないよう、各段の高さは中身ではなく 牌の寸法から決めています。
操作ボタン
局情報(局 / 残り / 供託 / ドラ表示牌)
下家(手牌 1 段・副露 + 抜きドラ 1 段・河 2 段)
上家(同上)
自分の河 2 段
自分の副露 + 抜きドラ 1 段
自分の手牌 1 段(14 枚が必ず 1 列に収まる)
コマンド
ログ(余った高さを吸収。新しい行が上)
上家・下家は横並びにせず縦に積んで全幅を使うので、河・副露・伏せ牌はすべて自分と同じ寸法です。 並び順は手番の流れどおり(自分 → 下家 → 上家 → 自分)で、直前に打つ上家が手牌のすぐ上に来ます。 ログを最下段に置いているのは、iPhone の Safari で画面下のツールバーが重なっても、隠れるのが古いログだけで済むようにするためです。
牌の寸法は盤面の幅から計算しているので、画面幅が変わっても手牌は 1 列のままです。 縦に余裕がない端末では牌を段階的に小さくして 1 画面に収めます (420×912 / 393×852 / 390×668 / 360×640 / デスクトップで、スクロールなしを確認済み)。 河が 2 段を超えた場合だけ、その枠の中だけがスクロールします(レイアウトは動きません)。
| 見た目 | 意味 |
|---|---|
| 明るい牌面 | 手出し(手牌から選んで切った牌) |
| 沈んだ牌面 | ツモ切り(引いてきた牌をそのまま切った牌) |
| 赤枠 | リーチ宣言牌 |
| 薄い牌 | 鳴かれた牌 |
手出しのほうが多い(実測で約 7 割)ので、少数派のツモ切り側に印を付けて河が騒がしくならない ようにしています。鳴かれた牌も河に残すので、フリテン判定や現物読みの材料はそのまま残ります。
タイトルの「三人麻雀」を 3 秒以内に 5 回叩くと、相手の手牌が表向きになり、
席の見出しに相手のシャンテン数と待ちも出ます。暗槓も 4 枚とも表になります。
もう一度 5 回叩くと元に戻ります。URL の末尾に #open を付けて開いても同じです。
発動中はタイトルが金色になり ◉ が付きます。
変わるのは画面だけで、CPU の打ち方には一切影響しません。
この機能は js/ui.js の描画部分だけに閉じていて、ゲーム進行にも CPU の思考にも
触れていません(node tests/audit.js でこれまでどおり覗き見なしを確認できます)。
基本
鳴き・進行
点数
未実装
九種九牌・四風連打・四家立直などの途中流局、および九蓮宝燈・流し満貫は入っていません。
打牌は次の式で評価します。α・β・γ はキャラクターごとの重みです。
評価 = -シャンテン数 * (500 + 500 * α速度)
+ 受け入れ枚数 * 8 * α速度 ← 場に見えていない残り枚数で加重
+ 打点期待値 * β打点 ← ドラ・赤・抜きドラ・役牌・染め手
- 危険度 * 2 * γ守備 ← 他家リーチに対する無筋の危険度
シャンテン数の重みも α に連動させているので、打点型は手を進めるよりドラや染め手の形を
残すことを選び、速攻型は形を崩してでも手を進めます。リーチ判断では、リーチを打たなかった
場合の翻数を実際に evaluate() で見積もって、ダマに構えるかどうかを決めています。
半荘ごとに、猫街三部作の 6 人から 2 人が重複なくランダムで選ばれます。
This is the beginning of the README. Read the rest at the original. Read the full README ↗