チートイツと国士無双を除く通常手のアガリ判定とシャンテン数を再帰呼び出しで算出する処理を紹介します。
プログラムの解説と実行
アガリ判定とシャンテン数のチェックをする処理を紹介します。アガリ判定とシャンテン数は手牌(tehai)の中身を調べて行います。国士無双、チートイツ、通常手(4面子+1雀頭)の3つの処理に分けて調査します。
通常手のシャンテン数を求める
麻雀は「4メンツ+1雀頭」を集めるゲームです(通常手の場合)。メンツ(コーツやシュンツ)とメンツ候補になるターツやトイツが増える毎にシャンテン数は減っていきます。シャンテン数を求める式は次のようになります。
上記の式の場合、テンパイは「0」でアガリは「-1」になります。なお、国士無双とチートイツの扱いは別になり、シャンテン数を求める計算式も異なります。このページでは今回は扱いません。
- 雀頭を抜き出す→シュンツを抜き出す→コーツを抜き出す→ターツを抜き出す
- 雀頭を抜き出す→コーツを抜き出す→シュンツを抜き出す→ターツを抜き出す
- コーツを抜き出す→シュンツを抜き出す→ターツを抜き出す
- シュンツを抜き出す→コーツを抜き出す→ターツを抜き出す
各手順で算出されたシャンテン数を比較して最小のシャンテン数を結果として採用します。プログラムでは手牌の元となるtehai配列から完全に独立したコーツとシュンツを前もって抜いてからクローン(tempTehai配列)を生成し、再帰呼び出しでシャンテン数を計算していきます。
大まかな手順はこんな感じです。コードには手を入れないといけませんが、参考になると幸いです。
リンク牌理/牌効率学習ツール
シャンテン数を求めてみよう
手牌を作ってプログラムの動作を確認してみましょう。操作は簡単です。牌をクリックすると下のパネル内に牌が追加されていくます。[シャンテン数を調べる]ボタンを押すとシャンテン数を調査する手順が表示されます。
面子多々(めんつたーた)の場合の処理
ターツの抜き出しとカウントを途中で中断して処理を抜けています。したがって算出したターツ数が実際のターツ数と異ります。
たとえば、下の手牌は「2メンツ+3ターツ+1雀頭」ですが、プログラム内部ではメンツとターツの合計が4つになった時点で処理を抜けて「ターツ数 = 2」を返すようにしています。
if(mentsu_suu+taatsu_suu<4){//メンツとターツの合計は4まで
現状での不具合と解決策(解決済2015/11/15)
カンツが混じっている場合シャンテン数が正確に算出されない不具合が見つかっています(2015年3月時点)。下の手牌のシャンテン数は1にならないといけないのですが、結果はテンパイになってしまいます。
これは「東がコーツ、残り1枚の東の単騎待ち」に解釈されるためです。いずれ解決しないといけませんが、今回はとりあえずここまでにしておきます。
JavaScriptソースコード
本記事で紹介したサンプルプログラムをダウンロードできます。
ダウンロードをする前にお読みください
- サイトで紹介している記事の内容や公開しているプログラムの動作は100%保障するものではありません。
- 当プログラム使用による如何なる不具合やトラブル、損害の責任も負いかねます。
- 当プログラムは断り無く内容が変わることがあります。
- 当プログラムを別サイトで配布することは禁止します。
- サポートはいたしません。
- 自己責任にてご利用くださいませ。
以上をご確認の上、プログラムのダウンロードをお願いいたします。
- 本プログラムはjQueryを組み込んだ状態でのみ動作します。ご注意ください。
- アガリ判定とシャンテン数を算出する処理は「麻雀C言語プログラム集」のシャンテン数を参考にしています。感謝です。
サンプルプログラムのソースコード
ソースコードは折りたたんであります。[+]を押すと、折りたたまれたソースコードが開きます。[-]を押すと、コードは折りたたまれます。
+ program_019.jsを開く
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | //============================================================================ //牌の配列:JSON形式 //============================================================================ var paiType = [ {"No":0,"paiName":"赤五萬","cssSprite":"man0","paigaNo":4}, {"No":1,"paiName":"一萬","cssSprite":"man1","paigaNo":0}, {"No":2,"paiName":"二萬","cssSprite":"man2","paigaNo":1}, {"No":3,"paiName":"三萬","cssSprite":"man3","paigaNo":2}, {"No":4,"paiName":"四萬","cssSprite":"man4","paigaNo":3}, {"No":5,"paiName":"五萬","cssSprite":"man5","paigaNo":5}, {"No":6,"paiName":"六萬","cssSprite":"man6","paigaNo":6}, {"No":7,"paiName":"七萬","cssSprite":"man7","paigaNo":7}, {"No":8,"paiName":"八萬","cssSprite":"man8","paigaNo":8}, {"No":9,"paiName":"九萬","cssSprite":"man9","paigaNo":9}, {"No":10,"paiName":"赤五筒","cssSprite":"pin0","paigaNo":14}, {"No":11,"paiName":"一筒","cssSprite":"pin1","paigaNo":10}, {"No":12,"paiName":"二筒","cssSprite":"pin2","paigaNo":11}, {"No":13,"paiName":"三筒","cssSprite":"pin3","paigaNo":12}, {"No":14,"paiName":"四筒","cssSprite":"pin4","paigaNo":13}, {"No":15,"paiName":"五筒","cssSprite":"pin5","paigaNo":15}, {"No":16,"paiName":"六筒","cssSprite":"pin6","paigaNo":16}, {"No":17,"paiName":"七筒","cssSprite":"pin7","paigaNo":17}, {"No":18,"paiName":"八筒","cssSprite":"pin8","paigaNo":18}, {"No":19,"paiName":"九筒","cssSprite":"pin9","paigaNo":19}, {"No":20,"paiName":"赤五索","cssSprite":"sou0","paigaNo":24}, {"No":21,"paiName":"一索","cssSprite":"sou1","paigaNo":20}, {"No":22,"paiName":"二索","cssSprite":"sou2","paigaNo":21}, {"No":23,"paiName":"三索","cssSprite":"sou3","paigaNo":22}, {"No":24,"paiName":"四索","cssSprite":"sou4","paigaNo":23}, {"No":25,"paiName":"五索","cssSprite":"sou5","paigaNo":25}, {"No":26,"paiName":"六索","cssSprite":"sou6","paigaNo":26}, {"No":27,"paiName":"七索","cssSprite":"sou7","paigaNo":27}, {"No":28,"paiName":"八索","cssSprite":"sou8","paigaNo":28}, {"No":29,"paiName":"九索","cssSprite":"sou9","paigaNo":29}, {"No":30,"paiName":"裏","cssSprite":"ji0","paigaNo":30}, {"No":31,"paiName":"東","cssSprite":"ji1","paigaNo":31}, {"No":32,"paiName":"南","cssSprite":"ji2","paigaNo":32}, {"No":33,"paiName":"西","cssSprite":"ji3","paigaNo":33}, {"No":34,"paiName":"北","cssSprite":"ji4","paigaNo":34}, {"No":35,"paiName":"白","cssSprite":"ji5","paigaNo":35}, {"No":36,"paiName":"發","cssSprite":"ji6","paigaNo":36}, {"No":37,"paiName":"中","cssSprite":"ji7","paigaNo":37} ]; //============================================================================ //グローバル変数 //============================================================================ var tehai = new Array(37);//手牌の配列:37種 tehai = [0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]; var tempTehai = new Array(37);//preTempTehai配列のクローン var red5manCount;//赤5マンの数 var red5pinCount;//赤5ピンの数 var red5souCount;//赤5ソウの数 var toitsu_suu;//トイツ数 var koutsu_suu;//コーツ数 var shuntsu_suu;//シュンツ数 var taatsu_suu;//ターツ数 var mentsu_suu;//メンツ数 var syanten_temp;//シャンテン数(作業用用) var syanten_normal;//シャンテン数(結果用) var kanzen_koutsu_suu;//完全コーツ数 var kanzen_shuntsu_suu;//完全シュンツ数 var kanzen_Koritsu_suu;//完全孤立牌数 //============================================================================ //赤ドラの有無をチェックしてカウントする処理【赤ドラのカウントを事前にしなかった場合に使う】 //各赤ドラはtehai配列の0,10,20番地にあるものとする //============================================================================ function checkReddora(){ //グローバル変数の初期化 red5manCount=0;//赤5マンの数 red5pinCount=0;//赤5ピンの数 red5souCount=0;//赤5ソウの数 //赤五萬の有無をチェックしてカウントする if(tehai[0]){ red5manCount+=tehai[0];//赤五萬の牌数を追加 } //赤五筒の有無をチェックしてカウントする if(tehai[10]){ red5pinCount+=tehai[10];//赤五筒の牌数を追加 } //赤五索の有無をチェックしてカウントする if(tehai[20]){ red5souCount+=tehai[20];//赤五索の牌数を追加 } } //============================================================================ //赤ドラの有無をチェックして配列操作する処理【シャンテン数やテンパイチェックを実行する前に使う】 //tehai配列内を0→5、10→15、20→25 //============================================================================ function moveReddora(){ //赤五萬の有無をチェックして番地を移動させる処理 if(tehai[0]&&red5manCount){ tehai[5]+=tehai[0];//赤五萬の牌数を五萬の番地5に追加 tehai[0]=0;//番地0を初期化 } //赤五筒の有無をチェックして番地を移動させる処理 if(tehai[10]&&red5pinCount){ tehai[15]+=tehai[10];//赤五筒の牌数を五筒の番地15に追加 tehai[10]=0;//番地10を初期化 } //赤五索の有無をチェックして番地を移動させる処理 if(tehai[20]&&red5souCount){ tehai[25]+=tehai[20];//赤五索の牌数を五索の番地25に追加 tehai[20]= 0;//番地20を初期化 } } //============================================================================ //赤ドラの有無をチェックして配列内の元の番地に戻す処理 //tehai配列内を5→0、15→10、25→20 //============================================================================ function removeReddora(){ //赤五萬の有無をチェックして番地を移動:5→0 if(!tehai[0]&&tehai[5]&&red5manCount){ tehai[5]--; tehai[0]++; } //赤五筒の有無をチェックして番地を移動:15→10 if(!tehai[10]&&tehai[15]&&red5pinCount){ tehai[15]--; tehai[10]++; } //赤五索の有無をチェックして番地を移動:25→20 if(!tehai[20]&&tehai[25]&&red5souCount){ tehai[25]--; tehai[20]++; } } //============================================================================ //アガリ判定とシャンテン数を返す関数 //============================================================================ function syantenCheck(){ var i; //初期化 toitsu_suu=0;//トイツ数 koutsu_suu=0;//コーツ数 shuntsu_suu=0;//シュンツ数 taatsu_suu=0;//ターツ数 mentsu_suu=0;//メンツ数 syanten_temp=0;//シャンテン数(計算用) syanten_normal=8;//シャンテン数(結果用) kanzen_koutsu_suu=0;//完全コーツ数 kanzen_shuntsu_suu=0;//完全シュンツ数 kanzen_Koritsu_suu=0;//完全孤立牌数 tempTehai = $.extend(true, [], tehai);//tehai配列のバックアップを取る //前もって完全なシュンツ・コーツ・孤立牌を抜いておく kanzen_koutsu_suu = KanzenKoutsuCheck();//完全に独立したコーツを抜き出して個数を返す関数呼び出し kanzen_shuntsu_suu = kanzenShuntsuCheck();//完全に独立したシュンツを抜き出して個数を返す関数呼び出し kanzen_Koritsu_suu=KanzenKoritsuCheck();//完全に独立した孤立牌を抜き出して個数を返す関数の実行 //雀頭抜き出し→コーツ抜き出し→シュンツ抜き出し→ターツ候補抜き出し for(i=1;i<38;i++){ //頭抜き出し if(tempTehai[i]>=2){ toitsu_suu++; tempTehai[i]-=2; mentu_cut1(1); tempTehai[i]+=2; toitsu_suu--; } }//for //【不要っぽい】雀頭抜き出し→シュンツ抜き出し→コーツ抜き出し→ターツ候補抜き出し //for(i=1;i<38;i++){ // //頭抜き出し // if(tempTehai[i]>=2){ // toitsu_suu++; // tempTehai[i]-=2; // mentu_cut2(1); // tempTehai[i]+=2; // toitsu_suu--; // } //}//for toitsu_suu=0; //【雀頭が無い場合の処理】コーツ抜き出し→シュンツ抜き出し→ターツ候補抜き出し for(var i=1;i<38;i++){ mentu_cut1(1); //【不要っぽい】雀頭抜き出し→シュンツ抜き出し→コーツ抜き出し→ターツ候補抜き出し //mentu_cut2(1); return syanten_normal;//最終的な結果 } //============================================================================ //メンツ抜き出し1【→コーツ抜き出し→シュンツ抜き出し】 //============================================================================ function mentu_cut1(i){ for(var j=i;j<30;j++){//※字牌のコーツは完全コーツ処理で抜いているの数牌だけで良い //コーツ抜き出し if(tempTehai[j]>=3){ mentsu_suu++; koutsu_suu++; tempTehai[j]-=3; mentu_cut1(j); tempTehai[j]+=3; koutsu_suu--; }//if //シュンツ抜き出し if(tempTehai[j]&&tempTehai[j+1]&&tempTehai[j+2]&&j<28){ shuntsu_suu++; tempTehai[j]--; tempTehai[j+1]--; tempTehai[j+2]--; mentu_cut1(j);//自身を呼び出す tempTehai[j]++; tempTehai[j+1]++; tempTehai[j+2]++; shuntsu_suu--; }//if }//for taatu_cut(1);//ターツ抜きへ return; } //============================================================================ //メンツ抜き出し2【シュンツ抜き出し→コーツ抜き出し】 //============================================================================ function mentu_cut2(i){ for(var j=i;j<30;j++){//※字牌のコーツは完全コーツ処理で抜いているの数牌だけで良い //シュンツ抜き出し if(tempTehai[j]&&tempTehai[j+1]&&tempTehai[j+2]&&j<28){ shuntsu_suu++; tempTehai[j]--; tempTehai[j+1]--; tempTehai[j+2]--; mentu_cut2(j);//自身を呼び出す tempTehai[j]++; tempTehai[j+1]++; tempTehai[j+2]++; shuntsu_suu--; }//if //コーツ抜き出し if(tempTehai[j]>=3){ mentsu_suu++; koutsu_suu++; tempTehai[j]-=3; mentu_cut2(j); tempTehai[j]+=3; koutsu_suu--; }//if }//for taatu_cut(1);//ターツ抜きへ return; } //============================================================================ //ターツ抜き出し //============================================================================ function taatu_cut(i){ for(var j=i;j<38;j++){ mentsu_suu=kanzen_koutsu_suu+koutsu_suu+kanzen_shuntsu_suu+shuntsu_suu; if(mentsu_suu+taatsu_suu<4){//メンツとターツの合計は4まで //トイツ抜き出し if(tempTehai[j]==2){ taatsu_suu++; tempTehai[j]-=2; taatu_cut(j); tempTehai[j]+=2; taatsu_suu--; } //リャンメン・ペンチャン抜き出し if(tempTehai[j]&&tempTehai[j+1]&&j<29&&j%10<9){ taatsu_suu++; tempTehai[j]--; tempTehai[j+1]--; taatu_cut(j); tempTehai[j]++; tempTehai[j+1]++; taatsu_suu--; } //カンチャン抜き出し if(tempTehai[j]&&!tempTehai[j+1]&&tempTehai[j+2]&&j<28&&j%10<8){ taatsu_suu++; tempTehai[j]--; tempTehai[j+2]--; taatu_cut(j); tempTehai[j]++; tempTehai[j+2]++; taatsu_suu--; } }//if }//for syanten_temp=8-mentsu_suu*2-taatsu_suu-toitsu_suu; if(syanten_temp<syanten_normal) {syanten_normal=syanten_temp;} return; }//function_end //============================================================================ //完全コーツを抜き出して個数を返す関数 //============================================================================ function KanzenKoutsuCheck(){ var Kanzenkoutsu_suu = 0; var i,j; //字牌の完全コーツを抜き出す for(i=31;i<38;i++){ if(tempTehai[i]>=3){ tempTehai[i]-=3; Kanzenkoutsu_suu++; } }//for //数牌の完全コーツを抜き出す for(i=0;i<30;i+=10){ if(tempTehai[i+1]>=3&&!tempTehai[i+2]&&!tempTehai[i+3]){ tempTehai[i+1]-=3; Kanzenkoutsu_suu++; } if(!tempTehai[i+1]&&tempTehai[i+2]>=3&&!tempTehai[i+3]&&!tempTehai[i+4]){ tempTehai[i+2]-=3; Kanzenkoutsu_suu++; } //3~7の完全コーツを抜く for(j=0;j<5;j++){ if(!tempTehai[i+j+1]&&!tempTehai[i+j+2]&&tempTehai[i+j+3]>=3&&!tempTehai[i+j+4]&&!tempTehai[i+j+5]){ tempTehai[i+j+3]-=3; Kanzenkoutsu_suu++; } } if(!tempTehai[i+6]&&!tempTehai[i+7]&&tempTehai[i+8]>=3&&!tempTehai[i+9]){ tempTehai[i+8]-=3; Kanzenkoutsu_suu++; } if(!tempTehai[i+7]&&!tempTehai[i+8]&&tempTehai[i+9]>=3){ tempTehai[i+9]-=3; Kanzenkoutsu_suu++; } }//for return Kanzenkoutsu_suu; } //============================================================================ //完全シュンツを抜き出して個数を返す関数 //============================================================================ function kanzenShuntsuCheck(){ var kanzenshuntsu_suu=0; var i; //123,456のような完全に独立したシュンツを抜き出すための処理 ////【注意】番地0,10,20,30が「0」の必要あり。事前に赤ドラを移動させる処理をしておく。 for(i=0;i<30;i+=10){//マンズ→ピンズ→ソーズ //123▲▲ if(tempTehai[i+1]==2&&tempTehai[i+2]==2&&tempTehai[i+3]==2&&!tempTehai[i+4]&&!tempTehai[i+5]){ tempTehai[i+1]-=2; tempTehai[i+2]-=2; tempTehai[i+3]-=2; kanzenshuntsu_suu+=2; } //▲234▲▲ if(!tempTehai[i+1]&&tempTehai[i+2]==2&&tempTehai[i+3]==2&&tempTehai[i+4]==2&&!tempTehai[i+5]&&!tempTehai[i+6]){ tempTehai[i+2]-=2; tempTehai[i+3]-=2; tempTehai[i+4]-=2; kanzenshuntsu_suu+=2; } //▲▲345▲▲ if(!tempTehai[i+1]&&!tempTehai[i+2]&&tempTehai[i+3]==2&&tempTehai[i+4]==2&&tempTehai[i+5]==2&&!tempTehai[i+6]&&!tempTehai[i+7]){ tempTehai[i+3]-=2; tempTehai[i+4]-=2; tempTehai[i+5]-=2; kanzenshuntsu_suu+=2; } //▲▲456▲▲ if(!tempTehai[i+2]&&!tempTehai[i+3]&&tempTehai[i+4]==2&&tempTehai[i+5]==2&&tempTehai[i+6]==2&&!tempTehai[i+7]&&!tempTehai[i+8]){ tempTehai[i+4]-=2; tempTehai[i+5]-=2; tempTehai[i+6]-=2; kanzenshuntsu_suu+=2; } //▲▲567▲▲ if(!tempTehai[i+3]&&!tempTehai[i+4]&&tempTehai[i+5]==2&&tempTehai[i+6]==2&&tempTehai[i+7]==2&&!tempTehai[i+8]&&!tempTehai[i+9]){ tempTehai[i+5]-=2; tempTehai[i+6]-=2; tempTehai[i+7]-=2; kanzenshuntsu_suu+=2; } //▲▲678▲ if(!tempTehai[i+4]&&!tempTehai[i+5]&&tempTehai[i+6]==2&&tempTehai[i+7]==2&&tempTehai[i+8]==2&&!tempTehai[i+9]){ tempTehai[i+6]-=2; tempTehai[i+7]-=2; tempTehai[i+8]-=2; kanzenshuntsu_suu+=2; } //▲▲789 if(!tempTehai[i+5]&&!tempTehai[i+6]&&tempTehai[i+7]==2&&tempTehai[i+8]==2&&tempTehai[i+9]==2){ tempTehai[i+7]-=2; tempTehai[i+8]-=2; tempTehai[i+9]-=2; kanzenshuntsu_suu+=2; } } for(i=0;i<30;i+=10){//マンズ→ピンズ→ソーズ //123▲▲ if(tempTehai[i+1]==1&&tempTehai[i+2]==1&&tempTehai[i+3]==1&&!tempTehai[i+4]&&!tempTehai[i+5]){ tempTehai[i+1]--; tempTehai[i+2]--; tempTehai[i+3]--; kanzenshuntsu_suu++; } //▲234▲▲ if(!tempTehai[i+1]&&tempTehai[i+2]==1&&tempTehai[i+3]==1&&tempTehai[i+4]==1&&!tempTehai[i+5]&&!tempTehai[i+6]){ tempTehai[i+2]--; tempTehai[i+3]--; tempTehai[i+4]--; kanzenshuntsu_suu++; } //▲▲345▲▲ if(!tempTehai[i+1]&&!tempTehai[i+2]&&tempTehai[i+3]==1&&tempTehai[i+4]==1&&tempTehai[i+5]==1&&!tempTehai[i+6]&&!tempTehai[i+7]){ tempTehai[i+3]--; tempTehai[i+4]--; tempTehai[i+5]--; kanzenshuntsu_suu++; } //▲▲456▲▲ if(!tempTehai[i+2]&&!tempTehai[i+3]&&tempTehai[i+4]==1&&tempTehai[i+5]==1&&tempTehai[i+6]==1&&!tempTehai[i+7]&&!tempTehai[i+8]){ tempTehai[i+4]--; tempTehai[i+5]--; tempTehai[i+6]--; kanzenshuntsu_suu++; } //▲▲567▲▲ if(!tempTehai[i+3]&&!tempTehai[i+4]&&tempTehai[i+5]==1&&tempTehai[i+6]==1&&tempTehai[i+7]==1&&!tempTehai[i+8]&&!tempTehai[i+9]){ tempTehai[i+5]--; tempTehai[i+6]--; tempTehai[i+7]--; kanzenshuntsu_suu++; } //▲▲678▲ if(!tempTehai[i+4]&&!tempTehai[i+5]&&tempTehai[i+6]==1&&tempTehai[i+7]==1&&tempTehai[i+8]==1&&!tempTehai[i+9]){ tempTehai[i+6]--; tempTehai[i+7]--; tempTehai[i+8]--; kanzenshuntsu_suu++; } //▲▲789 if(!tempTehai[i+5]&&!tempTehai[i+6]&&tempTehai[i+7]==1&&tempTehai[i+8]==1&&tempTehai[i+9]==1){ tempTehai[i+7]--; tempTehai[i+8]--; tempTehai[i+9]--; kanzenshuntsu_suu++; } } return kanzenshuntsu_suu; } //============================================================================ //完全孤立牌を抜き出して個数を返す関数 //============================================================================ function KanzenKoritsuCheck(){ var KanzenKoritsu_suu=0; var i,j; //字牌の完全孤立牌を抜き出す for(i=31;i<38;i++){ if(tempTehai[i]==1){ tempTehai[i]--; KanzenKoritsu_suu++; } } //数牌の完全孤立牌を抜き出す for(i=0;i<30;i+=10){//マンズ→ピンズ→ソーズ //1の孤立牌を抜く if(tempTehai[i+1]==1&&!tempTehai[i+2]&&!tempTehai[i+3]){ tempTehai[i+1]--; KanzenKoritsu_suu++; } //2の完全孤立牌を抜く if(!tempTehai[i+1]&&tempTehai[i+2]==1&&!tempTehai[i+3]&&!tempTehai[i+4]){ tempTehai[i+2]--; KanzenKoritsu_suu++; } //3~7の完全孤立牌を抜く for(j=0;j<5;j++){ if(!tempTehai[i+j+1]&&!tempTehai[i+j+2]&&tempTehai[i+j+3]==1&&!tempTehai[i+j+4]&&!tempTehai[i+j+5]){ tempTehai[i+j+3]--; KanzenKoritsu_suu++; } } //8の完全孤立牌を抜く if(!tempTehai[i+6]&&!tempTehai[i+7]&&tempTehai[i+8]==1&&!tempTehai[i+9]){ tempTehai[i+8]--; KanzenKoritsu_suu++; } //9の完全孤立牌を抜く if(!tempTehai[i+7]&&!tempTehai[i+8]&&tempTehai[i+9]==1){ tempTehai[i+9]--; KanzenKoritsu_suu++; } } return KanzenKoritsu_suu; } //============================================================================ //抜き出した牌とシャンテン数を出力させる処理【動作チェック用】 //============================================================================ $("#SyantenCheckBtn").click(function() { $("#paiTehaiSyantenCheck").empty(); moveReddora();//赤ドラを配列内で移動させる var syanten_suu = syantenCheck();//syantenCheck()の動作テスト用関数 $("#paiTehaiSyanten").empty().append("シャンテン数 = " + syanten_suu); }); //============================================================================ |
+ paiput2.jsを開く
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | //============================================================================ //牌画を操作するための配列:JSON形式 //============================================================================ var paigaType = [ {"No":0,"paiName":"一萬","cssSprite":"man1","paigaNo":1}, {"No":1,"paiName":"二萬","cssSprite":"man2","paigaNo":2}, {"No":2,"paiName":"三萬","cssSprite":"man3","paigaNo":3}, {"No":3,"paiName":"四萬","cssSprite":"man4","paigaNo":4}, {"No":4,"paiName":"赤五萬","cssSprite":"man0","paigaNo":0}, {"No":5,"paiName":"五萬","cssSprite":"man5","paigaNo":5}, {"No":6,"paiName":"六萬","cssSprite":"man6","paigaNo":6}, {"No":7,"paiName":"七萬","cssSprite":"man7","paigaNo":7}, {"No":8,"paiName":"八萬","cssSprite":"man8","paigaNo":8}, {"No":9,"paiName":"九萬","cssSprite":"man9","paigaNo":9}, {"No":10,"paiName":"一筒","cssSprite":"pin1","paigaNo":11}, {"No":11,"paiName":"二筒","cssSprite":"pin2","paigaNo":12}, {"No":12,"paiName":"三筒","cssSprite":"pin3","paigaNo":13}, {"No":13,"paiName":"四筒","cssSprite":"pin4","paigaNo":14}, {"No":14,"paiName":"赤五筒","cssSprite":"pin0","paigaNo":10}, {"No":15,"paiName":"五筒","cssSprite":"pin5","paigaNo":15}, {"No":16,"paiName":"六筒","cssSprite":"pin6","paigaNo":16}, {"No":17,"paiName":"七筒","cssSprite":"pin7","paigaNo":17}, {"No":18,"paiName":"八筒","cssSprite":"pin8","paigaNo":18}, {"No":19,"paiName":"九筒","cssSprite":"pin9","paigaNo":19}, {"No":20,"paiName":"一索","cssSprite":"sou1","paigaNo":21}, {"No":21,"paiName":"二索","cssSprite":"sou2","paigaNo":22}, {"No":22,"paiName":"三索","cssSprite":"sou3","paigaNo":23}, {"No":23,"paiName":"四索","cssSprite":"sou4","paigaNo":24}, {"No":24,"paiName":"赤五索","cssSprite":"sou0","paigaNo":20}, {"No":25,"paiName":"五索","cssSprite":"sou5","paigaNo":25}, {"No":26,"paiName":"六索","cssSprite":"sou6","paigaNo":26}, {"No":27,"paiName":"七索","cssSprite":"sou7","paigaNo":27}, {"No":28,"paiName":"八索","cssSprite":"sou8","paigaNo":28}, {"No":29,"paiName":"九索","cssSprite":"sou9","paigaNo":29}, {"No":30,"paiName":"裏","cssSprite":"ji0","paigaNo":30}, {"No":31,"paiName":"東","cssSprite":"ji1","paigaNo":31}, {"No":32,"paiName":"南","cssSprite":"ji2","paigaNo":32}, {"No":33,"paiName":"西","cssSprite":"ji3","paigaNo":33}, {"No":34,"paiName":"北","cssSprite":"ji4","paigaNo":34}, {"No":35,"paiName":"白","cssSprite":"ji5","paigaNo":35}, {"No":36,"paiName":"發","cssSprite":"ji6","paigaNo":36}, {"No":37,"paiName":"中","cssSprite":"ji7","paigaNo":37}, ]; //============================================================================ //グローバル変数 //============================================================================ var PaiCount = 0; //入力された牌の枚数 var PaiNo =[];//牌画表示用 //============================================================================ //牌画を挿入する関数 //============================================================================ $("span","#haiga").on('click', function(event){ var paiCountMax = 14;//手牌最大数 var paiNo = $(this).attr("name"); //牌の番号を取得 var paiName = $(this).attr("class"); //CSSスプライト用のクラス名を取得 if(PaiCount<paiCountMax){ if(tehai[paiNo]>3){ alert("5枚以上の同種牌を置くことはできません。"); return false; }else{ if(paiNo===0&&red5manCount==1||paiNo==10&&red5pinCount==1||paiNo==20&&red5souCount==1){ alert("赤ドラは各色1枚までです。"); return false; } tehai[paiNo] ++;//手牌 if(paiNo%10===0){checkReddora();}//赤ドラのチェック //PaiNo[PaiCount] = paiNo;//表示用手牌 PaiNo[PaiCount] = paiType[paiNo].paigaNo;//表示用手牌 paiSet(PaiCount,paiName);//牌画を表示させる関数を呼び出す PaiCount ++; $("#paikazu").empty().append(PaiCount); } }else{ alert("これ以上は牌を置けません。"); return false; } }); //============================================================================ //牌を配置する関数 //============================================================================ function paiSet(i,paiName) { paiga = "<span class=\"" + paiName + "\"></span>";//cssスプライトの牌画を配置 var putNo = "#pai" + i; $(putNo ,"#paisu").append(paiga); return; } //============================================================================ //任意の牌を1つ消す処理 //============================================================================ $("td","#paisu").click(function() { var tdNo = $(this).attr("id"); //牌画を配置したセルのIDを取得 var paikazu = PaiNo.length; if(paikazu === 0){ alert("これ以上牌を消せません"); return; }else{ tdNo = tdNo.slice(3,5);//削って番号のみにする if(PaiNo[tdNo]==4){red5manCount--;} if(PaiNo[tdNo]==14){red5pinCount--;} if(PaiNo[tdNo]==24){red5souCount--;} tehai[paigaType[PaiNo[tdNo]].paigaNo] --;//手牌 if(tdNo < paikazu){ $("td","#paisu").empty(); PaiNo.splice(tdNo,1); for(var i=0;i<paikazu -1 ;i++){ paiSet(i,paigaType[PaiNo[i]].cssSprite); } } PaiCount --; $("#paikazu").empty().append(PaiCount); } }); //============================================================================ //手牌を並べ替える処理 //============================================================================ $("#PaiSortBtn").on('click', function(event){ paiSort(); }); //============================================================================ //牌を並べ替える関数 //============================================================================ function paiSort() { //手牌を並び替える var paikazu = PaiNo.length; PaiNo.sort(function(b,c){ return b - c; }); $("td","#paisu").empty(); for (var i = 0;i<paikazu ;i++){ paiSet(i,paigaType[PaiNo[i]].cssSprite); } return; } //============================================================================ //リセット処理 //============================================================================ $("#PaiClreaBtn").on('click', function(event){ tehai = [0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]; PaiNo.length = 0;//牌を格納した配列の要素をすべて削除 PaiCount = 0;//カウントのリセット $("#paikazu").empty().append("0"); $("td","#paisu").empty(); $("#paiTehaiUkeire").empty(); $("#paiTehaiSyanten").empty(); red5manCount = 0;//赤5マンの数 red5pinCount = 0;//赤5ピンの数 red5souCount = 0;//赤5ソウの数 $("#paiTehaiSyantenCheck").empty(); }); //============================================================================ |
+ program_019.cssを開く
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | @charset "utf-8"; #paiTehai > span , #haiga > span, .haiga > span, td > span{ background-color:transparent; background-image:url(../images/pai.png); background-repeat:no-repeat; background-attachment:scroll; display:inline-block; } .man1{background-position:0px 0px;height:47px;width:31px;} .man2{background-position:-31px 0px;height:47px;width:31px;} .man3{background-position:-62px 0px;height:47px;width:31px;} .man4{background-position:-93px 0px;height:47px;width:31px;} .man5{background-position:-124px 0px;height:47px;width:31px;} .man6{background-position:-155px 0px;height:47px;width:31px;} .man7{background-position:-186px 0px;height:47px;width:31px;} .man8{background-position:-217px 0px;height:47px;width:31px;} .man9{background-position:-248px 0px;height:47px;width:31px;} .man0{background-position:-279px 0px;height:47px;width:31px;} .pin1{background-position:0px -47px;height:47px;width:31px;} .pin2{background-position:-31px -47px;height:47px;width:31px;} .pin3{background-position:-62px -47px;height:47px;width:31px;} .pin4{background-position:-93px -47px;height:47px;width:31px;} .pin5{background-position:-124px -47px;height:47px;width:31px;} .pin6{background-position:-155px -47px;height:47px;width:31px;} .pin7{background-position:-186px -47px;height:47px;width:31px;} .pin8{background-position:-217px -47px;height:47px;width:31px;} .pin9{background-position:-248px -47px;height:47px;width:31px;} .pin0{background-position:-279px -47px;height:47px;width:31px;} .sou1{background-position:0px -94px;height:47px;width:31px;} .sou2{background-position:-31px -94px;height:47px;width:31px;} .sou3{background-position:-62px -94px;height:47px;width:31px;} .sou4{background-position:-93px -94px;height:47px;width:31px;} .sou5{background-position:-124px -94px;height:47px;width:31px;} .sou6{background-position:-155px -94px;height:47px;width:31px;} .sou7{background-position:-186px -94px;height:47px;width:31px;} .sou8{background-position:-217px -94px;height:47px;width:31px;} .sou9{background-position:-248px -94px;height:47px;width:31px;} .sou0{background-position:-279px -94px;height:47px;width:31px;} .ji1{background-position:0px -141px;height:47px;width:31px;} .ji2{background-position:-31px -141px;height:47px;width:31px;} .ji3{background-position:-62px -141px;height:47px;width:31px;} .ji4{background-position:-93px -141px;height:47px;width:31px;} .ji5{background-position:-124px -141px;height:47px;width:31px;} .ji6{background-position:-155px -141px;height:47px;width:31px;} .ji7{background-position:-186px -141px;height:47px;width:31px;} .ji0{background-position:-217px -141px;height:47px;width:31px;} #haiga{ background-color:#173B0B; padding:5px 15px 3px 15px; margin-bottom:5px; color:#fff; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; } #pai0,#pai1,#pai2,#pai3{width:0;} table.style{margin-left:10px;} table.style tr td{background-color:#fff;} .style > thead > tr > td { vertical-align: bottom; border-bottom: 5px solid #ddd; } |
おすすめレンタルサーバー
エックスサーバー|高速・高機能レンタルサーバー
「オールSSDの快適ハイスペック環境」「国内管理、大容量バックボーン」「独自SSLが無料」「FastCGIなどの高速化機能」「最新のPHP7を実装」など、高機能・高コストパフォーマンスなレンタルサーバーです。※当サイトも「エックスサーバー」で運用しています。