Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

麻雀シミュレーションライブラリを作った

のに記事にするのを忘れていました。

github.com

概要

このライブラリを使うと、牌山、手牌、河の状態を簡潔に表現できます。

class Player {
    constructor(name) {
        this.name = name;
        this.hand = new Mahjongg.Hand([]); // 手牌
    }
    draw() {
        this.hand.draw(table.draw());
    }
    draw4() {
        this.draw(); this.draw(); this.draw(); this.draw();
    }
}
class Dice {
    constructor() {}
    throw() { this.number = (0 | Math.random() * 6) + 1; }
}
const dice1 = new Dice(), dice2 = new Dice();
const set = Mahjongg.bambooSuits.concat(Mahjongg.characterSuits)
    .concat(Mahjongg.circleSuits)
    .concat(Mahjongg.honorTiles);
const players = [new Player('Me'), new Player('花子'), new Player('ポチ'), new Player('太郎')];
const table = new Mahjongg.Table(set.concat(set).concat(set).concat(set)); // 牌山
table.shuffle(); // 洗牌する

dice1.throw(); dice2.throw();
table.leader = (dice1.number + dice2.number) % 4;
dice1.throw(); dice2.throw();
table.start(dice1.number + dice2.number);

for (let j = 0; j < 3; j++) {
    for (let i = 0; i < 4; i++) {
        players[(i + table.leader) % 4].draw4();
    }
}

for (let i = 0; i < 4; i++) {
    players[(i + table.leader) % 4].draw()
}
players[table.leader].draw(); // チョンチョンまでは再現できなかった…

麻雀のゲームの流れがそのまま記述できています。

ほかにも手牌の形から役判定をすることもできます。ただし、リーチや平和のような牌姿以外がからんでくるものは判定できません。天和に関しては「与えられた手牌から可能な4面子1雀頭の組み合わせを返す関数」が存在するので判定可能です。

用途

麻雀ゲームの製作にはもちろん、天和の確率計算などもできます(1000万回手牌を作ってみて何回天和が出たかカウントするという超ゴリ押しですが)。

本当はこのライブラリを使って「麻雀ゲームを作りながら覚えるプログラミング!」という記事を書こうとしていたのですが、思っていた以上に描画部分がかさんで(200行を余裕で突破した)しまったのでちょっと考えています… 誰か代わりに書いて