小粒プログラミング 牌山

#01 牌山を生成する

Javascriptで遊ぶ麻雀小粒プログラミング 今回のお題は、牌山の生成と生成した牌山を乱数でシャッフルする処理を紹介します。乱数は「Mersenne Twister in JavaScript」を使用して発生させます。

プログラムの実行

牌山を生成します。牌山は配列(yama)に保存されます。配列(yama)のサイズは0~135あり、牌の総数に対応しています。

牌山の牌に割り振られた番号
▲配列に保存されている牌山のイメージ(一番目の牌山)

牌山を生成する手順

最初に牌種ごとに整列した牌山を生成(元の牌山)します。JSON形式の配列(paiYama)の値(paiNo)を牌山(yama)に順番に代入します。最後に生成した牌山を乱数処理でシャッフルして作業は終了します。以上で、撹拌された牌山のできあがりです。

元になる牌山「一萬~九萬赤五萬、一筒~九筒赤五筒、一索~九索赤五索、字牌」が順番に並んで積まれている状態
シャッフルした牌山元になる牌山を乱数で並べ替えて積み直した状態

牌山生成プログラムの実行

[牌山生成&シャッフル]ボタンを押すと、元に牌山と乱数でシャッフルされた牌山が生成されます。出力された数字は牌の種類を示します。牌種の番号は配牌を配列に格納するの記事を参考にしてください。

元の牌山
 
シャッフルした牌山
 

擬似乱数生成器~メルセンヌ・ツイスタ

本サイトでは乱数生成にたびたびメルセンヌツイスターを利用することがあります。メルセンヌツイスターは擬似乱数生成器と呼ばれるものの一つで、ウィキペディアには次のように紹介されています。

