手札クラスをつくる
手札クラスを作っていきます。
今回は、手札クラスで終わるだけのつもりだったんですが、手札クラスはほとんどDeckと同じだったので他にもやろうと思います。
メソッドの実装はDeckと同じ、フィールドは、ランダムアクセスの多さからArrayListを採用しました。
import java.util.ArrayList;
import java.util.List;
public class Hand implements CardSheaf {
private List<Card> hand = new ArrayList<>();
@Override
public int indexOf(Card card) {
return CardSheaf.indexOf(hand, card);
}
@Override
public int cardSize() {
return hand.size();
}
@Override
public void addCard(Card card) {
CardSheaf.addCard(hand, card);
}
@Override
public void removeCard(Card card) {
CardSheaf.removeCard(hand, card);
}
@Override
public void removeCard(int index) {
CardSheaf.removeCard(hand, index);
}
@Override
public Card find(int number, Card.Mark mark) {
return CardSheaf.find(hand, number, mark);
}
@Override
public int indexOf(int number, Card.Mark mark) {
return CardSheaf.indexOf(hand, number, mark);
}
@Override
public Card getCard(int index) {
return CardSheaf.getCard(hand, index);
}
@Override
public Card takeCard(int index) {
return CardSheaf.takeCard(hand, index).getValue();
}
}
墓地クラスを作る
墓地クラスは手札以上にデッキと同じなので、説明は省略しますね。
import java.util.Stack;
public class Cemetery implements CardSheaf {
Stack<Card> cemetery = new Stack<>();
@Override
public int indexOf(Card card) {
return CardSheaf.indexOf(cemetery, card);
}
@Override
public int cardSize() {
return cemetery.size();
}
@Override
public void addCard(Card card) {
CardSheaf.addCard(cemetery, card);
}
@Override
public void removeCard(Card card) {
CardSheaf.removeCard(cemetery, card);
}
@Override
public void removeCard(int index) {
CardSheaf.removeCard(cemetery, index);
}
@Override
public Card find(int number, Card.Mark mark) {
return CardSheaf.find(cemetery, number, mark);
}
@Override
public int indexOf(int number, Card.Mark mark) {
return CardSheaf.indexOf(cemetery, number, mark);
}
@Override
public Card getCard(int index) {
return CardSheaf.getCard(cemetery, index);
}
@Override
public Card takeCard(int index) {
return CardSheaf.takeCard(cemetery, index).getValue();
}
}
フィールドクラスを作る
まずは、他のクラスと同じように実装していきます。
また、取り出しがしやすいように表側のカードと裏側のカードを別々にもつリストも用意します。
ランダムアクセスの多さから考えて、ArrayListを利用します。
package blackpoker;
import java.util.ArrayList;
import java.util.List;
public class Field implements CardSheaf {
private List<Card> front = new ArrayList<>();
private List<Card> back = new ArrayList<>();
private List<Card> fields = new ArrayList<>();
@Override
public int indexOf(Card card) {
if (card.isFront()) {
return CardSheaf.indexOf(front, card);
}
return CardSheaf.indexOf(back, card);
}
@Override
public int cardSize() {
return front.size() + back.size();
}
/**
* カードの枚数を返す。
* @param isFront 表側のカードについてかどうか
* @return カードの枚数
*/
public int cardSize(boolean isFront) {
return isFront ? front.size() : back.size();
}
@Override
public void addCard(Card card) {
CardSheaf.addCard(fields, card);
if (card.isFront()) {
CardSheaf.addCard(front, card);
return;
}
CardSheaf.addCard(back, card);
}
/**
* データ構造にカードを追加する。
* @param isFront 削除したいカードが表側かどうか。
*/
public void addCard(Card card, boolean isFront) {
CardSheaf.addCard(fields, card);
if (isFront) {
CardSheaf.addCard(front, card);
return;
}
CardSheaf.addCard(back, card);
}
@Override
public void removeCard(Card card) {
CardSheaf.addCard(fields, card);
if (card.isFront()) {
CardSheaf.removeCard(front, card);
return;
}
CardSheaf.removeCard(back, card);
}
@Override
public void removeCard(int index) {
Card rm = CardSheaf.getCard(fields, index);
CardSheaf.removeCard(fields, rm);
if (rm.isFront()) {
CardSheaf.removeCard(front, rm);
return;
}
CardSheaf.removeCard(back, rm);
}
/**
* データ構造からカードを削除する。
* @param isFront 削除したいカードが表側かどうか。
*/
public void removeCard(int index, boolean isFront) {
if (isFront) {
CardSheaf.removeCard(front, index);
return;
}
CardSheaf.removeCard(back, index);
}
@Override
public Card find(int number, Card.Mark mark) {
Card tmp = CardSheaf.find(front, number, mark);
return tmp != null ? tmp : CardSheaf.find(back, number, mark);
}
@Override
public int indexOf(int number, Card.Mark mark) {
int tmp = CardSheaf.indexOf(front, number, mark);
return tmp >= 0 ? tmp : CardSheaf.indexOf(back, number, mark);
}
@Override
public Card getCard(int index) {
return CardSheaf.getCard(fields, index);
}
public Card getCard(int index, boolean isFront) {
if (isFront) {
return CardSheaf.getCard(front, index);
}
return CardSheaf.getCard(back, index);
}
@Override
public Card takeCard(int index) {
return CardSheaf.takeCard(fields, index).getValue();
}
/**
* 指定された番号にあるカードを取り出す。
* カードはデータ構造から削除される。
* @param index 欲しいカードのインデックス
* @param isFront カードが表(防壁でない)かどうか。表ならtrue
*/
public Card takeCard(int index, boolean isFront) {
if (isFront) {
return CardSheaf.takeCard(front, index).getValue();
}
return CardSheaf.takeCard(back, index).getValue();
}
}
indexOf以外の関数は、裏・表側のカード別に指定できる関数を用意します。
また、addやremoveで第二引数がない場合、渡されたCardオブジェクトのisFrontを参照することにしました。
import java.util.ArrayList;
import java.util.List;
public class Field implements CardSheaf {
private List<Card> front = new ArrayList<>();
private List<Card> back = new ArrayList<>();
private List<Card> fields = new ArrayList<>();
//略
/**
* 防壁をセットする。
*/
public void setBarrier(Card card) {
if (card.isFront()) card.setFront(false);
if (card.isCharge()) card.setCharge(false);
if (card.canAttack()) card.setFront(false);
addCard(card, false);
}
/**
* カードを表向きで出す。(兵士など)
*/
public void summon(Card card) {
if (!card.isFront()) card.setFront(true);
if (card.isCharge()) card.setCharge(false);
addCard(card, true);
switch (card.getJob()) {
case ACE:
case MAGICIAN:
card.setCanAttack(true);
break;
default:
card.setCanAttack(false);
break;
}
}
/**
* 攻撃可能な(表側表示の)カードをリストで返す。
*/
public List<Card> lookAttackable(){
List<Card> attackable = new ArrayList<>();
for (Card tmp: front){
if(tmp.canAttack()) attackable.add(tmp);
}
return attackable;
}
/**
* 指定された(表側表示の)カードを攻撃可能にする。
* @param index 攻撃可能にしたいカードのインデックス。
*/
public void recovery(int index){
front.get(index).setCanAttack(true);
}
/**
* すべての(表側表示の)カードを攻撃可能にする。
*/
public void recoveryAll(){
for(Card tmp: front){
if(tmp != null) tmp.setCanAttack(true);
}
}
/**
* 指定されたカードをチャージする。
* @param index チャージしたいカードのインデックス。
* @param isFront カードが表側かどうか。
*/
public void charge (int index, boolean isFront){
if(isFront){
front.get(index).setCharge(true);
}else{
back.get(index).setCharge(true);
}
}
/**
* 表側表示のカードをすべてチャージする。
*/
public void chargeAllFront(){
for(Card tmp: front){
tmp.setCharge(true);
}
}
/**
* 裏側表示のカードをすべてチャージする。
*/
public void chargeAllBack(){
for(Card tmp: back){
tmp.setCharge(true);
}
}
/**
* カードをすべてチャージする。
*/
public void chargeAll(){
chargeAllFront();
chargeAllBack();
}
/**
* 指定されたカードをドライブする。
* @param index ドライブしたいカードのインデックス。
* @param isFront カードが表側かどうか。
*/
public void drive (int index, boolean isFront){
if(isFront){
front.get(index).setCharge(false);
}else{
back.get(index).setCharge(false);
}
}
/**
* 表側表示のカードをすべてドライブする。
*/
public void driveAllFront(){
for(Card tmp: front){
tmp.setCharge(false);
}
}
/**
* 裏側表示のカードをすべてドライブする。
*/
public void driveAllBack(){
for(Card tmp: back){
tmp.setCharge(false);
}
}
/**
* カードをすべてドライブする。
*/
public void driveAll(){
driveAllFront();
driveAllBack();
}
/**
* カードを破壊する。
* @param index 破壊したいカードのインデックス。
* @param isFront 破壊したいカードが表側かどうか。
* @return 破壊されたカードのオブジェクト。
*/
public Card destruction (int index, boolean isFront){
return takeCard(index, isFront);
}
/**
* 裏側のカードを表側にする。
* @param index 表側にしたいカードのインデックス。
*/
public void open(int index){
Card tmp = takeCard(index, false);
tmp.setFront(true);
addCard(tmp, true);
}
/**
* 指定されたカードがドライブ状態かどうか.
*/
public boolean isDrive(int barrierIndex) {
return !back.get(barrierIndex).isCharge();
}
/**
* 選択された兵士が攻撃可能かを調べる.
* @param index 調べたい兵士の順番(表向きのカードの中で)
*/
public boolean canAttack(int index) {
return front.get(index).canAttack();
}
/**
* 選ばれた兵士のオブジェクトのコピーを返す.
* @param index 調べたい兵士の順番(表向きのカードの中で)
* @return 兵士カードのオブジェクトのコピー
*/
public Card getSoldierData(int index) {
return front.get(index).clone();
}
/**
* 選ばれた兵士の番号を返す.
* @param index 調べたい兵士の順番(同じ向きのカードの中で)
* @param isFront カードは表か
* @return カード番号
*/
public int getNumber(int index, boolean isFront) {
List<Card> list = isFront ? front: back;
return list.get(index).getNumber();
}
}
基本的にはコメントに書いた通りです。
が、とりあえず召喚についてだけ説明します。
summon(召喚)メソッドは、setBarrier(防壁配置)と同じく、全体のリストと表示のカードリストにカードを追加し、表かどうか・チャージしているかどうかを揃えます。
その他、エース(1)とマジシャン(ジョーカー)は召喚酔いをしないというルールから、canAttackをtrueにします。
今回はここまで。
次回はPlayerクラスを作っていきたいと思います。