質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

3867閲覧

七並べプログラムを拡張して、 テーブルに置けるカードの候補を表示して、

gyro16

総合スコア89

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/01/27 02:12

編集2017/01/27 06:23

###前提・実現したいこと
七並べプログラムを拡張して、

テーブルに置けるカードの候補を表示して、

キーボードから入力して、そのカードをテーブルに置きたいのですが、

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 number63 * @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 number50 * @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/ツール等のバージョンなど)
より詳細な情報

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/01/27 02:20

「この辺りで発生しています」の「この辺り」ってどういうことですか?特定できないのでしょうか?発生する箇所が変わるのでしょうか?
swordone

2017/01/27 02:42 編集

「この辺り」と言われてもわかりません。NullPointerExceptionが発生した時のスタックトレースを掲載してください。 さらに、スタックトレースが示す行がどこなのかも加えて。
gyro16

2017/01/27 04:03

Teratailさんへ、いつもそうやって指摘頂くんですが、あがいてやった結果を載せているのに一律のご返信いつも不快感を感じています。どこが丸投げなんでしょうか?
swordone

2017/01/27 05:43

「丸投げです」などのコメントはteratailが出している訳ではなく、他のユーザが質問に対して「低評価」のボタンを押して、その理由を選ぶことで出てきます。まあこれは丸投げとは私は思わないので、誰か悪意で、もしくは質問をちゃんと読まずに付けているのではないでしょうか。
swordone

2017/01/27 05:47

ただ、スタックトレースを載せてくれとお願いしたはずですが…。加えて、あなたがフレームワークで使っているというtrumpパッケージの各クラスがどういうものなのかわからないので、そのコード、あるいはドキュメントを提示してください。
gyro16

2017/01/27 06:28

ソースを載せたいのですが、勝手が変わってページに全部載りません。
guest

回答1

0

自己解決

can.add(hand.pickCard(position));
ではなくて、
can.add(lookingCard);
です。
pickCard()はカードを引き出して、手札から削除していました。pickCard()は抜き取るメソッドでした。
候補を見るだけなら条件を満たしたカードを見るだけですので、条件を満たしたlookingCardです。
メソッドの使い方を誤解していたため抜き取ってしまったため NullPointerExceptionが発生していました。

投稿2017/01/27 09:03

gyro16

総合スコア89

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gyro16

2017/01/27 11:55

お陰様で今日は2本のプログラムが完成したしました。 少しづつ力はついています。有難うございました。
swordone

2017/01/27 14:13

これではクラスの内容がわからないわれわれには回答しようのない質問でしたね。 だからドキュメントの提示をお願いしたのですが、伝わらなかったようですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問