総合練習
変数、条件分岐、配列(またはリスト)、列挙、メソッドとクラスを使い、以下のスクリプト作りましょう
ポーカー手札の判定
参考:ポーカー・ハンドの一覧
目標
手札にある5枚のカードを確認し、評価し、Debug.Logで判定を表示。
例:A♥ A♦ 10♣ 7♦ 3♠ - ワンペア
を表示するのは目標である
解析
必要のは:
- カード1枚を表すクラス。1(エース)から13(キング)までの数値と、スート(ハート、ダイヤ、クラブ、スペード)を扱うクラス「
Card」- 数字は整数でOK
- スートは列挙(
Heart, Diamond, Club, Spade)にする - 数値とスートを文字列に変換するためのメソッドが必要
ConvertToString()
Cardクラス(答え)
using UnityEngine;
// カードのスート(列挙)を宣言
public enum CardSuit
{
Heart,
Spade,
Diamond,
Club,
}
// Monobehaviour(Unityのクラス)ではないので
public class Card
{
// カードの数字
private int number;
// カードのスート
private CardSuit suit;
// カードの数字
public int Number
{
get { return number; }
set
{
// Mathf.Clampは最小値と最大値の制限をかける
number = Mathf.Clamp(value, 1, 13);
}
}
// カードのスート
public CardSuit Suit
{
get { return suit; }
set { suit = Suit; }
}
// 文字列にするメソッド
public string ConvertToString()
{
string result = "";
// 数字を文字列にする
if (number >= 1 && number <= 10) // 1~10までの場合
{
result = $"{number}"; // 数字を文字列にする
}
else if (number == 11) // 「J」の場合
{
result = "J";
}
else if (number == 12) // 「Q」の場合
{
result = "Q";
}
else // 「K」の場合
{
result = "K";
}
// 模様も文字列にして、連結する
switch(suit) // "suit"で切り替える
{
case CardSuit.Heart:
result += "♥"; // ハート
break;
case CardSuit.Diamond:
result += "♦"; // ダイヤ
break;
case CardSuit.Club:
result += "♣"; // クラブ
break;
case CardSuit.Spade:
result += "♠"; // スペード
break;
}
return result;
}
}
- 5枚のカード表すハンド「Hand」クラス
- 5枚を設定する方法が必要:
SetCard(int i, Card card);
- 5枚を設定する方法が必要:
Handクラス - SetCard メソッド
// 手札を表すクラス(C#クラス)
public class Hand
{
// カードの配列
Card[] cards = new Card[5]; // 5枚
// カードを設定
public void SetCard(int i, Card card)
{
cards[i] = card;
}
}
-
- 同じ数値のカード何枚があるのかよく知りたいので、そのメソッド(
CountSameNumber(int number))を作る:
- 同じ数値のカード何枚があるのかよく知りたいので、そのメソッド(
Handクラス - CountSameNumber メソッド
// 同じカードの枚数を数える
// number: 数えたい数値(1~13)
private int CountSameNumber(int number)
{
int count = 0;
foreach(Card c in cards)
{
if (c.Number == number)
count++;
}
return count;
}
-
- 各種の評価機能
IsOnePair()(ワンペアであるか?)
- 各種の評価機能
Handクラス - IsOnePair メソッド
// ワンペアであるか?
private bool IsOnePair()
{
// いずれかの2枚のカードは同じ数値だったら、ワンペアになる
for (int i = 1; i <= 13; i++)
{
if (CountSameCard(i) == 2)
return true;
}
return false;
}
-
-
IsTwoPair()(ツーペアであるか?)
-
Handクラス - IsTwoPair メソッド
// ツーペアであるか?
private bool IsTwoPair()
{
// ワンペアと似ているが、2つのペアは異なるカードじゃないとだめ
int match = 0; // 1つ目のペアの数値
for (int i = 1; i <= 13; i++)
{
if (CountSameCard(i) == 2)
match = i;
}
// なにも一致しなかった
if (match == 0)
return false;
// もう一つのペアがないか確認する
for (int i = 1; i <= 13; i++)
{
// 2枚がある「かつ」前のペアと異なる
if (CountSameCard(i) == 2 && i != match)
return true;
}
return false;
}
-
-
-
IsThreeOfAKind()(スリー・オブ・ア・カインドであるか?)
-
-
Handクラス - IsThreeOfAKind メソッド
// スリー・オブ・ア・カインドであるか?
private bool IsThreeOfAKind()
{
// いずれかの3枚のカードは同じ数値だったら、 スリー・オブ・ア・カインドになる
for (int i = 1; i <= 13; i++)
{
if (CountSameCard(i) == 3)
return 3;
return false;
}
-
-
IsStraight()(ストレートであるか?)
-
Handクラス - IsStraight メソッド
// ストレートであるか?
private bool IsStraight()
{
// 連続になっているのかを確認が必要
// 例えば: 8-9-10-J(11)-Q(12)
// まず、最低のカードを求めましょう
int smallCard = 14; // Kよりも高いから始まる
foreach (Card c in cards)
{
if (c.Number < smallCard)
smallCard = c.Number; // 最低カードを更新
}
// では、5枚も連続であれば、各カード +1 は
// 必ず1枚ずつがあるはず
for (int i = smallCard; i < smallCard + 5; i++)
{
// 1つだけ!
if (CountSameNumber(i) != 1)
return false;
}
// 順番に1枚ずつがあった!
return true;
// メモ:A-K-Q-J-10 に対応していない
// 興味がある学生、ご自分でお試しください。
}
-
-
IsFlush()(フラッシュであるか?)
-
Handクラス - IsFlush メソッド
// フラッシュであるか?
private bool IsFlush()
{
// すべて同じスートでであればOK
CardSuit suit = cards[0].Suit;
// 残りのを確認
foreach(Card c in cards)
{
if (c.Suit != suit)
return false;
}
return true;
}
-
-
IsFullHouse()(フールハウスであるか?)
-
Handクラス - IsFullHouse メソッド
// フルハウスであるか?
private bool IsFullHouse()
{
// ツーペアと似ているが、枚数は2枚と3枚になる
int match = 0; // 1つ目のペアの数値
for (int i = 1; i <= 13; i++)
{
if (CountSameNumber(i) == 2)
match = i;
}
// なにも一致しなかった
if (match == 0)
return false;
// 残りの3枚を数える
for (int i = 1; i <= 13; i++)
{
// 3枚がある「かつ」前のペアと異なる
if (CountSameNumber(i) == 3 && i != match)
return true;
}
return false;
}
-
-
IsFourOfAKind()(フールハウスであるか?)
-
Handクラス - IsFourOfAKind メソッド
// フォー・オブ・ア・カインドであるか?
private bool IsFourOfAKind()
{
// いずれかの4枚のカードは同じ数値だったら、 フォー・オブ・ア・カインドになる
for (int i = 1; i <= 13; i++)
{
if (CountSameNumber(i) == 4)
return true;
return false;
}
-
-
IsStraightFlush()(フールハウスであるか?)
-
Handクラス - IsStraightFlush メソッド
// ストレートフラッシュであるか?
private bool IsStraightFlush()
{
// ストレート「かつ」フラッシュなので…
return IsStraight() && IsFlush();
}
必要のは:
- s
-
-
IsStraight()(ストレートであるか?)IsFlush()(フラッシュであるか?)IsFullHouse()(フールハウスであるか?)IsFourOfAKind()(フォー・オブ・ア・カインドであるか?)IsStraightFlush()(ストレートフラッシュであるか?)
- 順番にすべてを確認する機能が必要「
CheckResult」- 一番強いハンド → 一番弱いハンドの順庵で確認
- 当てはまった場合は、5枚のカードと判定を表示する
-
- テスト用のスクリプト「TestPoker」