Skip to main content

総合練習

変数、条件分岐、配列(またはリスト)、列挙、メソッドとクラスを使い、以下のスクリプト作りましょう

ポーカー手札の判定

参考:ポーカー・ハンドの一覧

目標

手札にある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枚のカード表すハンド「5枚のカード表すハンド「Hand」クラス
    • 5枚を設定する方法が必要
      • 5枚を設定する方法が必要:SetCard(int i, Card card);
    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();
                                                      }

                                                       

                                                       

                                                       

                                                       

                                                       

                                                       

                                                      必要のは:


                                                             
                                                               
                                                              • IsStraight()   (ストレートであるか?)
                                                              • IsFlush()     (フラッシュであるか?)
                                                              • IsFullHouse()   (フールハウスであるか?)
                                                              • IsFourOfAKind() (フォー・オブ・ア・カインドであるか?)
                                                              • IsStraightFlush()(ストレートフラッシュであるか?)
                                                              • 順番にすべてを確認する機能が必要「CheckResult
                                                                • 一番強いハンド → 一番弱いハンドの順庵で確認
                                                                • 当てはまった場合は、5枚のカードと判定を表示する
                                                              テスト用のスクリプト「TestPoker」