②山札に必要な振る舞い
課題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つの機能を学んでいきます
①引かれるカードはランダム → 乱数生成
③カードが存在しない場合は引けない → 分岐処理