メルセンヌ・ツイスタ (Mersenne twister、通称MT) は擬似乱数生成器 (PRNG) の1つである。1996年から1998年(1996年国際会議で発表、1997年朝日新聞記事、1998年1月論文掲載)に松本眞と西村拓士によって開発された。既存の疑似乱数生成アルゴリズムの欠点を改良して、高品質の疑似乱数を高速に生成するように設計されている。 2007年1月31日、松本眞とその指導学生の斎藤睦夫により、上記の改良版SFMTがウェブサイトに発表された。現在、公式ウェブサイトからダウンロードできる。 「メルセンヌ・ツイスタ」『フリー百科事典 ウィキペディア日本語版』より(http://ja.wikipedia.org/)。2015年3月24日22時(日本時間)現在での最新版を取得。

JavaScriptにも乱数を発生させるrandom関数が用意されていますが、牌山を生成する際は、メルセンヌツイスターを使うことにしてます。 本サイトでは、JavaScriptに移植されたMersenne Twister in JavaScriptで乱数を発生させています。詳しい使い方は、公式サイトMersenne Twister in JavaScriptをご覧ください。



JavaScriptソースコード

本記事で紹介したサンプルプログラムをダウンロードできます。

ダウンロードをする前にお読みください

  • サイトで紹介している記事の内容や公開しているプログラムの動作は100%保障するものではありません。
  • 当プログラム使用による如何なる不具合やトラブル、損害の責任も負いかねます。
  • 当プログラムは断り無く内容が変わることがあります。
  • 当プログラムを別サイトで配布することは禁止します。
  • サポートはいたしません。
  • 自己責任にてご利用くださいませ。

以上をご確認の上、プログラムのダウンロードをお願いいたします。

サンプルプログラムのソースコード

ソースコードは折りたたんであります。[+]を押すと、折りたたまれたソースコードが開きます。[-]を押すと、コードは折りたたまれます。

+ program_001.jsのソースコードを開く

//============================================================================
//牌の配列:JSON形式
//============================================================================
var paiYama = [
	{"No":0,"paiName":"一萬","paiCode":"1m","paiNo":1},
	{"No":1,"paiName":"一萬","paiCode":"1m","paiNo":1},
	{"No":2,"paiName":"一萬","paiCode":"1m","paiNo":1},
	{"No":3,"paiName":"一萬","paiCode":"1m","paiNo":1},
	{"No":4,"paiName":"二萬","paiCode":"2m","paiNo":2},
	{"No":5,"paiName":"二萬","paiCode":"2m","paiNo":2},
	{"No":6,"paiName":"二萬","paiCode":"2m","paiNo":2},
	{"No":7,"paiName":"二萬","paiCode":"2m","paiNo":2},
	{"No":8,"paiName":"三萬","paiCode":"3m","paiNo":3},
	{"No":9,"paiName":"三萬","paiCode":"3m","paiNo":3},
	{"No":10,"paiName":"三萬","paiCode":"3m","paiNo":3},
	{"No":11,"paiName":"三萬","paiCode":"3m","paiNo":3},
	{"No":12,"paiName":"四萬","paiCode":"4m","paiNo":4},
	{"No":13,"paiName":"四萬","paiCode":"4m","paiNo":4},
	{"No":14,"paiName":"四萬","paiCode":"4m","paiNo":4},
	{"No":15,"paiName":"四萬","paiCode":"4m","paiNo":4},
	{"No":16,"paiName":"赤五萬","paiCode":"0m","paiNo":0},
	{"No":17,"paiName":"五萬","paiCode":"5m","paiNo":5},
	{"No":18,"paiName":"五萬","paiCode":"5m","paiNo":5},
	{"No":19,"paiName":"五萬","paiCode":"5m","paiNo":5},
	{"No":20,"paiName":"六萬","paiCode":"6m","paiNo":6},
	{"No":21,"paiName":"六萬","paiCode":"6m","paiNo":6},
	{"No":22,"paiName":"六萬","paiCode":"6m","paiNo":6},
	{"No":23,"paiName":"六萬","paiCode":"6m","paiNo":6},
	{"No":24,"paiName":"七萬","paiCode":"7m","paiNo":7},
	{"No":25,"paiName":"七萬","paiCode":"7m","paiNo":7},
	{"No":26,"paiName":"七萬","paiCode":"7m","paiNo":7},
	{"No":27,"paiName":"七萬","paiCode":"7m","paiNo":7},
	{"No":28,"paiName":"八萬","paiCode":"8m","paiNo":8},
	{"No":29,"paiName":"八萬","paiCode":"8m","paiNo":8},
	{"No":30,"paiName":"八萬","paiCode":"8m","paiNo":8},
	{"No":31,"paiName":"八萬","paiCode":"8m","paiNo":8},
	{"No":32,"paiName":"九萬","paiCode":"9m","paiNo":9},
	{"No":33,"paiName":"九萬","paiCode":"9m","paiNo":9},
	{"No":34,"paiName":"九萬","paiCode":"9m","paiNo":9},
	{"No":35,"paiName":"九萬","paiCode":"9m","paiNo":9},

	{"No":36,"paiName":"一筒","paiCode":"1p","paiNo":11},
	{"No":37,"paiName":"一筒","paiCode":"1p","paiNo":11},
	{"No":38,"paiName":"一筒","paiCode":"1p","paiNo":11},
	{"No":39,"paiName":"一筒","paiCode":"1p","paiNo":11},
	{"No":40,"paiName":"二筒","paiCode":"2p","paiNo":12},
	{"No":41,"paiName":"二筒","paiCode":"2p","paiNo":12},
	{"No":42,"paiName":"二筒","paiCode":"2p","paiNo":12},
	{"No":43,"paiName":"二筒","paiCode":"2p","paiNo":12},
	{"No":44,"paiName":"三筒","paiCode":"3p","paiNo":13},
	{"No":45,"paiName":"三筒","paiCode":"3p","paiNo":13},
	{"No":46,"paiName":"三筒","paiCode":"3p","paiNo":13},
	{"No":47,"paiName":"三筒","paiCode":"3p","paiNo":13},
	{"No":48,"paiName":"四筒","paiCode":"4p","paiNo":14},
	{"No":49,"paiName":"四筒","paiCode":"4p","paiNo":14},
	{"No":50,"paiName":"四筒","paiCode":"4p","paiNo":14},
	{"No":51,"paiName":"四筒","paiCode":"4p","paiNo":14},
	{"No":52,"paiName":"赤五筒","paiCode":"0p","paiNo":10},
	{"No":53,"paiName":"五筒","paiCode":"5p","paiNo":15},
	{"No":54,"paiName":"五筒","paiCode":"5p","paiNo":15},
	{"No":55,"paiName":"五筒","paiCode":"5p","paiNo":15},
	{"No":56,"paiName":"六筒","paiCode":"6p","paiNo":16},
	{"No":57,"paiName":"六筒","paiCode":"6p","paiNo":16},
	{"No":58,"paiName":"六筒","paiCode":"6p","paiNo":16},
	{"No":59,"paiName":"六筒","paiCode":"6p","paiNo":16},
	{"No":60,"paiName":"七筒","paiCode":"7p","paiNo":17},
	{"No":61,"paiName":"七筒","paiCode":"7p","paiNo":17},
	{"No":62,"paiName":"七筒","paiCode":"7p","paiNo":17},
	{"No":63,"paiName":"七筒","paiCode":"7p","paiNo":17},
	{"No":64,"paiName":"八筒","paiCode":"8p","paiNo":18},
	{"No":65,"paiName":"八筒","paiCode":"8p","paiNo":18},
	{"No":66,"paiName":"八筒","paiCode":"8p","paiNo":18},
	{"No":67,"paiName":"八筒","paiCode":"8p","paiNo":18},
	{"No":68,"paiName":"九筒","paiCode":"9p","paiNo":19},
	{"No":69,"paiName":"九筒","paiCode":"9p","paiNo":19},
	{"No":70,"paiName":"九筒","paiCode":"9p","paiNo":19},
	{"No":71,"paiName":"九筒","paiCode":"9p","paiNo":19},

	{"No":72,"paiName":"一索","paiCode":"1s","paiNo":21},
	{"No":73,"paiName":"一索","paiCode":"1s","paiNo":21},
	{"No":74,"paiName":"一索","paiCode":"1s","paiNo":21},
	{"No":75,"paiName":"一索","paiCode":"1s","paiNo":21},
	{"No":76,"paiName":"二索","paiCode":"2s","paiNo":22},
	{"No":77,"paiName":"二索","paiCode":"2s","paiNo":22},
	{"No":78,"paiName":"二索","paiCode":"2s","paiNo":22},
	{"No":79,"paiName":"二索","paiCode":"2s","paiNo":22},
	{"No":80,"paiName":"三索","paiCode":"3s","paiNo":23},
	{"No":81,"paiName":"三索","paiCode":"3s","paiNo":23},
	{"No":82,"paiName":"三索","paiCode":"3s","paiNo":23},
	{"No":83,"paiName":"三索","paiCode":"3s","paiNo":23},
	{"No":84,"paiName":"四索","paiCode":"4s","paiNo":24},
	{"No":85,"paiName":"四索","paiCode":"4s","paiNo":24},
	{"No":86,"paiName":"四索","paiCode":"4s","paiNo":24},
	{"No":87,"paiName":"四索","paiCode":"4s","paiNo":24},
	{"No":88,"paiName":"赤五索","paiCode":"0s","paiNo":20},
	{"No":89,"paiName":"五索","paiCode":"5s","paiNo":25},
	{"No":90,"paiName":"五索","paiCode":"5s","paiNo":25},
	{"No":91,"paiName":"五索","paiCode":"5s","paiNo":25},
	{"No":92,"paiName":"六索","paiCode":"6s","paiNo":26},
	{"No":93,"paiName":"六索","paiCode":"6s","paiNo":26},
	{"No":94,"paiName":"六索","paiCode":"6s","paiNo":26},
	{"No":95,"paiName":"六索","paiCode":"6s","paiNo":26},
	{"No":96,"paiName":"七索","paiCode":"7s","paiNo":27},
	{"No":97,"paiName":"七索","paiCode":"7s","paiNo":27},
	{"No":98,"paiName":"七索","paiCode":"7s","paiNo":27},
	{"No":99,"paiName":"七索","paiCode":"7s","paiNo":27},
	{"No":100,"paiName":"八索","paiCode":"8s","paiNo":28},
	{"No":101,"paiName":"八索","paiCode":"8s","paiNo":28},
	{"No":102,"paiName":"八索","paiCode":"8s","paiNo":28},
	{"No":103,"paiName":"八索","paiCode":"8s","paiNo":28},
	{"No":104,"paiName":"九索","paiCode":"9s","paiNo":29},
	{"No":105,"paiName":"九索","paiCode":"9s","paiNo":29},
	{"No":106,"paiName":"九索","paiCode":"9s","paiNo":29},
	{"No":107,"paiName":"九索","paiCode":"9s","paiNo":29},

	{"No":108,"paiName":"東","paiCode":"1z","paiNo":31},
	{"No":109,"paiName":"東","paiCode":"1z","paiNo":31},
	{"No":110,"paiName":"東","paiCode":"1z","paiNo":31},
	{"No":111,"paiName":"東","paiCode":"1z","paiNo":31},
	{"No":112,"paiName":"南","paiCode":"2z","paiNo":32},
	{"No":113,"paiName":"南","paiCode":"2z","paiNo":32},
	{"No":114,"paiName":"南","paiCode":"2z","paiNo":32},
	{"No":115,"paiName":"南","paiCode":"2z","paiNo":32},
	{"No":116,"paiName":"西","paiCode":"3z","paiNo":33},
	{"No":117,"paiName":"西","paiCode":"3z","paiNo":33},
	{"No":118,"paiName":"西","paiCode":"3z","paiNo":33},
	{"No":119,"paiName":"西","paiCode":"3z","paiNo":33},
	{"No":120,"paiName":"北","paiCode":"4z","paiNo":34},
	{"No":121,"paiName":"北","paiCode":"4z","paiNo":34},
	{"No":122,"paiName":"北","paiCode":"4z","paiNo":34},
	{"No":123,"paiName":"北","paiCode":"4z","paiNo":34},
	{"No":124,"paiName":"白","paiCode":"5z","paiNo":35},
	{"No":125,"paiName":"白","paiCode":"5z","paiNo":35},
	{"No":126,"paiName":"白","paiCode":"5z","paiNo":35},
	{"No":127,"paiName":"白","paiCode":"5z","paiNo":35},
	{"No":128,"paiName":"發","paiCode":"6z","paiNo":36},
	{"No":129,"paiName":"發","paiCode":"6z","paiNo":36},
	{"No":130,"paiName":"發","paiCode":"6z","paiNo":36},
	{"No":131,"paiName":"發","paiCode":"6z","paiNo":36},
	{"No":132,"paiName":"中","paiCode":"7z","paiNo":37},
	{"No":133,"paiName":"中","paiCode":"7z","paiNo":37},
	{"No":134,"paiName":"中","paiCode":"7z","paiNo":37},
	{"No":135,"paiName":"中","paiCode":"7z","paiNo":37}
];

//グローバル変数==============================================================
var yama = new Array(135);//牌山の配列:136牌
//==============================================================================
//元になる牌山を生成する関数
function makePaiYama(){
	var i;
	for(i=0;i<136;i++){
		yama[i] = paiYama[i].paiNo;
	}
}
//==============================================================================
//牌山をシャッフルする関数【Mersenne Twister in JavaScriptを利用】
function shufflePaiYama(){
    var mt = new MersenneTwister();//Mersenne­Twister オブジェクトの初期化
	var i,j,k;
	for(i=135;i>0;i--){
    	j = mt.nextInt(0, 135);  // 0 以上 135 未満の乱数(整数)を発生させる
        k = yama[i];//変数kに退避
		yama[i] = yama[j];//乱数で発生した番地の牌を代入する
		yama[j] = k;//変数Kから戻す
	}
}
//==============================================================================
$("#PaiMakeBtn").click(function() {
	//牌山を生成する関数を呼び出す
	makePaiYama();

	//生成した牌山を表示する
	(function (){
		var i;
		var haipai="";
		for(i=0;i<136;i++){
			if(i==16||i==33||i==50||i==67||i==84||i==101||i==118||i==135){
				haipai += yama[i] + "<br>";//17牌毎に改行する
			}else{
				haipai += yama[i] + ",";//カンマを追加する
			}
		}
		$("#paiYama1").empty().append(haipai);
	})();

	//牌山をシャッフルする関数を呼び出す
	shufflePaiYama();

	//シャッフルした牌山を表示する
	(function (){
		var i;
		var haipai="";
		for(i=0;i<136;i++){
			if(i==16||i==33||i==50||i==67||i==84||i==101||i==118||i==135){
				haipai += yama[i] + "<br>";//17牌毎に改行する
			}else{
				haipai += yama[i] + ",";//カンマを追加する
			}
		}
		$("#paiYama2").empty().append(haipai);
	})();
});
//==============================================================================

おすすめレンタルサーバー

エックスサーバー|高速・高機能レンタルサーバー

オールSSDの快適ハイスペック環境」「国内管理、大容量バックボーン」「独自SSLが無料」「FastCGIなどの高速化機能」「最新のPHP7を実装」など、高機能・高コストパフォーマンスなレンタルサーバーです。※当サイトも「エックスサーバー」で運用しています。

ウザク式麻雀牌効率学習

麻雀の牌効率を覚えたい初心者向け決定版。読者に大好評の麻雀 定石「何切る」301選麻雀 傑作「何切る」300選の著者が「初心者が何切るを解く前に読んでもらうことで、効率よく学習してもらいたい」という願いを込めた一冊です。

-小粒プログラミング, 牌山
-