②山札に必要な振る舞い

課題7 山札クラスの定義 解答

①クラスの作成

public class Deck {

    /* 属性 */
    List<Card> cards;

}

コンポジションは、リストを使用することで表現します
クラスが持つ属性の型は、Cardなど自分が作ったものも使用できます

②(応用)コンストラクタの実装

    /* コンストラクタ */
    public Deck() {
        for (SuitEnum suit : SuitEnum.values()) {
            for (int i = 1; i <= 13; i++) {
                cards.add(new Card(suit, i));
            }
        }
    }

コンストラクタでは、デッキの初期化 = 全カードの作成を行います

このよう実装することで、デッキのインスタンス作成と同時にカードが生まれるため
デッキと関係のないカードが存在し得なくなりますね

③(応用)メソッドの実装

    /* 全てのカードを表示するメソッド */
    public void openAll() {
        for (Card card : cards) {
            card.openFace();
        }
    }

    /* 山札を初めの状態に戻すメソッド */
    public void shuffle() {
        cards = new ArrayList<>(); // リストの初期化を忘れずに
        for (SuitEnum suit : SuitEnum.values()) {
            for (int i = 1; i <= 13; i++) {
                cards.add(new Card(suit, i));
            }
        }
    }

カードの表示は拡張for文、山札を初めの状態に戻すには
コンストラクタと同様に、リストの初期化と全てのカードの再作成を行います

このshuffleメソッドはコンストラクタと同じ内容なので
以下のように書き変えても大丈夫です

public class Deck {

    /* 属性 */
    List<Card> cards;

    /* コンストラクタ */
    public Deck() {
        this.shuffle(); // shuffleメソッド呼出
    }

    /* 全てのカードを表示するメソッド */
    public void openAll() {
        for (Card card : cards) {
            card.openFace();
        }
    }

    /* 山札を初めの状態に戻すメソッド */
    public void shuffle() {
        cards = new ArrayList<>(); // リストの初期化を忘れずに
        for (SuitEnum suit : SuitEnum.values()) {
            for (int i = 1; i <= 13; i++) {
                cards.add(new Card(suit, i));
            }
        }
    }

}

コンストラクタの中身の処理を削除し
shuffleメソッドを呼び出すように処理を書き換えました
ちなみに、shuffleメソッドからコンストラクタを呼び出すことはできません

    /* コンストラクタ */
    public Deck() {
        cards = new ArrayList<>(); // リストの初期化を忘れずに
        for (SuitEnum suit : SuitEnum.values()) {
            for (int i = 1; i <= 13; i++) {
                cards.add(new Card(suit, i));
            }
        }
    }

    /* 山札を初めの状態に戻すメソッド */
    public void shuffle() {
        this.Deck(); // これはダメ!!
    }

山札に必要なことを考え、実装する

山札クラスを作成し、基本的な機能まで実装できました
さてここからは、山札に必要な振る舞いを考え追加実装していきましょう
と言っても、必要な機能はたった一つ

「カードを引く」ことです

しかし、カードを引くと言っても以下のような制約が必要そうです

  • ①引かれるカードはランダム

  • ②引いたカードは山札からなくなる

  • ③カードが存在しない場合は引けない

このうち、②についてはリストの削除メソッドを使えば実装できそうですが
他の2つは今の知識では難しそうです
というわけで、次のページからは以下の2つの機能を学んでいきます

  • ①引かれるカードはランダム → 乱数生成

  • ③カードが存在しない場合は引けない → 分岐処理