11/6の課題について、
class Kadai1106{
public static void main(String [] args) throws Exception{
BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
// 試行回数times,正解Moo数a,入力Moo数q,bull&cowの数b,c,入力用文字列strの定義
int times=0,b,c;
MooNumber a,q;
a=new MooNumber();
System.out.println(a);
String str;
System.out.println("Guess a Moo number");
while(true){
//while文を繰り返す毎にtimesを+1
times=times+1;
//qの入力と判別
str=d.readLine();
q=new MooNumber(str);
//bull,cowの数を調べる
b=MooNumber.getBull(a);
c=MooNumber.getCow(a);
//正解ならwhile文を抜ける
if(b==4) break;
//不正解ならB,Cを表示し繰り返し
else System.out.println(times+":"+b+"B"+c+"C");
}
System.out.println(times+":"+b+"B"+c+"C");
System.out.println("Correct answer in "+times);
}
}
というクラスを作ったのですが、これを走らせようとするとまず
getBull/getCowはnon-staticなので参照できないという主旨のコンパイルエラー
が出ました。文字列に変換してからintに再変換しようなどと方針を変えても
同じ結果になるので、MooNumberクラス内のgetBull/Cowメソッドに
static int getBull(MooNumber m){
というようにstatic属性を追加してみました。これを走らせようとすると今度
は配列digits[]がnon-staticであるというエラーが出たのでこれにもstaticを
追加しました。(これがプログラムにどのような影響を及ぼしているのかは、
理解していません)
これでプログラムは走るようにはなったのですが、走らせてみるとどんな答え
を入力しても必ず正解になってしまうという現象が起りました。原因究明のた
め
System.out.println(a);
をあちこちに挟んでみるとどうやら入力Moo数qの値を、文字列strを元に代入
した時点でqと同時に正解aにもその値が代入されているらしいことがわかりま
した。プログラムをいくらいじり回してもこれは直ることがなく、情報棟閉館
時間になったので断念してしまいました。
Javaに関するWEBサイトをあたってもみましたが知識が大雑把なのでどうして
もどこで間違えているのかが理解できません(MooNumberクラスに手をつけて
いる時点でおかしいのでしょうが)。ご指導願います。
|
> これを走らせようとするとまずgetBull/getCowはnon-staticなので参照できな
> いという主旨のコンパイルエラーが出ました。
はい.
> b=MooNumber.getBull(a);
という書き方は 静的メソッド(static method)
(http://lecture.ecc.u-tokyo.ac.jp/~ktanaka/programming01/1030-3.html)
の呼び出し方ですが,定義の方では,
> int getBull(MooNumber m){
のように,staticをつけないすなわち動的メソッドとして定義しているので,
コンパイラはそのようなエラーを出します.
さて,
> b=MooNumber.getBull(a);
という式では q と a の間の bull を計算したいはずなのに,aしか出てきて
いませんね.動的メソッド
(http://lecture.ecc.u-tokyo.ac.jp/~ktanaka/programming01/1030-4.html)
の呼び出し方を見直してみると正解にたどり着けると思います.
> これを走らせようとするとまずgetBull/getCowはnon-staticなので参照でき
>ないという主旨のコンパイルエラーが出ました。文字列に変換してからintに
>再変換しようなどと方針を変えても同じ結果になるので、MooNumberクラス内
>のgetBull/Cowメソッドに
> static int getBull(MooNumber m){というようにstatic属性を追加し
>てみました。これを走らせようとすると今度は配列digits[]がnon-staticであ
>るというエラーが出たのでこれにもstaticを追加しました。(これがプログラ
>ムにどのような影響を及ぼしているのかは、理解していません)
プログラミングにおいては,意味を理解しないで変更してうまくいくという
幸運に恵まれることはそうはありません.この変更は,
http://lecture.ecc.u-tokyo.ac.jp/~ktanaka/programming01/1030-4.htmlの
ページの最後に
> クラス内の変数の宣言に static をつけると,クラス変数といって,そのク
> ラスのインスタンスを作らずに参照できる変数ができる.これまでには,
> Math.PIなどが出てきた.しかし,通常のプログラミングではそれほど問題に
> ならない.
と書いたように,配列 digits[] をクラス変数にしたのですが,このようにす
ると digits はインスタンス,すなわち,
> a=new MooNumber();
> q=new MooNumber(str);
などで作ったものごとに別々な実体を持つものではなく,クラス中のすべての
インスタンスで共有する変数になります.そのため,新たに MooNumberを作っ
て q に入れるたびに,aの中身も入れ替わって見えるわけです.
|
ヒントをいくつか与える.
public String toString(){
return ""+digits[0]+""+digits[1]+""+digits[2]+""+digits[3];
}
と定義してある.これを利用して,
MooNumber a=new MooNumber();
System.out.println("Moo number is "+a);
のようにデバッグ用の表示が楽にできる.
bull=a.getBull(b);のようにして計算できる.
オプション課題はネットニュースと掲示板に1つづつ投稿があった.こちらに 関する講評は次回以降おこなう.なお,オプション課題の提出期限は特にもう けないので,講義期間中にそれまでなかったような自信作ができたら,いつで も投稿して欲しい.