###前提・実現したいこと
七並べプログラムを拡張して、
テーブルに置けるカードの候補を表示して、
キーボードから入力して、そのカードをテーブルに置きたいのですが、
FantanRuleクラスを改変して、その後の利用しているところのFantanPlayerの処理を変えるのですが、
自分でいじったSelectFantanRule では NullPointerException が発生してしまいます
FantanRule と FantanPlayer を拡張して対処したいです。
public class FantanRule implements Rule{
/**
* テーブルに置けるカードを探す。
*
* @param hand 手札
* @param table テーブル
* @return 見つかったカードの組み合わせ。見つからなかった場合はnullを返す
*/
public Card[] findCandidate(Hand hand, Table table){
// 現在の手札からテーブルに出させるものを探す
Card[] candidate = rule_.findCandidate(myHand_, table_);
// 候補がある場合はテーブルに出す
if(candidate != null){
System.out.println(" " + candidate[0] + "を置きました。\n");
table_.putCard(candidate);
// テーブルの状態を表示する System.out.println(table_); // 手札がなくなったら、上がりを宣言する if(myHand_.getNumberOfCards() == 0){ master_.declareWin(this); }
} else{
// テーブルに出せるカードがなかった場合、パスする
pass_++;
※
構成
trump フレームワーク
Card
Hand
Joker
Master
Player
Rule
Table
Fantan
FantanMaster
FantanPlayer
FantanTable
FantanRule
追加拡張に
SelectFantanRule
SelectFantanPlayer
を作っています
###発生している問題・エラーメッセージ
NullPointerException がSelectFantanRule のこの辺りで発生していますが、フレームワークのtrump で提供されるCardクラス や Handクラスもいじってはいないので NullPointerException の覚えはないです。
int number = lookingCard.getNumber();
この行を指していますが、Cardクラス も Handクラスもいじってはないので、
この行がNullPointerException と言われています
int number = lookingCard.getNumber();
java
1import trump.Card; 2import trump.Table; 3import trump.Hand; 4import trump.Rule; 5import java.util.*; 6 7/* 8* 七並べ用ルールクラス。 9*/ 10public class SelectFantanRule implements Rule{ 11 /** 12 * テーブルに置けるカードを探す。 13 * 14 * @param hand 手札 15 * @param table テーブル 16 * @return 見つかったカードの組み合わせ。見つからなかった場合はnullを返す 17 */ 18 public Card[] findCandidate(Hand hand, Table table){ 19 // テーブルに置けるカードの候補 20 Card[] candidate = null; 21 int count = 0; 22 ArrayList<Card> can = null; 23 24 // 手札にあるカードを1枚ずつチェックして、テーブルに置けるか調べる 25 int numberOfHand = hand.getNumberOfCards(); 26 for(int position = 0; position < numberOfHand; position++){ 27 // 手札にあるカードを見る 28 Card lookingCard = hand.lookCard(position); 29 int number = lookingCard.getNumber(); 30 int suit = lookingCard.getSuit(); 31 32 // 今注目している手札の左か右にカードがあれば、カードを置ける 33 int leftNumber = (number != 1) ? number - 1 : Card.CARD_NUM; 34 int rightNumber = (number != Card.CARD_NUM) ? number + 1 : 1; 35 36 if((true == isThereCard(table, suit, leftNumber)) 37 || (true == isThereCard(table, suit, rightNumber))){ 38 // 手札からカードを引いて候補とする 39 if(count == 0){ 40 can = new ArrayList<Card>(); 41 } 42 can.add(hand.pickCard(position)); 43 44 /* 45 candidate = new Card[1]; 46 candidate[0] = hand.pickCard(position); 47 break; 48 */ 49 } 50 } 51 if(can.size() != 0){ 52 candidate = (Card[])can.toArray(new Card[0]); 53 } 54 return candidate; 55 } 56 57 /** 58 * テーブルにカードが置かれているか調べる。 59 * 60 * @param table テーブル 61 * @param suit スート 62 * @param number 数 63 * @return カードが置かれている場合はtrue 64 */ 65 private boolean isThereCard(Table table, int suit, int number){ 66 // テーブルにあるカードを調べ、カードが置かれているか調べる 67 Card[][] cards = table.getCards(); 68 if(cards[suit - 1][number - 1] != null){ 69 return true; 70 } else{ 71 return false; 72 } 73 } 74} 75 76import trump.Card; 77import trump.Master; 78import trump.Table; 79import trump.Player; 80import trump.Rule; 81import java.util.*; 82 83/** 84* 七並べ用プレイヤークラス。 85*/ 86public class SelectFantanPlayer extends FantanPlayer{ 87 /** パスした回数 */ 88 private int pass_; 89 90 /** 91 * コンストラクタ。 92 * 93 * @param name 名前 94 * @param master 進行役 95 * @param table テーブル 96 * @param rule ルール 97 */ 98 public SelectFantanPlayer(String name, Master master, Table table, Rule rule){ 99 super(name, master, table, rule); 100 } 101 102 /** 103 * カードを配る。 104 * 105 * @param card 受け取ったカード 106 */ 107 public void receiveCard(Card card){ 108 if(card.getNumber() == 7){ 109 // カードが7の場合、テーブルにカードを置く 110 System.out.println(name_ + ":" + card + "を置きました。"); 111 table_.putCard(new Card[] { card }); // ()の内側は{}、Card[](card)、配列Card[]をインスタンス化するのに 112 // new Card[] { 初期化子 } という配列のための記法 113 } else{ 114 // カードが7でない場合は、受け取ったカードを手札へ加える 115 super.receiveCard(card); 116 } 117 } 118 119 /** 120 * 順番を指名する。 121 * 122 * @param nextPlayer 次のプレイヤー 123 */ 124 public void play(Player nextPlayer){ 125 // 現在の手札を表示する 126 System.out.println(" " + myHand_); 127 128 // 現在の手札からテーブルに出させるものを探す 129 Card[] candidate = rule_.findCandidate(myHand_, table_); 130 131 // 候補がある場合はテーブルに出す 132 if(candidate != null){ 133 System.out.println("テーブルに置けるカードは:"); 134 for(int i = 0; i < candidate.length; i++){ 135 if(i != candidate.length - 1){ 136 System.out.print(candidate[i] + ","); 137 }else{ 138 System.out.println(candidate[i] + ":"); 139 } 140 } 141 Scanner scan = new Scanner(System.in); 142 System.out.println("テーブルに置くカードを入力してください"); 143 String input = scan.next(); 144 for(int i = 0; i < candidate.length; i++){ 145 if(input.equals(candidate[i].toString())){ 146 Card[] card = new Card[1]; 147 card[0] = candidate[i]; 148 table_.putCard(card); 149 System.out.println(" " + card[0] + "を置きました。\n"); 150 151 // テーブルの状態を表示する 152 System.out.println(table_); 153 // 手札がなくなったら、上がりを宣言する 154 if(myHand_.getNumberOfCards() == 0){ 155 master_.declareWin(this); 156 } 157 } 158 } 159 160 /* 161 System.out.println(" " + candidate[0] + "を置きました。\n"); 162 table_.putCard(candidate); 163 164 // テーブルの状態を表示する 165 System.out.println(table_); 166 167 // 手札がなくなったら、上がりを宣言する 168 if(myHand_.getNumberOfCards() == 0){ 169 master_.declareWin(this); 170 } 171 */ 172 } else{ 173 // テーブルに出せるカードがなかった場合、パスする 174 pass_++; 175 ((FantanMaster)master_).pass(this); // (FantanMaster)キャストが必要、FantanMaster固有の処理 176 177 // パス回数が制限回数以上ならばカードを全てテーブルに置く 178 if(pass_ > FantanMaster.PASS_LIMIT){ 179 int numberOfHand = myHand_.getNumberOfCards(); 180 // 手札を全てテーブルに置く 181 for(int count = 0; count < numberOfHand; count++){ 182 table_.putCard(new Card[] { myHand_.pickCard(0) }); // 手札の枚数の数だけ1枚ずつカードを引いて置く 183 // putCard()はCard[]配列 184 // new Card[] { 初期化子 } という配列のための記法 185 } 186 } 187 } 188 } 189 190 /** 191 * パスした回数を教える。 192 * 193 * @return パスした回数 194 */ 195 public int getPass(){ 196 return pass_; 197 } 198} 199
こちらが元の七並べプログラムです。
テーブルに置ける、最初に見つけた候補のカードをただ置くだけのプログラムです。
###該当のソースコード
java
1import trump.Card; 2import trump.Table; 3import trump.Hand; 4import trump.Rule; 5 6/* 7* 七並べ用ルールクラス。 8*/ 9public class FantanRule implements Rule{ 10 /** 11 * テーブルに置けるカードを探す。 12 * 13 * @param hand 手札 14 * @param table テーブル 15 * @return 見つかったカードの組み合わせ。見つからなかった場合はnullを返す 16 */ 17 public Card[] findCandidate(Hand hand, Table table){ 18 // テーブルに置けるカードの候補 19 Card[] candidate = null; 20 21 // 手札にあるカードを1枚ずつチェックして、テーブルに置けるか調べる 22 int numberOfHand = hand.getNumberOfCards(); 23 for(int position = 0; position < numberOfHand; position++){ 24 // 手札にあるカードを見る 25 Card lookingCard = hand.lookCard(position); 26 int number = lookingCard.getNumber(); 27 int suit = lookingCard.getSuit(); 28 29 // 今注目している手札の左か右にカードがあれば、カードを置ける 30 int leftNumber = (number != 1) ? number - 1 : Card.CARD_NUM; 31 int rightNumber = (number != Card.CARD_NUM) ? number + 1 : 1; 32 33 if((true == isThereCard(table, suit, leftNumber)) 34 || (true == isThereCard(table, suit, rightNumber))){ 35 // 手札からカードを引いて候補とする 36 candidate = new Card[1]; 37 candidate[0] = hand.pickCard(position); 38 break; 39 } 40 } 41 return candidate; 42 } 43 44 /** 45 * テーブルにカードが置かれているか調べる。 46 * 47 * @param table テーブル 48 * @param suit スート 49 * @param number 数 50 * @return カードが置かれている場合はtrue 51 */ 52 private boolean isThereCard(Table table, int suit, int number){ 53 // テーブルにあるカードを調べ、カードが置かれているか調べる 54 Card[][] cards = table.getCards(); 55 if(cards[suit - 1][number - 1] != null){ 56 return true; 57 } else{ 58 return false; 59 } 60 } 61}
###試したこと
SelectFantanRule 、SelectPlayer を作ってみたがうまくいかない
###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報
回答1件
あなたの回答
tips
プレビュー