はじめに
唐突にアウトプットしたさに駆られたのですが、書く内容が無かったので数カ月前に作ったポーカーについて書こうと思います。
機能定義
ポーカーのルールを満たしている
配列に53枚のカードを収納 シャッフルorランダムで5枚を限度に抽出 選択した枚数だけ引き直し
役が高い順から判定
ジョーカーはオールマイティ
ディーラー(CPU)は自動的に実行
抽出後の配列からこちらもランダムで5枚抽出
GUIで動く
交換したいカードをクリックすることで選択する
CPUの難易度設定
easyは交換しないnormalは交換する
事前準備
表示する画像の準備
いらすとやから拝借しました
以下のようにファイル名を付けます
##変数の用意
var cards = []; //山札
var my_hand = []; //自分の手札
var my_rank = 11; //自分の役
var cpu_rank = 11; //CPUの役
var my_rank_name; //自分の役名
var cpu_rank_name; //CPUの役名
var difficultyNum = 0; //難易度設定
#プログラミングの流れ
-山札の準備
-山札から手札を引きつつ表示する
-CPUの手札を引く
-手札を判定しつつ、役名を表示する
-CPUの手札を判定する
--選択した手札を交換する(任意)
--手札を判定する(任意)
--役名を表示する(任意)
-勝負結果を表示する
--難易度がNORMALの場合、CPUの手札を交換する
--CPUの手札を公開する
##山札の準備
//開始ボタン
start = () => {
initCard(); //山札セット
shuffleCard(); //山札シャッフル
first();
$("#startbutton").hide();
$("#changebutton").show();
$("#judgebutton").show();
}
//カードを山札にセット
initCard = () => {
x = 0;
for (i = 1; i <= 13; i++) {
cards[x] = new Card(0, i);
x++;
cards[x] = new Card(1, i);
x++;
cards[x] = new Card(2, i);
x++;
cards[x] = new Card(3, i);
x++;
}
cards[52] = new Card(4, 15);
}
//カードシャッフル
shuffleCard = () => {
for (i = 0; i < 53; i++) {
r = Math.floor(Math.random() * 13 * 4);
w = cards[i];
cards[i] = cards[r];
cards[r] = w;
}
}
function Card(mark, num) {
this.mark = mark;
this.num = num;
}
53枚のカードに画像のファイル名と同じようにスートと数字を与えます。
##山札から手札を引きつつ表示する
//カードを表示する関数
dispCard = (card) => {
let imgurl = "";
for (i = 0; i < card.length; i++) {
imgurl = `${card[i].mark}_${card[i].num}`;
// console.log(imgurl);
$("#disp").append(`<img src=img/${imgurl}.png alt=card${i}>`);
}
}
//山札から引きつつ山札削除&表示
draw = () => {
my_hand = cards.slice(0, 5);
cards.splice(0, 5);
dispCard(my_hand);
my_rank_name = rank(my_hand);
$("#rank_name").text(my_rank_name);
}
山札から先頭の5枚を取り出しつつ、山札から削除。
カードの変数からスートの値と数字の値を取り出し、imgタグの文字列を形成しブラウザ上に表示します。
##CPUの手札を引く
//CPUの手札準備
cpu_draw = () => {
cpu_hand = cards.slice(0, 5);
cards.splice(0, 5);
for (i = 0; i < 5; i++) {
$("#cpu_disp").append(`<img src = img/0_0.png alt=card${i}>`);
};
}
自分の手札と同じように山札から引くが、すべて裏面で表示する。
##手札を判定しつつ、役名を表示
//役判定&表示
rank = (my_hand, my_rank, my_rank_name) => {
my_rank = rank_judge(my_hand);
my_rank_name = disp_rank(my_rank, my_rank_name);
return my_rank_name;
}
###手札判定の詳細
//役判定
rank_judge = (my_hand) => {
let joker_flg = 0;
let cnt = 0;
let current_rank = 11;
sort(my_hand);
joker_flg = joker_judge(my_hand, joker_flg);
cnt = sameNum(my_hand);
current_rank = various_rank(my_hand, cnt, current_rank, joker_flg);
if (sameMark(my_hand)) {
if (current_rank > 5) {
current_rank = 5;
};
}
if (stairs_judge(my_hand, joker_flg)) {
if (sameMark(my_hand)) {
if (current_rank != 0) {
current_rank = rsf(my_hand);
}
} else {
if (current_rank > 6) {
current_rank = 6;
};
};
};
returnAce(my_hand);
if (joker_flg == 1) {
my_hand.push(new Card(4, 15));
};
return current_rank;
}
-手札を数字順に並べる
-ジョーカーの有無を調べる
--ジョーカーがあった場合、ジョーカーを削除し、--フラグを立てる。以後は4枚で判定
-同じ数字のカードの数を調べる
-階段以外の役の判定をする
-マークが全て同じかを調べる
-階段は作れるかを調べる
--ストレートフラッシュかを調べる
--ロイヤルストレートフラッシュかを調べる
-順番に判定していき、より高い役の判定が通れば随時役を更新していく
####手札を数字順に並べる
//最初に並べ替え
sort = (my_hand) => {
my_hand.sort(function (a, b) {
if (a.num < b.num) return -1;
if (a.num > b.num) return 1;
return 0;
});
}
####ジョーカーの有無を調べる
//JOKERフラグ判定
joker_judge = (my_hand, joker_flg) => {
if (my_hand[my_hand.length - 1].mark == 4) {
my_hand.pop();
joker_flg = 1;
};
return joker_flg;
}
ジョーカーはファイル名で数字を14としているので、ソートした場合5番目に現れます。
5番目のカードのスートが4かであるかでジョーカーの有無を判定します。
####同じ数字のカードの数を調べる
//同じ数字の枚数判定
sameNum = (my_hand) => {
let cnt = 0;
for (let i = my_hand.length; i >= 2; i--) {
if (my_hand[i - 1].num == my_hand[i - 2].num) {
cnt++;
};
};
return cnt;
}
隣り合う数字を比べ、同じ数字のカードの数を調べる
1ペアなら1、2ペアなら2、3カードなら2、フルハウスなら3、フォーカードなら3
####階段以外の役の判定をする
//階段以外の約判定
various_rank = (my_hand, cnt, current_rank, joker_flg) => {
switch (cnt) {
case 0:
switch (joker_flg) {
case 0:
current_rank = 10;
return current_rank;
break;
case 1:
current_rank = 9;
return current_rank;
break;
}
break;
case 1:
switch (joker_flg) {
case 0:
current_rank = 9;
return current_rank;
break;
case 1:
current_rank = 7;
return current_rank;
break;
}
break;
case 2:
if ((my_hand[0].num == my_hand[1].num && my_hand[1].num == my_hand[2].num) ||
(my_hand[1].num == my_hand[2].num && my_hand[2].num == my_hand[3].num) ||
(my_hand[my_hand.length - 1].num == my_hand[my_hand.length - 2].num && my_hand[my_hand.length - 2].num == my_hand[my_hand.length - 3].num)) {
switch (joker_flg) {
case 0:
current_rank = 7;
return current_rank;
break;
case 1:
current_rank = 3;
return current_rank;
break;
};
break;
} else {
switch (joker_flg) {
case 0:
current_rank = 8;
return current_rank;
break;
case 1:
current_rank = 4;
return current_rank;
break;
};
};
break;
case 3:
if (my_hand[1].num == my_hand[2].num && my_hand[2].num == my_hand[3].num) {
switch (joker_flg) {
case 0:
current_rank = 3;
return current_rank;
break;
case 1:
current_rank = 0;
return current_rank;
break;
};
break;
} else {
current_rank = 4;
return current_rank;
};
break;
};
}
####マークが全て同じかを調べる
//マークは全て同じ?
sameMark = (my_hand) => {
let i = 0;
while (my_hand[i].mark == my_hand[i + 1].mark) {
i++;
if (i == my_hand.length - 1) {
break;
};
};
if (i == my_hand.length - 1) {
return true;
} else {
return false;
};
}
####階段は作れるか?
//階段判定
stairs_judge = (my_hand, joker_flg) => {
if (stairs(my_hand)) {
return true;
} else if (joker_flg == 1) {
if (joker_stairs(my_hand)) {
return true;
} else {
changeAce(my_hand);
if (joker_stairs(my_hand)) {
return true;
} else {
return false;
};
};
} else {
changeAce(my_hand);
if (stairs(my_hand)) {
return true;
} else {
return false;
};
};
}
#####手札の数字は階段か?
//数字は階段?
stairs = (my_hand) => {
let i = my_hand.length;
while (my_hand[i - 1].num - my_hand[i - 2].num == 1) {
i--;
if (i == 1) {
break;
};
};
if (i == 1) {
return true;
} else {
return false;
};
}
#####Aを14に変えたら階段になるか?
//Aの変換関数
changeAce = (my_hand) => {
sort(my_hand);
while (my_hand[0].num == 1) {
my_hand[0].num += 13;
sort(my_hand);
};
}
//Aを戻す関数
returnAce = (my_hand) => {
sort(my_hand);
while (my_hand[my_hand.length - 1].num == 14) {
my_hand[my_hand.length - 1].num -= 13;
sort(my_hand);
};
}
#####JOKERを使えば階段になる?
//JOKER使えば作れる?
joker_stairs = (my_hand) => {
if ((my_hand[3].num - my_hand[2].num == 2 && my_hand[2].num - my_hand[1].num == 1 && my_hand[1].num - my_hand[0].num == 1) ||
(my_hand[3].num - my_hand[2].num == 1 && my_hand[2].num - my_hand[1].num == 2 && my_hand[1].num - my_hand[0].num == 1) ||
(my_hand[3].num - my_hand[2].num == 1 && my_hand[2].num - my_hand[1].num == 1 && my_hand[1].num - my_hand[0].num == 2)) {
return true;
} else {
return false;
};
}
#####ロイヤルストレートフラッシュか?
//ロイヤルストレートフラッシュ判定
rsf = (my_hand, current_rank) => {
if (my_hand[0].num == 10 || my_hand[my_hand.length - 1].num == 14) {
current_rank = 1;
return current_rank;
} else {
current_rank = 2;
return current_rank;
};
}
###役名を表示する
//役名表示
disp_rank = (my_rank, my_rank_name) => {
switch (my_rank) {
case 0:
my_rank_name = "ファイブカード";
break;
case 1:
my_rank_name = "ロイヤルストレートフラッシュ";
break;
case 2:
my_rank_name = "ストレートフラッシュ";
break;
case 3:
my_rank_name = "フォーカード";
break;
case 4:
my_rank_name = "フルハウス";
break;
case 5:
my_rank_name = "フラッシュ";
break;
case 6:
my_rank_name = "ストレート";
break;
case 7:
my_rank_name = "スリーカード";
break;
case 8:
my_rank_name = "ツーペア";
break;
case 9:
my_rank_name = "ワンペア";
break;
case 10:
my_rank_name = "豚さん";
break;
};
// $("#rank_name").text(my_rank_name);
return my_rank_name;
}
##選択した手札を交換する
###選択した手札の色を変える
//表示カードをクリックしたら画像変更&class付与
$("#disp").on("click", "img", function () {
$(this).toggleClass("clicked");
});
.clicked{
background-color: blue;
opacity: 0.5; /** 画像の透明度 */
display: block;
}
###選択した手札を交換する
//交換するボタン
change = () => {
let cnt = $(".clicked").length;
for (let i = 0; i < cnt; i++) {
let card_src = $(`.clicked:eq(${i})`).attr("src");
card_src = card_src.split("_");
card_src[0] = card_src[0].replace("img/", "");
card_src[1] = card_src[1].replace(".png", "");
my_hand.some(function (v, i) {
if (v.mark == card_src[0] && v.num == card_src[1]) my_hand.splice(i, 1); //id:3の要素を削除
});
}
$(".clicked").remove();
let addarray = cards.slice(0, cnt);
dispCard(addarray);
Array.prototype.push.apply(my_hand, addarray);
cards.splice(0, cnt);
my_rank_name = rank(my_hand);
$("#rank_name").text(my_rank_name);
$("#changebutton").hide();
}
##勝負結果を表示する
###CPUの手札交換(難易度がNORMAL)
cpuChange =(cpu_hand,cpu_rank)=>{
cpu_hand = cpuSplice(cpu_hand,cpu_rank);
cpu_hand = cpuAdd(cpu_hand);
returnAce(cpu_hand);
return cpu_hand;
}
cpuSplice = (cpu_hand, cpu_rank) => {
cpu_rank = rank_judge(cpu_hand);
let joker_flg = 0;
joker_flg = joker_judge(cpu_hand, joker_flg);
switch (joker_flg) {
case 0:
cpu_hand = normalCpuChange(cpu_hand, cpu_rank);
return cpu_hand;
break;
case 1:
cpu_hand = jokerCpuChange(cpu_hand, cpu_rank);
returnAce(cpu_hand);
cpu_hand.push(new Card(4, 15));
return cpu_hand;
break;
};
console.log(cpu_hand);
}
cpuAdd =(cpu_hand)=>{
let addarray = cards.slice(0, 5 - cpu_hand.length);
cards.splice(0, 5 - cpu_hand.length);
Array.prototype.push.apply(cpu_hand, addarray);
console.log(cpu_hand);
return cpu_hand;
}
####CPUの手札の交換基準
--ジョーカーを持ってない
|
|-- 役がない -- マークが4つ揃ってる -- 1枚交換
| |
| -- 階段まであと1枚 -- 1枚交換
| |
| -- マークが3つ揃ってる -- 2枚交換
| |
| -- 全部変える
|
|-- 1ペア -- マークが4つ揃ってる -- 1枚交換
| |
| -- 階段まであと1枚 -- 1枚交換
| |
| -- ペア以外の3枚を変える
|
|-- 2ペア -- ペア以外の1枚を変える
|
|-- 3カード -- 3カード以外の2枚を変える
|
--ジョーカーを持っている
|
|-- 1ペア -- マークが3つ揃ってる -- 1枚交換
| |
| -- 階段まであと2枚 -- 1枚交換
| |
| -- 全部変える
|
-- 3カード -- ペア以外の2枚を変える
####ジョーカーを持っていないときの交換
normalCpuChange = (cpu_hand, cpu_rank) => {
sort(cpu_hand);
cpu_rank = rank_judge(cpu_hand);
switch (cpu_rank) {
case 10:
cpu_hand = sameMarkMock(cpu_hand);
if (cpu_hand.length == 4) {
return cpu_hand;
break;
}
cpu_hand = stairMock(cpu_hand);
if (cpu_hand.length == 4) {
return cpu_hand;
break;
}
cpu_hand = sameThreeMark(cpu_hand);
if (cpu_hand.length == 3) {
return cpu_hand;
break;
}
cpu_hand = [];
return cpu_hand;
break;
case 9:
cpu_hand = sameMarkMock(cpu_hand);
if (cpu_hand.length == 4) {
return cpu_hand;
break;
};
cpu_hand = stairMock(cpu_hand);
if (cpu_hand.length == 4) {
return cpu_hand;
break;
};
cpu_hand = onePairSampling(cpu_hand);
return cpu_hand;
break;
case 8:
cpu_hand = twoPairSampling(cpu_hand);
return cpu_hand;
break;
case 7:
cpu_hand = threeCardSampling(cpu_hand);
return cpu_hand;
break;
};
return cpu_hand;
}
#####同じマークが手札-1枚か?
//同じマークが手札-1枚か?
sameMarkMock = (cpu_hand) => {
let cpu_hand2 = cpu_hand.slice();
for (var i = 0; i < cpu_hand.length; i++) {
cpu_hand2.splice(i, 1);
// console.log(cpu_hand2);
if (sameMark(cpu_hand2)) {
return cpu_hand2;
break;
};
cpu_hand2 = cpu_hand.slice();
// console.log(cpu_hand2);
};
return cpu_hand2;
}
#####あと1枚で階段?
//あと1枚で階段?
stairMock = (cpu_hand, joker_flg) => {
sort(cpu_hand);
let cpu_hand2 = cpu_hand.slice();
joker_flg = 1;
for (var i = 0; i < 5; i++) {
cpu_hand2.splice(i, 1);
console.log(joker_flg);
if (stairs_judge(cpu_hand2, joker_flg)) {
returnAce(cpu_hand2);
return cpu_hand2;
break;
};
cpu_hand2 = cpu_hand.slice();
returnAce(cpu_hand);
};
joker_flg = 0;
return cpu_hand2;
}
#####同じマークが手札-2枚か?
//同じマークが手札-2枚か?
sameThreeMark = (cpu_hand) => {
let cpu_hand2 = cpu_hand.slice();
for (var i = 0; i < 4; i++) {
cpu_hand2.splice(i, 1);
let cpu_hand3 = cpu_hand2.slice();
for (var j = i; j < 4; j++) {
cpu_hand3.splice(j, 1);
if (sameMark(cpu_hand3)) {
return cpu_hand3;
break;
};
cpu_hand3 = cpu_hand2.slice();
};
if (cpu_hand.length == 3) {
return cpu_hand3;
break;
};
cpu_hand2 = cpu_hand.slice();
};
if (cpu_hand.length == 3) {
return cpu_hand3;
} else {
return cpu_hand2
};
}
#####ワンペアの時、ペアの2枚を抜き取る
//ワンペア時、ペアの2枚を取る
onePairSampling = (cpu_hand) => {
sort(cpu_hand);
for (var i = 0; cpu_hand[i].num != cpu_hand[i + 1].num; i++) {};
cpu_hand = cpu_hand.splice(i, 2);
return cpu_hand;
}
#####ツーペアの時、残りの1枚を抜き取る
//ツーペア時、残りの一枚を抜き取る
twoPairSampling = (cpu_hand) => {
sort(cpu_hand);
if (cpu_hand[1].num == cpu_hand[2].num && cpu_hand[3].num == cpu_hand[4].num) {
cpu_hand.splice(0, 1);
return cpu_hand;
} else if (cpu_hand[0].num == cpu_hand[1].num && cpu_hand[3].num == cpu_hand[4].num) {
cpu_hand.splice(2, 1);
return cpu_hand;
} else if (cpu_hand[0].num == cpu_hand[1].num && cpu_hand[2].num == cpu_hand[3].num) {
cpu_hand.splice(4, 1);
};
return cpu_hand;
}
#####スリーカード時に3枚を抜きだす
//スリーカード時に三枚を抜き出す
threeCardSampling = (cpu_hand) => {
sort(cpu_hand);
if (cpu_hand[0].num == cpu_hand[1].num && cpu_hand[1].num == cpu_hand[2].num) {
cpu_hand.splice(3, 2);
} else if (cpu_hand[1].num == cpu_hand[2].num && cpu_hand[2].num == cpu_hand[3].num) {
cpu_hand.splice(0, 1);
cpu_hand.splice(3, 1);
} else if (cpu_hand[2].num == cpu_hand[3].num && cpu_hand[3].num == cpu_hand[4].num) {
cpu_hand.splice(0, 2);
};
return cpu_hand;
}
####ジョーカーを持っているときの交換
jokerCpuChange = (cpu_hand, cpu_rank) => {
sort(cpu_hand);
switch (cpu_rank) {
case 9:
cpu_hand = sameMarkMock(cpu_hand);
if (cpu_hand.length == 3) {
return cpu_hand
break;
};
cpu_hand = onePairstairMock(cpu_hand);
if (cpu_hand.length == 3) {
return cpu_hand;
break;
};
cpu_hand = [];
return cpu_hand;
break;
case 7:
cpu_hand = jokerThreeCardSampling(cpu_hand);
return cpu_hand;
break;
};
}
#####ジョーカー所持時、あと2枚で階段ができるか?
onePairstairMock = (cpu_hand) => {
sort(cpu_hand);
let cpu_hand2 = cpu_hand.slice();
let joker_flg = 1;
for (var i = 0; i < 5; i++) {
cpu_hand2.splice(i, 1);
if (jokerStairsMockJudge(cpu_hand2, joker_flg)) {
returnAce(cpu_hand2);
return cpu_hand2;
break;
};
cpu_hand2 = cpu_hand.slice();
};
joker_flg = 0;
return cpu_hand2;
}
jokerStairsMockJudge = (my_hand, joker_flg) => {
if (stairs(my_hand)) {
return true;
} else if (joker_flg == 1) {
if (jokerStairsMock(my_hand)) {
return true;
} else {
changeAce(my_hand);
if (jokerStairsMock(my_hand)) {
return true;
} else {
return false;
};
};
} else {
changeAce(my_hand);
if (stairs(my_hand)) {
return true;
} else {
return false;
};
};
}
jokerStairsMock = (cpu_hand) => {
if ((cpu_hand[2].num - cpu_hand[1].num == 2 && cpu_hand[1].num - cpu_hand[0].num == 1) ||
(cpu_hand[2].num - cpu_hand[1].num == 1 && cpu_hand[1].num - cpu_hand[0].num == 2)) {
return true;
} else {
return false;
};
}
#####ジョーカー所持時、ペアの2枚を抜き出す
//ジョーカー所持時、ペア2枚を抜き出す
jokerThreeCardSampling = (cpu_hand) => {
sort(cpu_hand);
if (cpu_hand[0].num == cpu_hand[1].num) {
cpu_hand.splice(2, 2);
} else if (cpu_hand[1].num == cpu_hand[2].num) {
cpu_hand.splice(0, 1);
cpu_hand.splice(2, 1);
} else if (cpu_hand[2].num == cpu_hand[3].num) {
cpu_hand.splice(2, 2);
};
return cpu_hand;
}
###CPUの結果表示&勝敗表示
//勝ち負け判定
showdown = (my_rank, my_hand, cpu_rank, cpu_hand) => {
console.log(difficultyNum);
if(difficultyNum == 1){
cpu_hand = cpuChange(cpu_hand,cpu_rank);
};
let imgurl = "";
$("#cpu_disp img").remove();
for (i = 0; i < cpu_hand.length; i++) {
imgurl = `${cpu_hand[i].mark}_${cpu_hand[i].num}`;
// console.log(imgurl);
$("#cpu_disp").append(`<img src=img/${imgurl}.png alt=card${i}>`);
}
cpu_rank_name = rank(cpu_hand, cpu_rank, cpu_rank_name);
$("#cpu_rank_name").text(cpu_rank_name);
my_rank = rank_judge(my_hand);
cpu_rank = rank_judge(cpu_hand);
if (my_rank < cpu_rank) {
$("#result").text("win");
} else if (my_rank > cpu_rank) {
$("#result").text("lose");
} else {
$("#result").text("draw");
};
$("#judgebutton").hide();
$("#changebutton").hide();
$("#difficulty").hide();
$("#onemorebutton").show();
}
#終わりに
圧倒的駄記事になってしまった