1 :
◆WtRerEDlHI :
05/03/07 16:20:44 ひょんなことから、今日から2週間、javaの家庭教師をすることになりました。
で、生徒がプログラム作ってる間暇なことが判明。
なので、もしよかったら参加しませんか?
詳しいルールは
>>2 以降です。
開催は朝9:00〜夜18:00までです。
ルール sage進行 全ての質問に答えられるとは限りません。 (当然、生徒優先です。)
c:\の下にJavaProgramというフォルダを新しく作ります。 ここに、プログラムを入れます。 以降は、このフォルダの中で作業をします。 ※最初は、エクリプスを使わないでやります。
まず、helloWorld.javaというテキストファイルを作ります。 中身は、以下のようにします。 文字の使い方 public class helloWorld { public static void main(String[] args) { // 文字を表示する System.out.println("Hello World"); } }
次に、バッチファイルを作ります。 j.batというテキストファイルを作って、中身を以下のようにします。 ※最初の1行の数字は、インストールしたフォルダにあわせてください。 SET JAVA_HOME=D:\j2sdk1.5.2_06 SET PATH=%PATH%;%JAVA_HOME%\bin SET CLASSPATH=.;%JAVA_HOME%\lib\tools.jar
これで準備が出来たので、DOSプロンプトを開きます。 cd c:\JavaProgram で、プログラムのおいてあるフォルダに移動したら j.bat を実行して、設定をします。 これで準備完了 まずは、javaのプログラムをコンパイルします。 javac helloWorld.java 何も表示されなかったら成功です。 次に、コンパイルしたプログラムを実行します。 java helloWorld 画面にHello Worldと出たら成功です。 失敗した場合は、大文字小文字を間違えていないか 確認してください。 ×javac helloworld.java
動いたのでプログラムの解説 >public class helloWorld { helloWorldって名前のクラスを定義します。 クラスというのは、プログラムの塊みたいなものです。 javaでは、クラス名=ファイル名になります。 >public static void main(String[] args) { 今度は、メインというなまえの、メソッドを定義します。 javaでは、プログラムが実行されると、このmainが最初に 実行されます。 他の細かいpublicとかstaticとかは、とりあえず後で説明します。 いまは、こういうものだと思っておいてください。 {}で囲まれた単位がブロックになっています。 なので、helloWorldクラスの中に、mainメソッドがあると いえます。
mainの中には、 >// 文字を表示する >System.out.println("Hello World"); となっています。 //はコメントといって、それ以降の文字は無視されます。 プログラムに説明やメモを書くのに使います。 >System.out.println("Hello World"); は、画面に文字を出す命令です。 ""でくくってある文字を出します。
なんとなくわかった? というわけで、次のステップへ
変数の使い方1 helloWorld.javaを以下のように書き換えます。以降も、そんな感じで やっていくので、バックアップを取りながらやりましょう。 public class helloWorld { public static void main(String[] args) { // 変数の定義 int x; // xに0を代入 x = 0; // 文字を表示する System.out.println("x:" + x); } }
コンパイルして実行すると、 x:5 と出たと思います。 解説です。 >// 変数の定義 >int x; xという名前のint型の変数を定義しています。 変数というのは、箱のようなものです。 intというのは、箱の種類をあらわします。 intは、整数を入れられる箱です。 まとめると、整数を入れられる箱xを作ったということです。 >// xに0を代入 >x = 0; xに0をいれます。 >// 文字を表示する >System.out.println("x:" + x); xの中身を表示します。これは、こういうものだとおもっておいてください。
Q&A ・変数には最初なにがはいっているの? →わかりません。変数に値を入れる前に、使おうとするとコンパイルエラーになります。 ・変数の種類は? →ほかにも、文字を入れる変数、小数点が使える変数など色々ありますが あとでおしえます。
応用。割り算です。 /が÷の意味です。でてこないけど、*は×です。 計算 public class helloWorld { public static void main(String[] args) { // 変数の定義 int x; // xに10を代入 x = 10; // 計算 x = x / 5; // 文字を表示する System.out.println("x:" + x); } }
さらに応用です。 //男子800、女子700円で8時間働いた額を求める public class helloWorld { public static void main(String[] args) { // 変数の定義と初期化 int jikyuDansei = 800; int jikyuJosei = 700; int kyuryoDansei = 0; int kyuryoJosei = 0; // 8時間バイトしたときの給料 kyuryoDansei = jikyuDansei * 8; kyuryoJosei = jikyuJosei * 8; // 文字を表示する System.out.println("男性給料:" + kyuryoDansei); System.out.println("女性給料:" + kyuryoJosei); } }
こんな感じでもOKですね。 //男子800、女子700円で8時間働いた額を求める(別の例) public class helloWorld { public static void main(String[] args) { // 変数の定義と初期化 int jikyuDansei = 800; int jikyuJosei = 700; int kyuryo = 0; // 8時間バイトしたときの給料 kyuryo = jikyuDansei * 8; // 文字を表示する System.out.println("男性給料:" + kyuryo); // 8時間バイトしたときの給料 kyuryo = jikyuJosei * 8; // 文字を表示する System.out.println("女性給料:" + kyuryo); } }
以上、変数については、なんとなく分かってきたので 次は、メソッドを覚えます。 //メソッドのサンプル public class helloWorld { // メソッドの定義 private static void helloWorld() { System.out.println("Hello World"); } public static void main(String[] args) { // 文字表示 helloWorld(); } }
>private static void helloWorld() { helloWorldというメソッドを作ります。 中身は >System.out.println("Hello World"); なので、Hello Worldという字を出すメソッドです。 このメソッドは定義しただけなので、中身がいつ実行されるかは わかりません。 mainは、 >// 文字表示 >helloWorld(); となっています。ここで、helloWorld()として、メソッドを呼び出しています。 実行結果はいかのようになります。 Hello World
次は、戻り値のあるメソッドです。 //メソッドのサンプル2 public class helloWorld { // メソッドの定義 private static int pi() { return 3; } public static void main(String[] args) { int x; x = pi(); System.out.println(x); } }
先生。質問!
>>16 において
変数 kyuryo の初期化は不要なように思えますが
>private static int pi() { piというメソッドを定義します。 さっきまでvoidだった場所が、intになっています。 これは、メソッドの戻り値の型をあらわします。 >return 3; returnは戻り値を返すという命令です。 >x = pi(); pi()メソッドの戻り値は3になるので、実行結果は 3 になります。
ちなみに、コメントのつけ方や、変数の初期化などは後でまとめて おしえます。いまはまあ、細かいことは言わずに、 まずは全体的な流れをおぼえるという感じでいきましょう。
メソッドの最後は、引数です。 //男子800、女子700円で8時間働いた額を求める public class helloWorld { public static void main(String[] args) { // 変数の定義と初期化 int jikyuDansei = 800; int jikyuJosei = 700; int kyuryo = 0; // 8時間バイトしたときの給料 kyuryo = kyuryoKeisan(jikyuDansei, 8); // 文字を表示する System.out.println("男性給料:" + kyuryo); // 8時間バイトしたときの給料 kyuryo = kyuryoKeisan(jikyuJosei, 8); // 文字を表示する System.out.println("女性給料:" + kyuryo); } // メソッドの定義(給料計算メソッド) private static int kyuryoKeisan( int argJikyu, // 時給 int argJikan // 勤務時間 ) { // 給料 int kyuryo = 0; // 時給と勤務時間から給料を求める kyuryo = argJikyu * argJikan; // 求めた給料を返却 return kyuryo; } }
メソッドの定義です。 >private static int kyuryoKeisan( >int argJikyu, // 時給 >int argJikan // 勤務時間 >) { ()のなかで、argJikyuとargJikanというのを定義しています。 これを引数といいます。 呼び出すところでは、 >kyuryo = kyuryoKeisan(jikyuDansei, 8); という感じでよびます。 こうすると、kyuryoKeisanメソッドを呼んだときに、 jikyuDanseiがargJikyuに、8がargJikanにはいります。 kyuryoKeisanメソッドのなかで、給料を計算して、結果を返します。
なんとなく分かったところで、次はif文です。 //if文 public class helloWorld { public static void main(String[] args) { int a = 2; if (a == 1) { System.out.println("aは1"); } else { System.out.println("aは1以外"); } } }
if文は条件を判断する命令です。 >if (a == 1) { ()の中の式が正しかったら{}の中を、違ってたらelse {}の中を 実行します。 if ()の条件式の書き方 a == 1 :aが1と等しい a != 1 :aが1と等しくない(1以外) a > b a >= b a < b a <= b 他にもありますが、基本はこんな感じです。
さっきの給料計算を改造して、6000以上だったら ボーナス1000円もらえるようにしましょう。 答えは以下のとおり // メソッドの定義(給料計算メソッド) private static int kyuryoKeisan( int argJikyu, // 時給 int argJikan, // 勤務時間 int argBonus // ボーナス ) { // 給料 int kyuryo = 0; // 時給と勤務時間から給料を求め規定額以上かを判定する kyuryo = argJikyu * argJikan; if (kyuryo >= 6000) { kyuryo = kyuryo + 1000; } else { kyuryo = kyuryo; } // 求めた給料を返却 return kyuryo; }
最後はfor文です これは、繰り返しです。 //for文 public class helloWorld { public static void main(String[] args) { for (int i = 0; i < 10; ++i) { System.out.println(i); } } }
>for (int i = 0; i < 10; ++i) { 最初のint i=0 これは、繰り返しに使う変数定義です。 最初に一回だけ実行されます。 i<10 これは、繰り返しの条件です i<10の間だけ、繰り返します。 ++i これは、増分を書くところで、ループの最後に呼ばれます。 (++iというのは、i=i+1の省略形です。) まとめると、 i=0からはじまって、i=1,i=2....i=9まで繰り返すということです。 1からはじまって10までなら for (i = 1; i <= 10; ++i) または for (i = 1; i < 11; ++i) と書くといいでしょう。 どっちでもいいですが、上のほうが10回という数字に意味があるので 分かりやすいかと思います。
応用問題1 0から9までの数を表示するプログラムをつくりなさい。 ただし、5のばあいは、500を表示すること 応用問題2 掛け算の九九を表示するプログラムを作りなさい。 1*1〜9*9までを表示すること。 以上、正解は明日。 今日は、講座の終わりに書き込みましたが、明日からは講座をしながら 少しずつ書いていきたいと思います。
先生。質問!
>>28 におけるkyuryoKeisanの引数argBonus
は不要では無いでしょうか
>>32 あーごめんなさい。不要ですね。
(生徒が間違ったプログラムを作った名残です。ごめんなさい)
良スレの予感
応用問題1の答え //for文 public class helloWorld { public static void main(String[] args) { for (int i = 0; i <= 10; ++i) { if (i == 5) { System.out.println("500"); } else { System.out.println(i); } } } }
応用問題2の答え public class helloWorld { public static void main(String[] args) { for (int i = 1; i <= 9; i = i + 2) { System.out.println(i + "の段"); for (int j = 2; j <= 8; j = j + 2) { System.out.println(i + "*" + j + "=" + (i * j)); } } } }
というわけで、今日の授業開始 まずは、昨日のおさらいもかねて、 九九を9の段から順番に表示するプログラムを作る
回答。簡単ですね。 public class helloWorld { public static void main(String[] args) { for (int i = 1; i <= 9; i = i + 2) { System.out.println(i + "の段"); for (int j = 2; j <= 8; j = j + 2) { System.out.println(i + "*" + j + "=" + (i * j)); } } } }
今日は配列をやります。 public class helloWorld { public static void main(String[] args) { int[] x = { 0, 1, 2 }; for (int i = 0; i <= 2; ++i) { System.out.println(x[i]); } } }
>int[] x = { 0, 1, 2 }; xという変数を配列で定義して、値を初期化しています。 x[0] = 0; x[1] = 1; x[2] = 2; という意味です。
別の書き方をするとこうなります。 public class helloWorld { public static void main(String[] args) { int[] x = new int[3]; x[0] = 10; x[1] = 11; x[2] = 12; for (int i = 0; i <= 2; ++i) { System.out.println(x[i]); } } }
>int[] x = new int[3]; これは、xをint型の配列[]で定義して そこにint型で[3]の配列を代入するみたいな意味です。 これで、x[0],x[1],x[2]の3個の箱が出来ます。 new int[3]の3は、箱の数です。箱の番号は0から始まるので、 箱の最大番号は2になるのを理解してください。 箱の番号を表す[]の中の数字を添え字といいます。 添え字と箱の中身は別です。 x[0] = 10 というのは、0番目の箱に10を入れるということです。
それでは、応用問題 10個箱を作って、1〜10間での数をいれたあと 表示するプログラムを作りなさい。
答え。あってるけど何か変です。 public class helloWorld { public static void main(String[] args) { int[] x = new int[10]; for (int h = 0; h <= 9; ++h){ x[h] = h + 1; } for (int i = 0; i <= 9; ++i) { System.out.println(i + " : " + x[i]); } } }
>for (int h = 0; h <= 9; ++h){ >x[h] = h + 1; >} ループ用の変数にhを使っていますが、これはiにしたほうがいいでしょう。 一般的にループ用の変数の名前にはiが使われます。 ちなみに、 うえのループとしたのループは別々の{}で囲まれているので iも別々に定義されます。
じゃあ、逆に10〜1を入れるにはどうすればいい? 答えはこんな感じ public class helloWorld { public static void main(String[] args) { int[] x = new int[10]; for (int i = 0; i <= 9; ++i){ x[i] = 10 - i; } for (int i = 0; i <= 9; ++i) { System.out.println(i + " : " + x[i]); } } }
というわけで、超基本編はおしまい。 ここからは、eclipseというソフトを使っておこないます。
以降は、 プロジェクト名 test パッケージ名 testJava クラス名 MainJava という感じでクラスを作って行います。 前回までは、helloWorld.javaを使っていましたが、名前が変だったので MainJavaにします。 クラスの最初の文字は大文字です。(helloWorldが間違っていた)
コテハン記憶チェックつけるの忘れてました。 すみません。 で、ここまでできたら、さっきのプログラムを移植して 動くかどうかテストしてみてください。 eclipseの使い方については省略します。
IBMのJREをインストールすれば、eclipseきちんと動くようです。
>>51 のページに書いてあります。
今日は、昨日の復習・・・かなりつまづいているので
復習だけで終わりそう?
こんどは、新しいクラスを作ってみる 掛け算と足し算のメソッドが入ったクラスSubJavaを作る package testJava; public class SubJava { public static int kakezan( int argHidari, int argMigi ){ int kotae = argHidari * argMigi; return kotae; } public static int tasizan( int argHidari, int argMigi ){ int kotae = argHidari + argMigi; return kotae; } }
これをmainで使う場合は、以下のとおり package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { int kotae; kotae = SubJava.kakezan(1, 5); System.out.println(kotae); kotae = SubJava.tasizan(1, 5); System.out.println(kotae); } }
まず、SubJavaがMainJavaから使えるようにする。 >import testJava.SubJava; あとは、使いたい場所でクラス名.メソッド名と書けばOK >kotae = SubJava.kakezan(1, 5); >kotae = SubJava.tasizan(1, 5);
つぎに、tashizanのstaticをはずしてみる。 public int tasizan( int argHidari, int argMigi ){ int kotae = argHidari + argMigi; return kotae; }
そうすると、MainJavaでtashizanが使えなくなるので、 以下のように変える public static void main(String[] args) { int kotae; kotae = SubJava.kakezan(1, 5); System.out.println(kotae); SubJava subJava = new SubJava(); kotae = subJava.tasizan(1, 5); System.out.println(kotae); }
javaでは、コンパイルしたら、設計図みたいなのが出来るだけで、 本体は出来ない。そこで、本体を作ってあげる必要がある。 >SubJava subJava = new SubJava(); ここで、subjavaをSubJava型で新しく作る。 (xという箱をint型で作るのと同じ感じ) >kotae = subJava.tasizan(1, 5); subjavaの中のtashizanを使う じゃあなんで、staticは使えたのか? staticの場合は、設計図みたいなとこに本体があって みんなで使う感じになってる。 なんで、本体を作らなくても使える。 逆に、本体を作っても、staticだけは、新しく作られずに 設計図のが使われる。
わかりやすくするために、変数でやってみる。 package testJava; public class SubJava { public static int x = 0; public int y = 0; public static int kakezan( int argHidari, int argMigi ){ int kotae = argHidari * argMigi; return kotae; } public int tasizan( int argHidari, int argMigi ){ int kotae = argHidari + argMigi; return kotae; } }
これを使うMainJavaはこんな感じ package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava.x = SubJava.x + 1; System.out.println(SubJava.x); SubJava subJava = new SubJava(); subJava.x = subJava.x + 1; System.out.println(subJava.x); subJava.y = subJava.y + 1; System.out.println(subJava.y); } }
xはstaticなので、そのまま本体を作らなくても使える。 >SubJava.x = SubJava.x + 1; でも、yは本体を作る必要がある ついでに、本体のxにも1を足してみる >SubJava subJava = new SubJava(); >subJava.x = subJava.x + 1; >subJava.y = subJava.y + 1; 実行結果は 1 2 1 になる。 >subJava.x = subJava.x + 1; の結果が2になることを理解してほしい。 xはstaticなので、本体を作っても設計図のほうに+1される。
本体を2個作ることも出来る package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava subJava = new SubJava(); subJava.x = subJava.x + 1; System.out.println(subJava.x); subJava.y = subJava.y + 1; System.out.println(subJava.y); SubJava subJava2 = new SubJava(); subJava2.x = subJava2.x + 1; System.out.println(subJava2.x); subJava2.y = subJava2.y + 1; System.out.println(subJava2.y); } }
実行結果は 1<-x 1<-y 2<-x 1<-y になる。(<-yとかはわかりやすくするためにつけた、表示されない) xはstaticなので2になる。 subJavaでもsubJava2でも同じのを使っているため。 yは本体の中に組み込まれているので、 別々の値になる。なので1になる。
staticあり、なしの区別と 本体を作るということが理解できただろうか? 応用問題 合計を求めるメソッドを作れ。 goukei(1) -> 1 goukei(5) -> 6 goukei(16) -> 22 というような感じで、どんどん足していって答えを返すメソッド。 メインでは、以下のように呼び出す。 package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava subJava = new SubJava(); subJava.goukei = subJava.goukei + subJava.kazu; System.out.println(subJava.goukei(1)); System.out.println(subJava.goukei(5)); System.out.println(subJava.goukei(16)); } }
まちがえた、メインは以下のとおり package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava subJava = new SubJava(); System.out.println(subJava.goukei(1)); System.out.println(subJava.goukei(5)); System.out.println(subJava.goukei(16)); } }
合計の値をどうやって保持するか? というのが難しい?
答えはこんな感じ (goukeiをstaticにしないのは、本体を何個も作っても個別に合計を計算できるように。) package testJava; public class SubJava { public int goukei = 0; public int goukei( int argKazu ){ goukei = goukei + argKazu; return goukei; } }
さて、一応正解なのですが、たとえば、mainで subJava.goukei = 100; などとされると、合計の値がおかしくなってしまいます。 そこで、 public int goukei = 0; を private int goukei = 0; に変えます。 privateは、定義されている{}の外から見えなくなるという意味です。 定義されている{}の中やさらにその中の{}の中では見れます。 なんで、mainJavaからは、goukei という変数はみれませんが、 SubJavaのなかでは、普通に使えるというわけです。 予断ですが、変数とメソッドに同じ名前をつけています。 わかりづらいですね。やめたほうがいいです。
応用問題 本体を複数作られたとしても、大丈夫な、総合計を求めるメソッドを作りなさい。 メインはこんな感じ package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava subJava1 = new SubJava(); System.out.println(subJava1.goukei(1)); System.out.println(subJava1.goukei(5)); System.out.println(subJava1.goukei(16)); SubJava subJava2 = new SubJava(); System.out.println(subJava2.goukei(1)); System.out.println(subJava2.goukei(5)); System.out.println(subJava2.goukei(16)); System.out.println(SubJava.soGoukei()); } }
答えはこんな感じ。staticを使うというのに気づけば楽勝 package testJava; public class SubJava { private int goukei = 0; private static int soGoukei = 0; public int goukei( int argKazu ){ goukei = goukei + argKazu; soGoukei = soGoukei + argKazu; return goukei; } public static int soGoukei(){ return soGoukei; } }
ちなみに、クラスも配列に出来る。 package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava[] subJava = new SubJava[2]; subJava[0] = new SubJava(); System.out.println(subJava[0].goukei(1)); System.out.println(subJava[0].goukei(5)); System.out.println(subJava[0].goukei(16)); subJava[1] = new SubJava(); System.out.println(subJava[1].goukei(1)); System.out.println(subJava[1].goukei(5)); System.out.println(subJava[1].goukei(16)); System.out.println(SubJava.soGoukei()); } }
ポイントは、 >SubJava[] subJava = new SubJava[2]; ここでは、配列の数を決めただけで、初期化はされていないので、 >subJava[0] = new SubJava(); 各添え字ごとに、初期化をする必要があるということ。 あとは、intとかの配列と一緒だと思ってかまわないです。
次はセッター、ゲッターの考え方を覚えましょう まずは、SubJava package testJava; public class SubJava { private int no = 0; private int jikyu = 0; public int getJikyu() { return jikyu; } public void setJikyu(int argJikyu) { jikyu = argJikyu; } public int getNo() { return no; } public void setNo(int argNo) { no = argNo; } }
>private int no = 0; >private int jikyu = 0; で変数を定義していますが、privateなのでMainJavaからはみえません そこで、 >public int getNo() { >return no; >} >public void setNo(int argNo) { >no = argNo; >} をつくってアクセスできるようにします。
MainJavaはこんな感じになります。 package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava tonosama = new SubJava(); tonosama.setNo(1); tonosama.setJikyu(3000); System.out.println("no:" + tonosama.getNo()); System.out.println("jikyu:" + tonosama.getJikyu()); SubJava puzzle = new SubJava(); puzzle.setNo(2); puzzle.setJikyu(2700); System.out.println("no:" + puzzle.getNo()); System.out.println("jikyu:" + puzzle.getJikyu()); } }
tonosamaとpuzzleの二人について、社員番号と時給を設定している感じです。 このように、classは、ゲッターセッターを使うことによって おっきな変数の塊のようなかんじで使うことが出来ます。 社員情報をSubJavaというクラスにまとめているわけです。 例では、tonosamaの社員情報を作成して、社員番号と時給を設定 そのあとに、puzzleの社員情報を作成して、社員番号と時給を設定しています
それでは問題。 時給2000円以上の場合は、2000円にするという処理をいれたいけど どうすればいいでしょう?
生徒がだした回答が以下のとおり うーん、確かにあってるんだけど・・・・。 package testJava; public class SubJava { private int no = 0; private int jikyu = 0; public int getJikyu() { if (jikyu >= 2000){ return 2000; } else { return jikyu; } } public void setJikyu(int argJikyu) { jikyu = argJikyu; } public int getNo() { return no; } public void setNo(int argNo) { no = argNo; } }
とりあえず、正解ということにしておいて次の問題 引数に勤務時間を入れると給料が取得できるメソッドを作りなさい。 計算式は 給料=勤務時間×時給 MainJavaはこんな感じ package testJava; import testJava.SubJava; public class MainJava { public static void main(String[] args) { SubJava tonosama = new SubJava(); tonosama.setNo(1); tonosama.setJikyu(3000); System.out.println("no:" + tonosama.getNo()); System.out.println("jikyu:" + tonosama.getJikyu()); System.out.println("kyuryo:" + tonosama.getKyuryo(8)); SubJava puzzle = new SubJava(); puzzle.setNo(2); puzzle.setJikyu(2700); System.out.println("no:" + puzzle.getNo()); System.out.println("jikyu:" + puzzle.getJikyu()); System.out.println("kyuryo:" + puzzle.getKyuryo(8)); } }
答えはこんな感じです・・・と、おもったら public int getKyuryo(int argJikan) { return jikyu * argJikan; }
うまくいかないですね。なぜでしょう? それは、getJikyuで2000以上かどうか見てるからです。 と、いうわけで、セットするときに2000以上だったら2000でセットするように改造しましょう。 package testJava; public class SubJava { private int no = 0; private int jikyu = 0; public int getJikyu() { return jikyu; } public int getKyuryo(int argJikan) { return jikyu * argJikan; } public void setJikyu(int argJikyu) { if (argJikyu >= 2000){ jikyu = 2000; } else { jikyu = argJikyu; } } public int getNo() { return no; } public void setNo(int argNo) { no = argNo; } }
こんな感じです。 逆に、内部で2000ではなく、2000以上の値で処理したい場合には、 return jikyu * argJikan; ではなく return getJikyu() * argJikan; にすればよかったです。 これは、どっちがいいかというと、どっちともいえませんが、 セットするときに値を調整したほうが、分かりやすいと思います。
と、いうわけで、今日はこんな感じでおしまい。 よく、復習しておいてください。 何か質問あったら遠慮なくどうぞ。
おはようございます。 今日もがんばりましょう。
85 :
sage :05/03/09 21:16:27
先生!今更ごめんなさい! どうしてJavaのインストール先がデフォルトのままじゃいけないんですか?
先生です。きょうは、1日復習で終わってしまった・・・。
生徒が文法や単語を覚え切れてないので、明日は自習になりました。
>>85 ディフォルトのインストール先はProgram Filesなので、
フォルダ名に空白が入るからです。
コマンドプロンプトや環境変数の設定などで
空白がはいってると不便だし誤動作するといやなので
別のフォルダに入れました。
あと、外人の作ったアプリは、日本語名の入ったフォルダに
対応していないことが多いのでこれも注意しよう!
◆WtRerEDlHI先生頑張ってくれ! ずっとこのスレ続けていってほしいYO
>>87 応援ありがとう!先生うれしいよ。
あしたもがんばるぜ!
みんなも質問あったら遠慮なくどうぞ。
先生、初心者が疑問に思う点とか分からないから
質問してもらえると勉強になるデス。
超良スレ。がんがれ。 先生しつもーん。 オブジェクト指向がなかなか身につかない気がするの。 何が分からないのか分からない状態だから、 こんなこと聞くと困るかもしれないけど、何が原因だと思う? 一応、一通りは勉強しました。 読んだ本は「10日でおぼえるオブジェクト指向入門」。
先生さあ、なんか昼間10時間くらい寝たからねむくないんだよねー 明日起きれるのだろうか・・・ それはさておき、質問にこたえますです。 >オブジェクト指向がなかなか身につかない気がするの。 うーん、難しいなあ。オブジェクト指向以前の言語は知っていますか? オブジェクト指向の言語が出てきたときに、「あ、俺が求めていた言語だ」って喜んだ人と、 「なにこれ、意味分からない」って思った人と2種類いると思うんだよね。 ちなみに、先生は前者でした。 前者なら、あとは、いろいろ実践を積む・・・なんか作ってみたりして、それを 人に見せる機会を設ける。 後者なら、各機能について、どうして、既存の言語と違ってこうなってるんだろう? っていうのを考えてみるといいと思う。 最初から、オブジェクト指向を覚えた人は・・・、どうなんだろうなあ。
オブジェクト指向にしても、ほかの事についてもそうなんだけど たとえば、昔はGOTOしかなかったわけだ。それが、GOSUB〜RETURNが できて、関数ができて・・・という風に、どんどん 拡張されてきた。 で、GOSUBしかなかった時代に「関数があったらいいな」って思っていたの人なら 関数を始めて目にしたときに、その意味、利点が分かっていると思うんだよね。 そういう人は、あとはもう、関数の文法だけ覚えれば使いこなせるはず。 そうじゃなくて、GOSUBで満足していた人にとっては、「関数って何だ?」って ことになるわけだ。そういう人にとって関数を覚えるのはただ複雑な機能にしか 過ぎないんだよね。文法を覚えても、いまいち使いこなせない。 そもそも、GOSUBでも同じことができるわけだし。 そういう人は、「どうして関数という機能が追加されたか」ってことを考えれば いいと思う。そうすれば、意味や利点が分かってくる。 そうやって、自分の物にしてけばいいと思うよ。
ちなみに、オブジェクト指向のなにがいまいち分からない? ・クラスとかそのへん ・デザインパターン ・UML クラスとかそのへんは、ある程度しっかり理解しておいたほうがいいと思う。 実際すべての機能を使うかどうかは別として。 英語の文法みたいなものだから、覚えないと話せないからね。 デザインパターンは、いうなれば、過去のプログラムのよくある形をまとめただけ だから、知らなくても何とかなるし、実践で使う機会にならなければ「ふーん」ってな もんだと思う。デザインパターンが生み出される前から同じ形のプログラムを作ってた人も 多いと思うし。ただ、しっていて損することはないよね。 基本設計をするときに、「これは、あのパターンでやろう」とかいえたらすごいと思う。 数学の公式みたいなものだから。知らなくても自分で考えれば何とかなる。 けど、自分で考えるより公式知ってれば早いし正確だし無駄がない。 UMLもデザインパターンと同じ位置づけだよね。 ただ、仕事でやるんなら、コミニュケーションの手段として必要かもしれない。 そうなったらきちんと覚えないと。でも、それまでは気にしなくていいと思う。
なんか、読み返してみると分かりづらいですが、 参考になったでしょうか? そいでは。また明日もがんばりましょう。 ていうか、今日だ。
おはようございます。 今日は2次元配列から int[][] x = new x[3][3]; int[][] x = { {0,1,2}, {3,4,5}, {6,7,8} }; こんな感じで配列の配列をつくれます。
サンプルはこんな感じ yは使ってないけど、こんなふうにできるってことで。 package testJava; public class MainJava { public static void main(String[] args) { int[][] x = { { 0, 1, 2}, { 3, 4, 5}, { 6, 7, 8} }; int[][] y = new int[3][3]; for (int i = 0; i <= 2; ++i) { for (int j = 0; j <= 2; ++j) { System.out.println(x[i][j]); } } } }
それでは問題 1:九九の答えを配列に入れる 2:答えの配列の中身を表示 こんな感じのプログラムを作れ ただし、1と2のループは分ける事
答えはこんな感じ 最初のループは0から始めてもいい(その場合は計算式が変わる) package testJava; public class MainJava { public static void main(String[] args) { int[][] x = new int[9][9]; for (int i = 1; i <= 9; ++i) { for (int j= 1; j <= 9; ++j) { x[i - 1][j - 1] = i * j; } } for (int i = 0; i <= 8; ++i) { for (int j = 0; j <= 8; ++j) { System.out.println(x[i][j]); } } } }
boolean型をおぼえます package testJava; public class MainJava { public static void main(String[] args) { boolean isX; isX = true; if (isX) { System.out.println("True"); } else { System.out.println("False"); } isX = false; if (isX) { System.out.println("True"); } else { System.out.println("False"); } if (1 == 1) { System.out.println("True"); } else { System.out.println("False"); } isX = (1 == 1); if (isX) { System.out.println("True"); } else { System.out.println("False"); } } }
boolean型には、trueかfalseがはいります。 trueは真、falseは偽という意味です。 if文は if ( 条件式 ) という感じで条件の中身によって分岐しますが じつは、これは条件式の結果がtrueかどうかを判断しています。 なので、 >isX = true; >if (isX) { とすれば、trueになります。 逆に言うとbolean型には条件式の判断結果を入れることが出来ます。 >isX = (1 == 1); とすれば、isXにはtrueがはいります。
boolean型は名前をつけるときにisXXXXという感じでつけます。 たとえば、えらーかどうかならisErrorです。 OKかどうかならisOK。 isCheckとかはだめです。チェックの結果がどういうときにtrueか分からないからです。 isOKなら、OKだったらtrueというのが、名前を見ただけでわかります。
次に、Stringを覚えます。 package testJava; public class MainJava { public static void main(String[] args) { String s = new String("あいうえお"); String t = "かきくけこ"; s = s + t; System.out.println(s); } }
Stringは文字列の入る型です。正確には文字列の入るクラスのようなものです。 >String s = new String("あいうえお"); このようにして、文字列を入れることが出来ます。 >String t = "かきくけこ"; newの部分は省略可能です。 文字列は足し算のみできます。 >s = s + t; 文字が連結されます。
文字列の比較は、==ではなく、equarlsというメソッドを使ってやります。 Stringはクラスなので、メソッドを持っています。 そのなかに、引数と自分の中身が同じ文字ならtrueを返すという equarlsメソッドがあるので、これを使うわけです。 package testJava; public class MainJava { public static void main(String[] args) { String s = new String("あいうえお"); String t = "かきくけこ"; if (s.equals(t)) { System.out.println("True"); } else { System.out.println("False"); } } }
と、いうわけで練習問題 引数の中身が”あ”かどうか調べて、”あ”だったらtrueを返却する isAというメソッドを作りなさい。
こんな感じかな package testJava; public class MainJava { public static void main(String[] args) { String s = new String("あ"); String t = "か"; if (isA(s)) { System.out.println("True"); } else { System.out.println("False"); } if (isA(t)) { System.out.println("True"); } else { System.out.println("False"); } } public static boolean isA( String argS ) { boolean isA; if ("あ".equals(argS)) { isA = true; } else { isA = false; } return isA; } }
ちなみに、 >if (isA(s)) { >System.out.println("True"); >} else { >System.out.println("False"); >} この部分は System.out.println(isA(s)); でOKです。
先生質問!
>>105 の
if ("あ".equals(argS)) {
は
if (argS.equals("あ")) {
と等価と思えますが正しいですか?
否定 booleanに!をつけると逆の意味になります。 package testJava; public class MainJava { public static void main(String[] args) { boolean isX; isX = (1 == 1); System.out.println(isX); isX = (1 == 1); System.out.println(!isX); isX = !(1 == 1); System.out.println(isX); isX = !(1 == 1); System.out.println(!isX); } }
>>105 結果は同じですが、意味は違います。
>if ("あ".equals(argS)) {
"あ"のメソッドequarlsを使って、比較をしています
>if (argS.equals("あ")) {
argSのメソッドequarlsを使って、比較をしています
結局一緒じゃん?って思うかもしれませんが、実は深い意味があります。
まだおしえていませんが、argSにnullが入った場合に変わってきます。
とりあえず、ここでは、
「文字列と変数を比べる場合は、文字列を左に書く」
と単純に覚えてそういう癖をつけてください。
他の言語だと
変数 == 文字列
なので違和感あるかもしれませんが、癖をつけておいてください。
パラメータ public static void main(String[] args) { のString[] argsのところには、クラスを実行したときのパラメータが入る たとえば、 javac MainJava ああああ いいいい としたばあい、 args[0] = ああああ args[1] = いいいい になる。 Eclipseのばあい、実行のところで、プログラム引数を設定すればいい
配列の数 package testJava; public class MainJava { public static void main(String[] args) { int i = args.length; System.out.println(i); int[] x = new int[100]; i = x.length; System.out.println(i); } }
配列の数(要素数)を取得できます。 配列名.length; >int i = args.length; と、いうわけで応用問題 引数の内容を全部表示するプログラムを作れ 例 java MainJava あ い う あ java MainJava あ い う あ い う
答えはこんな感じ、配列の数の分だけループするということに 気がつけば簡単? package testJava; public class MainJava { public static void main(String[] args) { int i = args.length; System.out.println(i); int[] x = new int[100]; i = x.length; System.out.println(i); } }
つぎのもんだい 引数の1こめと2こめをくらべて、結果を出すプログラムを作れ ただし、引数の数が2こじゃないばあいは、めっせーじをひょうじすること 答えは、こんな感じ public class MainJava { public static void main(String[] args) { int len = args.length; if (len < 2) { System.out.println("少ない"); } else { if (len > 2) { System.out.println("多い"); } else { if (args[0].eqauls(args[1])) { System.out.println("OK牧場"); } else { System.out.println("OK農場"); } } } } }
String にも、長さを調べるメソッドがある String s = "あああ"; System.out.println(s.length()); こんな感じ。 では、 引数の1こめと2こめをくらべて、どっちが長いかを出すプログラムを作れ ただし、引数の数が2こじゃないばあいは、めっせーじをひょうじすること
こんな感じ public class MainJava { public static void main(String[] args) { if (args.length == 2) { if (args[0].length() == args[1].length()) { System.out.println("同じだよ"); } else { if (args[0].length() < args[1].length()) { System.out.println("後の方が長いよ"); } else { System.out.println("前の方が長いよ"); } } } else { System.out.println("適していません"); } } }
先生 >114 が正しく動きません
先生、話がとんで申し訳ないんですが、例外のthrowsについて全く理解出来ません。 try,catchの処理とどう違うのでしょうか?
>>118 本当だ・・・
>>114 ぜんぜん違うソースですね。申し訳ありません。
環境が手元にないので動かしていませんが、下記のようになると思います。
package testJava;
public class MainJava {
public static void main(String[] args) {
int len = args.length;
for (int i = 0; i < len; ++i) {
System.out.println(args[i]);
}
}
}
>>119 質問の意味がわからないので、例外について軽く解説します。
メソッド内で、異常が起きた場合、javaは例外を発生します。
例外が発生した場合、2種類の処理のうちどちらかをしなくてはいけません。
catchして、例外を処理するか、throwして、呼び出し元に例外処理を任せるかの
どちらかです。
例外を処理するというのは、たとえばエラーメッセージをだすとか、
そういうことです。このへんは、プログラムの用件や例外の内容によって
処理が変わってくると思います。
たとえば、mainからメソッド1を呼んで、その中からメソッド2を呼ぶような
プログラムがあるとします。
例:main -> メソッド1 → メソッド2
メソッド2で例が発生した場合は、
1:メソッド2で例外をcatchしてエラーメッセージを表示
2:メソッド2で例外をthrowしてメソッド1でcatchしてエラーメッセージを表示
3:メソッド2で例外をthrowしてメソッド1でthrowhしてmainでcatchしてエラーメッセージを表示
4:メソッド2で例外をthrowしてメソッド1でthrowhしてmainでthrowして例外で終了
この4パターンのどれかの処理をする必要があります。
それでは、1〜4まで、どれがいいのか?それは用件によります。 たとえば、「例外の処理はmainで全部行う」というルールの下に、 3を選択すれば、エラーメッセージを表示する処理をmainにまとめることができます。 逆に、「例外の処理は発生したメソッド内で行う」というルールの下に 1を選択すれば、mainやメソッド1は、例外を気にすることなく下位のメソッドを 呼ぶことができます。 この辺は、例外の内容やプログラムの構成によって変わってくるので どれがいいとはいえません。ただ、プログラムの設計段階で方針を決めてから 作るといいと思います。
さて、例外には2種類あります。ExceptionとRuntimeExceptionです。 Exceptionは、プログラムのどこかで、必ず処理しなくてはいけない例外です。 RuntimeExceptionは、プログラム上で処理しなくてもいい例外です。 ここでいう処理というのはcatchかthrowのどちらかをしなくてはいけないということです。 まあ、例外が起きたら処理をしなくてはいけないというのは理解できると思います。 では、なぜRuntimeExceptionは処理しなくていいのか? RuntimeExceptionは、おもにプログラムにバグがあったときにでる例外だからです。 たとえば、ヌルポインターとかは、プログラムにバグがなければ発生しないですよね? RuntimeExceptionは、自動的に上にthrowされます。 メソッド2でおきたとしたら、どんどん上にthrowされていって、最後には mainでthrowされて、例外でプログラムが終了します。 とはいえ、catchしていけないということではなく、必要に応じて catchしてもいいことになっています。
以上が、例外についての簡単な説明です。 メソッド2のxxxという部分で例外が発生するとして、 メソッド2で例外処理したいならcatchすればいいし private void method2() { try { xxx ← ここで例外発生するかも } catch (xxxException ex) { 例外処理 } } メソッド2を呼んだとこで処理したければthrowすればいいです。 private void method2() throws xxxException { xxx ← ここで例外発生するかも }
わかりましたか? 月曜からまた授業を始めますが、それまでに復習しといてくださいね。 質問とかあったら、遠慮なくどうぞ。
126 :
89 :05/03/12 02:45:12
>91 ありがと。オブジェクト指向以前の言語を知らないと、 オブジェクト指向のありがたみが分かりづらいって言うのは聞いたことある。 ちょっと悔しいな……Javaが初めて触れるプログラミング言語なんだ。 全般的に理解がボンヤリしてるんだけど、一番不可解なのは 抽象クラスとインターフェイスの違いかな? あと、要求をクラス化する(UML?)作業に自信がない。 先生の話聞いてると、なんかスッキリします。ほんとにどうもありがとう。
>>119 ですが、なんとなくは分かりました。
>catchして、例外を処理するか、throwして、呼び出し元に例外処理を任せるかの
どちらかです。
のところが分からなかったのです。
まだ理解してない点
メインメソッドでthrowした場合はどうなるんですか?
エラー表示はされないという事?
main -> メソッド1
のメソッド1で例外をthrowした時に
メインでキャッチ文を書いてない場合はどうなるのでしょうか?
先生麻雀帰りです。
>>126 Javaが初めての言語なのかあ。だとしたら、何でもいいのでアセンブラを軽く
覚えるといいと思う。おぼえるっていうか、入門書をただ一冊読むだけで
コンピュータがメモリをどういう風に使ってるかわかるので
いろいろ役に立つと思うよ。細かい文法とか命令とかは覚える必要ないけど
概念だけでも知ってると役に立つので、読んでみたらいいんじゃないかな。
抽象クラスとインターフェイスについては、明日こたえます。(先生眠い)
クラスが先にあって、その後に抽象クラスが発明されて、その後に
インタフェイスが発明された・・・という仮定のもと考えてみると
いいかも。
>>127 >メインメソッドでthrowした場合はどうなるんですか?
ためしてみればいいじゃーん。
例外が発生してプログラムが終わります。
>メソッド1で例外をthrowした時に
>メインでキャッチ文を書いてない場合はどうなるのでしょうか?
その例外がExceptionなら、コンパイルエラーが出ます。
(かならず処理しなくてはいけない例外なので、処理しないとコンパイルできない)
RuntimeExceptionなら、自動的にmainから上にthrowされて、
例外が発生してプログラムが終了します。
おはようございます。 まずは、質問の答えから 抽象クラスというのは、実際に中身が実装されていないメソッドを含む クラスのことをいいます。 これは、どういうときに使うかというと、クラスの雛形を作るときにつかいます。 たとえば、時間割を作るとき、枠線と月〜土、それに時間目をあらわす1〜6の 数字が入った雛形を作っておいて、それをコピーして 科目を書き入れるという作業をすると思います。 javaになおしてみると 例:枠線抽象クラス→1年生1学期時間割クラス みたいな感じになります。どうように、 例:枠線抽象クラス→2年生1学期時間割クラス なんかも、簡単に作れるわけです。
もうすこし、別の例でやってみましょう。 たとえば、犬と猫のお面を作るとします。 そのばあい、目、鼻、口があることは決まっていますが、 その中身はきまっていません。 逆に、お面の基本部分である、材質、紐の長さなどは 決まっています。 そこで、材質、紐の長さなどは普通のメソッドとしてつくり、 目、鼻、口のメソッドは中身を作れないけど必要なことは決まっているので 抽象クラスで作ります。
えーでも、普通のクラスでも同じこと出来るのでは? と、おもうかもしれません。まったくそのとおりです。 では、もし、目、鼻、口を抽象クラスで作らなかったらどうなるでしょう? 普通のクラスで作った場合、オーバライドされないかもしれません。 その場合、空の目、鼻、口が出来てしまいます(いみわからないけど) また、何も作らなかった場合、目、鼻、口を作るのを忘れてしまうかも しれません。それでは、お面が作れません。 そこで、目、鼻、口を抽象クラスで定義することによって、 その存在を明確にして、分かりやすくするというわけです。
なんか、説明微妙におかしいですね。 抽象メソッドをつくると書くべくところを抽象クラスってかいてる・・・orz ってわけでもっかい説明
もうすこし、別の例でやってみましょう。 たとえば、犬と猫のお面を作るとします。 そのばあい、目、鼻、口があることは決まっていますが、 その中身はきまっていません。 逆に、お面の基本部分である、材質、紐の長さなどは 決まっています。 そこで、材質、紐の長さなどは普通のメソッドとしてつくり、 目、鼻、口のメソッドは中身を作れないけど必要なことは決まっているので 抽象メソッドで作ります。
えーでも、普通のメソッドでも同じこと出来るのでは? と、おもうかもしれません。まったくそのとおりです。 では、もし、目、鼻、口を抽象メソッドで作らなかったらどうなるでしょう? 普通のメソッドで作った場合、オーバライドされないかもしれません。 その場合、空の目、鼻、口が出来てしまいます(いみわからないけど) また、何も作らなかった場合、目、鼻、口を作るのを忘れてしまうかも しれません。それでは、お面が作れません。 そこで、目、鼻、口を抽象メソッドで定義することによって、 その存在を明確にして、分かりやすくするというわけです。
抽象メソッドを含むクラスは、必然的に抽象クラスになります。 それにより、目、鼻、口をl作らなくてはいけないことが、さらに 分かりやすくなるというわけです。 補足ですが、 >また、何も作らなかった場合、目、鼻、口を作るのを忘れてしまうかも >しれません。それでは、お面が作れません。 とありますが、抽象メソッドを絶対にオーバライド しなくてはいけないということではありません。
次にインタフェイスですが、これは、空のメソッドのみでつくられたクラス のようなものです。 抽象クラスとの大きな違いは、普通のメソッドが含まれていないことです。 また、複数指定できるということです。 たとえば、お面に値段をつけたいとします。 そのばあい、お面クラスに値段の情報を入れてもいいのですが、 他の商品(ヨーヨーとかわたあめとか)にも値段はつけます。 そこで、値段インタフェイスをつくります。 で、犬のお面を作るときは class 犬のお面 extends お面抽象クラス implements 値段インタフェイス みたいにするわけです。
インタフェイスは複数指定できます。 たとえば、対象年齢インタフェイスとかもつけたかったら class 犬のお面 extends お面抽象クラス implements 値段インタフェイス 、対象年齢インタフェイス というような感じです。
まとめると 抽象クラス ・普通のメソッドも含めることが出来る インタフェイス ・普通のメソッドを含めない ・たくさん指定できる ということになります。抽象クラスは、普通のクラスでも 代用できる感じですが、インターフェイスは代用できないですね。 また、インターフェイスだけでは、足りない部分もあると思います。 そのへんの個性を理解して、使い分けていくといいのではないでしょうか。
で、今日の問題 引数をもらって、その段の九九を表示するプログラムをつくりなさい。
こんなかんじ package testJava; public class MainJava { public static void main(String[] args) { if (args.length != 0) { int n = 0; if ("1".equals(args[0])) { n = 1; } if ("2".equals(args[0])) { n = 2; } ・・・中略・・・ if ("8".equals(args[0])) { n = 8; } if ("9".equals(args[0])) { n = 9; } System.out.println("args[0]" + "の段"); for (int i = 1; i <= 9; ++i) { System.out.println(n + "*" + i + "=" + (n * i)); } } else { System.out.println("適していません"); } } }
なんか、すっきりしないですね。 そこで、Stringをintにする方法を教えます。 IntegerというクラスのparseIntというメソッドを使います。 >Integer.parseInt(args[0]); package testJava; public class MainJava { public static void main(String[] args) { if (args.length != 0) { int n = 0; n = Integer.parseInt(args[0]); System.out.println(n + "の段"); for (int i = 1; i <= 9; ++i) { System.out.println(n + "*" + i + "=" + (n * i)); } } else { System.out.println("適していません"); } } }
さて、いままで使ってきたintですが、これはプリミティブ型といいます ようは、javaに用意されている命令ということです。 それにたいして、Stringは、型として使っていますがclassで出来ています。 (なので、本来はStringクラスと呼ぶのがただしい) それをふまえて、今度はobjectです。 javaのクラスは、objectをもとに、出来ています。 なので、objectには全てのclassを入れることが出来ます。 package testJava; public class MainJava { public static void main(String[] args) { //オブジェクト Object o; String x = "あああ"; o = x; //キャスト x = (String) o; } }
>Object o; でobjectを定義して、 >o = x; で、Stringをいれています。 逆にx=oというのはできるのでしょうか? そのまま書くとエラーになります。 なぜかというと、oはobjectで、中にどんな型のものが入っているか分からないからです。 そこで、 >//キャスト >x = (String) o; というように、oの型をおしえてあげます。 これをキャストといいます。 キャストは、どんな型でも出来ます。 たとえば 例:x = (Integer) o; ただし、上記の例では実行時にエラーになります。 なぜなら、xにはStringがはいっているからです。 StringをIntegerに変換することは出来ないので、エラーになるわけです。
どんどんいきます double型です。これはプリミティブ型です。 小数をあらわすことができます。 また、intでキャストすることが出来ます。 その場合、切り捨てです。 >d = 1.1 + 2.2; の結果がおかしいことを確認してください。 3.3になりません。 これは、計算を2進数で行っているため、誤差が発生するのです。 (なので、doubleはお金の計算などには実は向いていません。) package testJava; public class MainJava { public static void main(String[] args) { double d; d = 0.5; System.out.println(d); System.out.println((int) d); d = 1.99; System.out.println(d); System.out.println((int) d); d = 1.1 + 2.2; System.out.println(d); System.out.println((int) d); } }
判り易い説明ですね。 いつも見てるので頑張って下さい。
あっ一つ質問よろしいでしょうか。 今、サーブレットとJSPについて勉強してるんですがいまいちweb.xmlの中身とその使い方が理解できません。 ネットで見たりするんですが、ぼやーとしか判りません。
次は乱数です。ランダムな数を発生するメソッドです。 Math.random() 値はdouble型で、 0.0 <= Math.random() < 1.0 の範囲の数字が帰ってきます。 これに任意の数をかけ、intにすることで 0〜任意の数までを取得できます。 nを任意の数とすると (int) (Math.random() * n) になります。 1〜任意の数の場合は (int) ((Math.random() * n)+1) です。
練習問題 サイコロを1000回振って、 統計を出しなさい 出力例 1:200 2:200 3:200 4:200 5:100 6:100
ヒント: サイコロを振るところは int d = (int) ((Math.random() * 6) + 1); です。
>>145 ありがとうございます。
>>146 web.xmlは設定ファイルだから、説明は難しいなあ。
システムの構成によっても違うし。
ゲームでいったらオプション画面みたいなものだよ。
そこで、難易度とか、何機設定だとか、言語だとか、コンティニューが
可能かとかを設定するわけだ。
で、web.xmlの場合は、ディレクトリ構成や、ログの場所、エンコード指定なんかを
設定するわけだ。
なんで、設定できる項目については、システムによって違うので
その説明書を見てもらうしかないです。
設定内容についても、自分が設定したいようにしてくれとしか
説明の仕様がないなあ。
たとえば、Shift_JISでエンコードしたいときに、
「Shift_JISでエンコード」っていう情報をweb.xmlに書けば、
Shift_JISでエンコードされるようになるだけなので、
実際やってみるしかないと思います。
答えはこんな感じ 箱に入れるときと表示するときで配列の添え字の扱いが違うので あわせると分かりやすくなると思います。 package testJava; public class MainJava { public static void main(String[] args) { int[] x = new int[6]; for (int i = 0; i < 1000; ++i) { int d = (int) ((Math.random() * 6) + 1); x[d - 1] = x[d - 1] + 1; } for (int i = 0; i < 6; ++i) { System.out.println((i + 1) + ":" + x[i]); } } }
おはようございます メソッドの戻り値が配列だった場合どうなるか? サイコロを2個振るメソッドです。 package testJava; public class MainJava { public static void main(String[] args) { int[] d; d = xai(); System.out.println(d[0]); System.out.println(d[1]); } public static int[] xai() { int[] d = new int[2]; d[0] = (int) ((Math.random() * 6) + 1); d[1] = (int) ((Math.random() * 6) + 1); return d; } }
次は、ANDとORです。 ANDは&&ORは||で表せます。 package testJava; public class MainJava { public static void main(String[] args) { int a = 1; int b = 2; if (a == 1 && b == 2) { System.out.println("OK"); } if (a == 1 || b != 2) { System.out.println("OK"); } } }
問題 サイコロを振って奇数偶数を判断するプログラムを作りなさい。
こたえはこんな感じです。 > if (d == 1 || d == 3 || d == 5) { ここで、1または3または5の時という条件で判断しています。 package testJava; public class MainJava { public static void main(String[] args) { int d = (int) ((Math.random() * 6) + 1); if (d == 1 || d == 3 || d == 5) { System.out.println(d + ":" + "奇数です"); } else { System.out.println(d + ":" + "偶数です"); } } }
応用問題。サイコロを2個振って 片方が1でもう片方が1,3,5の場合に あたりとなるプログラムを作りなさい。
答えはこんな感じ package testJava; public class MainJava { public static void main(String[] args) { int[] d; d = xai(); d[0] = 6; d[1] = 1; if ((d[0] == 1 && (d[1] == 1 || d[1] == 3 || d[1] == 5)) || (d[1] == 1 && (d[0] == 1 || d[0] == 3 || d[0] == 5))) { System.out.println(d[0] + ":" + d[1] + ":" + "大当たり!"); } else { System.out.println(d[0] + ":" + d[1] + ":" + "残念でした。"); } } public static int[] xai() { int[] d = new int[2]; d[0] = (int) ((Math.random() * 6) + 1); d[1] = (int) ((Math.random() * 6) + 1); return d; } }
次はnullです。nullとは、何も設定されていないというような意味です。 ""(ブランク)とは違うので注意してください。 package testJava; public class MainJava { public static void main(String[] args) { String x = null; if (x == null) { System.out.println("null"); } } }
>String x = null; xを定義していますが、中身はnullです。 >if (x == null) { xがnullかどうかは、==で判断できます。 x.equarls(null) や、 null.equarls(x) では判断できません なぜなら、nullにはequarlsというメソッドが無いからです。
下記の例では、xx.length()をする場所で実行時にエラーになります。 xxがnullなので、nullの中にはlengthというメソッドが無いからです。 package testJava; public class MainJava { public static void main(String[] args) { String x = new String("A"); System.out.println(x.length()); String xx = null; System.out.println(xx.length()); } }
ANDやORは、左から判定して、条件が確定したら右の式は みません。 String xx = null; if (xx.length() == 0 || xx == null) { 上記はエラーになりますが、 String xx = null; if (xx == null || xx.length() == 0) { 上記はエラーになりません
次はelse if を覚えましょう if (条件) { } else if (条件2) { } こんな感じで、elseの後にifをまたかけます。 そうすると、条件1以外の場合に条件2を判定します。 いっぱいつなげて書くとこんなかんじ if (条件) { } else if (条件2) { } else if (条件3) { } else { }
それでは、ここまでのまとめ問題 トランプを作りましょう。 まずはcardをあらわすclassを考えましょう。 このクラスはトランプのカードの1枚の情報を入れる クラスです。 ちょっと考えてみてください。
ヒント ・マーク ・数 があればいいかな?
マークは文字で表すことにしましょう スペードなら"S"みたいな感じで。 あと、ゲッター、セッターつかってくださいね。
と、いうわけで出来たのがこちら まあ、そのまんまですね。 package testJava; public class Card { private int no = 0; private String mark; public int getNo() { return no; } public void setNo(int argNo) { no = argNo; } public String getMark() { return mark; } public void setMark(String argMark) { mark = argMark; } }
じゃあ、こんどはこのクラスを作って トランプのデッキを作りましょう。 作ったら中身を表示するプログラムを作ってください。 デッキは配列で[52]です。
ちなみにまとめへんの最終目標は チェンジなしのポーカーを作ることです [S1][S2][D1][K5][H8] ワンペア こんな感じの たぶん、完成までには今週いっぱいかかるので やる気のある人は先行して作ってみてください。 できたら、そーすみせてね。参考にしたいです。 ルールとしては、「ならってないことは使わない」←重要 そんなもんかな。
UMLについて分かり易く教えていただければ幸いです。
>>170 UMLというのは、プログラムの流れ、構造などを
図であらわしたものです。
図の描き方などは、ここではちょっと説明できないです。
(図だし)
もうすこし、具体的に分からないところとかあれば
また質問してください。
ひとつだけ、新しいの System.out.print("あああ"); printlnと違って改行しない。
public class BbsException extends Exception { /** * コンストラクタ * @param message エラーメッセージ */ public BbsException(String message){ super(message); } superの意味がいまいちわかりません。 あとthisとか。 もう一つ。 private,protectなどの修飾子の意味は分かりますが 使い所がいまいち分かりません。。 お手数かけてすみません。
>>173 thisが自分のクラス、superが親クラスを指します。
>public class BbsException extends Exception
なので、
this が BbsException
super が Exception
になります。
>super(message);
は、親クラスのコンストラクタを実行するということです。
>private,protectなどの修飾子の意味は分かりますが >使い所がいまいち分かりません。。 とりあえず、まとめると public:全てのクラス protected:定義したクラス、そのサブクラス、同じパッケージに含まれる全てのクラス 無指定:定義したクラス、同じパッケージに含まれる全てのクラス private:定義したクラス こんな感じでしょうか 全部publicでいいじゃん!という感じがしますが、それだと誰がどこで 内容を変えているか分からない・・・ので、 必要に応じてprivateにしたりとか、 そういう感じで、見える範囲を絞っていくことで、プログラムをみたときに 分かりやすくなるように定義すればいいと思います。 たとえば、privateの変数があったとします。 このばあい、そのクラスの中を全部見れば、変数の使われ方が分かりますが publicだったばあいは、他のクラスで変更されているかもしれないので、 それこそプロジェクトのソース全部をみないといけません。 こんな感じでわかりましたか?
177 :
デフォルトの名無しさん :2005/03/24(木) 16:43:00
age
178 :
デフォルトの名無しさん :2005/03/28(月) 01:09:55
age
先生、生きてるー?
先生生きてるよー; まとめ編で生徒がてこずっているので復習とかしています。 あとねえ、毎日やってもお金の無駄なので 一日おきに授業をして、休みの日は復習させることにしました。 先生収入2分の1だよ・・・orz;
181 :
デフォルトの名無しさん :2005/04/11(月) 17:12:06
age
182 :
デフォルトの名無しさん :2005/04/14(木) 00:13:05
先生(仮)死亡?? 授業内容にいくつかツッコミたいのですが、受けてくれません?>先生(仮)
183 :
デフォルトの名無しさん :2005/04/14(木) 20:11:01
184 :
182 :2005/04/16(土) 02:45:02
>>183 教えるスキル (Java のスキルでなくて) があるとは思わないですけど、せっかくの良スレ、生かしたいですな。
ちょっと考えてみます。
教えられるスキルとは何か。
期待あげ! っと行きたいですが荒らされると嫌なので 期待sage!!!!!
187 :
182 :2005/04/16(土) 14:35:27
>>185 順序だって構成できるとか、説明が上手とか、そんなん。
ちょこちょこと書いてみたんですけど、自分がやるととりとめがない&解り難い内容になることが判明。
自分にはできません…。大人しく先生の復帰を待ちまふわ…。スレ汚しスマソ。
だれかJavaのオブジェクト指向の概念を 噛み砕いてかつ解りやすく説明してくんないかなー 30代で独学で勉強しているのだがー Java初心者スレはレベルが高すぎて、、、難しい。。。 例えば 電話class ┌─オブジェクト──────── │┌フィールド(データーとか性質) │└例えば電話番号とか? │┌メソッド(機能) │├電話をかける(発信) │└電話を受ける(着信) └────────────── こういう形だっていうのは何となく理解できるのですが それがどーした!! って感じで。。。汗;
それでもってオブジェクト指向の利点?
既存のオブジェクトを拡張しやすいって事なんだよね?
>>188 の電話classを伝承したFAXclass
┌─オブジェクト────────
│┌フィールド(データーとか性質)
│└例えば電話番号とか?
│┌メソッド(機能)
│├文字データーを受ける
│└文字データーを送る
└──────────────
とすることでー既存の電話機能にFax機能を簡単に加えれる!
って感じなんだよね。このへんは色々な初心者教本に書かれている
ので理解は出来るのですが、やっぱりそれがドウシタ?
としか思わないのですが、、、
サブルーチンとかどう違うのかな?
要するに、そういったクラスを作ってmainに数行加えるだけで 他の機能をバグが少なく実装できるってことじゃないの? 他のオブジェクト系だとそういうのイッパイしてるとスパゲティソースになるんちゃう?
>他のオブジェクト系だとそういうのイッパイしてるとスパゲティソースになるんちゃう? ミスッタ!他のオブジェクト志向じゃない言語で、そういったものを実装しようとすると ゴチャゴチャになってスパゲティコードになってまうんじゃないだろうか・・・て意味です。
>>189 具体的に何が解らないの?利点?
サブルーチンは処理の手続きを書いてるのに対してクラスは物
>クラスは物 物の型
先生生きてますよ。今うちのパソコン設定中でみてなかったです。
授業が2から3日おきに、なったので暇なんだよね
っていうわけで
>>182 つっこみいいですよ。間違ってるとこあったら指摘してください。
>>188 理解できてるじゃないですか。それであってますよ。
ただ、それがどうした?っていっているってことは、
オブジェクト指向の利点が分かっていないってことだとおもう。
>サブルーチンとかどう違うのかな?
サブルーチン=メソッドだとおもってくれればOK
┌─プログラム────────
│┌グローバル変数
│└例えば電話番号とか?
│┌メインルーチン
│└メイン処理
│┌サブルーチン
│├文字データーを受ける
│└文字データーを送る
└──────────────
オブジェクト指向じゃない言語で作ったら、
こんな感じになるよね。
で、オブジェクトの利点だけど
>>190 もかいてるけど
>要するに、そういったクラスを作ってmainに数行加えるだけで
>他の機能をバグが少なく実装できるってことじゃないの?
オブジェクト指向の利点は、機能の拡張と管理が簡単なこと。
ただ、逆に言えば、機能の拡張をしない、最初の一本目のプログラムを
作る場合は、そんなにありがたくないかもしれない。
だから、オブジェクト指向っていってもピンと来ないって言うのは
あると思う。
実際、自分で作ったクラスを継承したクラスとかそんなに
作らないと思うし。
それに、オブジェクト指向の言語じゃなければ出来ないって ことは、無いと思う。ぶっちゃけ、他の言語でも同じようなことは出来る。 なんで、他の言語から来た人は、新しいことを覚えなきゃいけないから 難しく感じちゃうんだよね。 たとえば、メソッドをおぼえるにしても、「サブルーチンでいいじゃん。」みたいな。 でも、そんなこといったら、C言語もJavaも「そんなのアセンブラでいいじゃん。」って 話になるしね。 こんな感じで分かりました?
・・・まあそうかも。 OOPの利点は、(開発組織が夢に見る)再利用性であると思うな。 ただOOPしたからといって再利用性が即座に手に入るわけでは無い。 OOPLは再利用性を入手するための手段でしかない。
先生が復活している!! Javaだけに限った話じゃないのですが 全くの素人(過去に経験なし)がプログラム言語を覚える際 言語よりアルゴリズムの仕組みを覚えるほうが良いのかな と思い始めたのですが、どうでしょうか?? 足し算や引き算、掛け算、割り算といった簡単な命令分だけで 素数を求めるなんてアルゴリズムが理解できていないと出来ませんよね?
全然先生じゃないけど、 javaのクラスライブラリに、素数とか吐いてくれるクラスあったと思うよ。 すなわち、素数求める計算式知らなくてもライブラリ使えれば出来ると思います。 あ、でも、何か言語覚えながらアルゴリズム理解したらわかりやすいんじゃないかな。
>>201 >素数とか吐いてくれるクラスあったと思うよ。
ふおーマジッすか
そういう物を簡単に使えちゃうって所も
オブジェクト指向の利点とやらですねぇ
まぁ、私には素数を必要とするプログラムも
見当つかないけどね(汗;
ごめん先生じゃないから適当なこと言ってるかも知れない。
優良スレなのでここのログちょっと添削して私のサイトに残しておきます。
先生の都合が悪ければ削除するのでよろしくお願いします。
ttp://nori.voxx.jp/java.2ch.html 興味あればどうぞ。私もプログラミング言語を初めて、しかもJavaからやってるので
初歩的な部分を学びながら少しだけ書いてます。
先生の講座の補完ができれば幸いです。
素数は頭の体操にはいいが、いっぱしのソフトウェアを作ろうとしたら そういうことじゃないんだな、大事なのは。
205 :
182 :2005/04/20(水) 14:36:56
先生の授業内容にツッコミを入れたいと言っていたものです。
揚げ足取りのつもりでは無いことを前置きしておきます。
>>3 Java のインストール
4月20日現在、
>>3 のリンクは切れています。
SUN のサイトは、昔ほどではありませんがサイト構成の変更が多く、インストール URL の直リンは避けた方が無難だと考えます。
SUN のサイト内を自由に行き来できる能力も Java プログラマに求められるスキルになっている感もあるくらいで…(本当はそれじゃいかんのですが)。
インストール先を C ドライブ直下に変更する話には同意です。
が、パス名に半角空白が混じると、引数に与えるパス名に半角空白が混じった場合に「"」でクォートしなければならいのが面倒、という一点のみでの同意です。
206 :
182 :2005/04/20(水) 14:37:23
>>5 初めてのコード入力
ここで使用するテキストエディタについての言及が無いのは寂しい。
巷の入門書では Windows 付属の「メモ帳」でええやん、というような記述が目立ちますが、まっとうなエディタと比べれば作業効率やミスの発生率において各段に差が付いてしまいます。
ここは強調していただきたかった。
僕個人としては、Windows 環境であれば Vim、もしくは xyzzy をお勧めします。
Vim
ttp://www.kaoriya.net/ xyzzy
ttp://www.jsdlab.co.jp/~kei/xyzzy/ なお、Vim と xyzzy については書店でも入門書を入手する事ができます。
207 :
182 :2005/04/20(水) 14:38:19
環境設定 通常、このようなバッチファイルを作成するのは、複数の開発環境 (異なるバージョンの VM をインストールしている) を共存させる場合に使うテクニックであるように思います。 そうでなければ、Win9x 系なら AUTOEXEC.BAT、NT/2000/XP 系ならシステムのプロパティから単に PATH 環境変数を追加するだけなのが常套手段のように思います。 ですから、 ----- start ---------------------------- SET JAVA_HOME=D:\j2sdk1.5.2_06 SET PATH=%PATH%;%JAVA_HOME%\bin SET CLASSPATH=.;%JAVA_HOME%\lib\tools.jar ----- end ------------------------------ は ----- start ---------------------------- SET PATH=%PATH%;C:\j2sdk1.5.2_06\bin ----- end ------------------------------ で初心者には充分でしょう。「JAVA_HOME」や「CLASSPATH」の概念が出てくるのは、自前で常用的に使用するクラスライブラリを作成した場合か、Tomcat のように、tools.jar の力を借りないと起動できないアプリを導入した時だと思います。 まぁ、Tomcat のような場合は、別途起動スクリプトを用意するのが序等手段だとは思いますが。
208 :
182 :2005/04/20(水) 14:39:23
>>8 > javaでは、クラス名=ファイル名になります。
これはちょっと微妙。
なぜならひとつのソースにいくつでもクラスを定義できるから。
クラス名=ファイル名の制約を受けるのは public なクラスのみ。
>>13 > Q&A
> ・変数には最初なにがはいっているの?
> →わかりません。変数に値を入れる前に、使おうとするとコンパイルエラーになります。
ここで言う「変数」はローカル変数のことだと考えられるから、この文脈からいうとこれは正しい。
しかし、クラス変数やインスタンス変数には明示的な初期化は不要。
クラスロード時、もしくはインスタンスロード時に規定の値によって自動的に初期化される。そしてこのことは後の授業で触れられていない…。
といったところです。
「粘着」とおっしゃる方はご指摘ください。歓迎されないようでしたら続きは書きませんので。
>>182 最近JAVAはじめて、ここを1からずーっと見てるので一応意見を。
いくつかある中のエディタに関してですがメモ帳「でも」出来ます、じゃないと困る気がします。
なんかこれ効率悪いなー、とか思った時に初めてそういう物を探した方がいいかな、とか。
特にプログラム自体初めて、って人にはその方がいい気がします。
コンパイル、実行ってのも仕組みを理解しておくべきですし。
ちなみに自分は、メモ帳からスタートして
CPad
http://hp.vector.co.jp/authors/VA017148/ になって
Eclipseになりました。
環境変数に関しては何か問題が出てきた場合の事を考えて、
バッチでやってるんじゃ無いかなー、とか思ったりします。
まあPATH設定の仕方があれば尚良、だとは思いますけど。
その他の細かい部分は、わからない人に対してとりあえず理解させる
(したつもりになってもらう)と言う事で、それは教え方の違いだと思います。
後、リンク切れに関しては指摘するなら正しいアドレスを貼ると
これから見る人はありがたいと思います。よくわかんないけど
http://java.sun.com/j2se/1.5.0/ja/download.html これって違うんですかね。違ってたら正しいの誰かお願いします。
そいではまたROMに戻ります。先生頑張ってー
210 :
182 :2005/04/20(水) 21:29:44
>>209 ご指摘ありがとうございます。
リンク切れの正しい URL を示さなかったのは僕の落ち度です。すんません。
> その他の細かい部分は、わからない人に対してとりあえず理解させる
> (したつもりになってもらう)と言う事で、それは教え方の違いだと思います。
いやほんと、この部分は非常に難しいですね。
どうも差し出がましいことしたみたいで申し訳ないっす。
僕も ROM に戻ります。先生ガンバレー!
え?わざわざ、テキストエディタでやるのは、身近なソフトでプログラミングができる事を知り、 なおかつ、基本的なコマンドプロンプトコマンドを使ってのコンパイルや 動作確認のができることを知る為じゃないの。 最初から、エディタ使ったら初めてからの人は混乱するからじゃないの。 最初からeclipseなんて使ったらコンパイルや動作確認にコマンドプロンプト使わないし。
最近、生徒と都合があわず、授業してない・・・。今月ピンチな先生です。
>>199 >Javaだけに限った話じゃないのですが
>全くの素人(過去に経験なし)がプログラム言語を覚える際
>言語よりアルゴリズムの仕組みを覚えるほうが良いのかな
>と思い始めたのですが、どうでしょうか??
まったく言語を理解していない、初心者ならば、まずはひとつでも言語を覚えると
いいと思います。
アルゴリズムは確かに大事ですが、別に知らなくても何とかなるので。
言語を覚え、プログラムの組み立て方を覚えた後に、
必要に応じてアルゴリズムを学んでいけばいいと思います。
っていうか、アルゴリズムは数学でいえば公式みたいなものなので、
たとえば素数が必要になったときに、素数のアルゴリズムをネットで検索して
おぼえてそれをプログラムで使う見たいな流れで必要に応じて
おぼえていけばいいんじゃないかな。
今から言語を覚えるならお勧めは、Javaかなあ。
開発環境も無料だし。
>>203 >優良スレなのでここのログちょっと添削して私のサイトに残しておきます。
ありがとうございます。全然OKです。
分かりやすく編集とかしてくれても全然かまわないです。(むしろしてほしい)
自分としてもありがたいです。よろしくお願いします。
要望としては、
メソッドの説明で、なんかおかしくて再度いいなおした場所
(
>>130 あたり)をうまく編集してほしいです。
あと、115のプログラムで「おなじです」「ちがいます」のメッセージが
「OK牧場」「OK農場」になってる部分も分かりづらいので
なおしてほしいな・・・。
(OK農場=ガッツ石松語でNOの意味)
勝手なこと言ってすみません。
>>205 >インストール URL の直リンは避けた方が無難だと考えます。
これは、そのとおりですね。
リアルタイムで読んでない人には、不便でした。
>>206 >ここで使用するテキストエディタについての言及が無いのは寂しい。
あー、それもまたいうとおり。でもまあ、すぐEclipse使うから良いかなってw
ちなみに、私がお勧めするエディタは、秀丸です。秀丸の利点は・・・
・最低限の機能がそろっている(マクロ、強調表示、正規表現、GREP)
・安定している
特に仕事に使うにおいて「安定している」というのが最大限の利点です。
ほかのエディタは、正直まだ不安です。
サクラエディタなんかが、機能的には優れてると思うのですが、
まだちょっと怖くて使ってないです。
>>207 >環境設定
えーっと、なぜこのようなバッチにしたかというと、後で応用が聞くからです。
バッチファイルというものがあるというのを、かるく理解してもらえるというのもあります。
プロパティなどで設定する方法しか知らないと、
複数の環境を構築したい場合に、影響があるかもしれません。
「JAVA_HOME」や「CLASSPATH」を設定しておかないと、それを使うアプリを
今後使うときに、困るかもしれません。
なので、こんな感じにしました。
あと、普通業務で使うなら、こうするっていうのもあるし。
初心者なので、細かいことは抜きにして、まずは簡単にということで
詳しく触れてませんが、まあ、そういう理由でこうしました。
>>208 >> javaでは、クラス名=ファイル名になります。
>これはちょっと微妙。
>なぜならひとつのソースにいくつでもクラスを定義できるから。
>クラス名=ファイル名の制約を受けるのは public なクラスのみ。
これは、まったくもってそのとおりですね。
簡単に教えるつもりが、うそを教えてしまっています。
・・・まとめサイト直しておいてほしいです。
>クラス変数やインスタンス変数には明示的な初期化は不要。
これについたは、まだ説明してなかったですね。
そのうち、説明する予定です。
>>211 >え?わざわざ、テキストエディタでやるのは、身近なソフトでプログラミングができる事を知り、
>なおかつ、基本的なコマンドプロンプトコマンドを使ってのコンパイルや
>動作確認のができることを知る為じゃないの
これはまったく、そのとおりです。
Eclipseの利点を知るには、基本が分かってないと・・・との考えからです。
えーっと、あと実はこの講座をはじめる1日前に、 MS-DOSの基本 (バッチファイル作成、パスの概念など) という授業をやっていまして、そのときに説明した関係上、 エディタやバッチについて詳しく解説していなかったという・・・ のもあります。
と、いうわけで・・・ ポーカーは、実はできているので、あさってアップします (生徒の理解が微妙だったため、一回作った後に作り直したりしています。) みんなもPOKER作ってみよう! 実際自分で作ってみないと! 講座読んで分かった気になっても、なかなか作れないと思うし。
>>213 ありがとうございます。私も、このログを編集しながら学んでいます。
が、私も勉強し始めたばかりで、まだ良くインターフェースと抽象クラスの
説明はできそうにありません。
個人的な話でスレを汚したくありませんので、できればでよろしいので
私のWebにあるBBSに説明を書いていただけると嬉しいです。
先生これからも講座よろしくお願いします。
>>208 182先生、質問!
>> javaでは、クラス名=ファイル名になります。
>これはちょっと微妙。
>なぜならひとつのソースにいくつでもクラスを定義できるから。
>クラス名=ファイル名の制約を受けるのは public なクラスのみ。
・・・ということは「public なクラスだけはひとつのソースにひとつのクラスを定義する」
が成立すると推論しますが如何
223 :
182 :2005/04/21(木) 15:01:24
先生の UP を先回りして作ってみました。役判定がいい加減です (KとAが繋がってない) 基本構造はできてるので UP しときます。 ----- start ---------------------------- import java.util.*; public class Poker { public static void main( String[] args ) { Deck deck = new Deck(); System.out.println("Let's play poker !"); System.out.println(); for (int k = 0; k < 10; k++) { // 手抜き deck.suffle(); Card[] hand = deck.getHand(5); Arrays.sort(hand, new Comparator() { public int compare(Object a, Object b) { Card cardA = (Card)a; Card cardB = (Card)b; return cardA.getRank() - cardB.getRank(); } });
224 :
182 :2005/04/21(木) 15:01:48
String comma = ""; for (int i = 0; i < hand.length; i++) { System.out.print(comma + hand[i].toString()); comma = ","; } // ストレート系、フラッシュ系の判定 boolean straight = true; boolean flush = true; for (int i = 1; i < hand.length; i++) { if (straight && hand[0].getRank() + i != hand[i].getRank()) { straight = false; } if (flush && hand[0].getSuit() != hand[i].getSuit()) { flush = false; } } if (straight) { System.out.print("ストレート"); } if (flush) { System.out.print("フラッシュ"); } if (straight || flush) { System.out.println(); continue; }
225 :
182 :2005/04/21(木) 15:02:35
// ペア系の判定 boolean twocard = false; boolean threecard = false; boolean fourcard = false; int pair = 0; int rank = hand[0].getRank(); for (int i = 1; i < hand.length; i++) { if (rank == hand[i].getRank()) { if (threecard) { fourcard = true; threecard = false; } else if (twocard) { threecard = true; twocard = false; pair--; } else { twocard = true; pair++; } } else { rank = hand[i].getRank(); twocard = false; } }
226 :
182 :2005/04/21(木) 15:03:36
if (fourcard) { System.out.print("フォーカード"); } else if (threecard) { if (pair > 0) { System.out.print("フルハウス"); } else { System.out.print("スリーカード"); } } else if (pair > 0) { if (pair == 2) { System.out.print("ツーペア"); } else { System.out.print("ワンペア"); } } else { System.out.print("ノーペア"); } System.out.println(); } } }
227 :
182 :2005/04/21(木) 15:04:57
class Deck { private static final int SUITS = 4; private static final int RANKS = 13; private Card[] cards = new Card[SUITS * RANKS]; Deck() { for (int i = 0; i < SUITS; i++) { for (int j = 0; j < RANKS; j++) { cards[RANKS * i + j] = new Card(i, j); } } } void suffle() { for (int i = SUITS * RANKS - 1; i > 0; i--) { int swap = (int)(Math.random() * (i + 1)); Card tmp = cards[i]; cards[i] = cards[swap]; cards[swap] = tmp; } }
228 :
182 :2005/04/21(木) 15:26:55
Card[] getHand( int sheets ) { Card[] hand = new Card[sheets]; for (int i = 0; i < hand.length; i++) { hand[i] = cards[i]; } return hand; } // テストドライバ public static void main( String[] args ) { Deck deck = new Deck(); for (int i = 0; i < deck.cards.length; i++) { System.out.println(deck.cards[i].toString()); } } }
229 :
182 :2005/04/21(木) 15:30:22
class Card { private static final String[] SUITS = { "S", "H", "D", "C" }; private static final String[] RANKS = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; private int suit; private int rank; Card( int suit, int rank ) { this.suit = suit; this.rank = rank; } int getSuit() { return suit; } int getRank() { return rank; } public String toString() { return "[" + SUITS[suit] + ":" + RANKS[rank] + "]"; } }
230 :
182 :2005/04/21(木) 15:31:42
----- end ------------------------------ Poker.java 一本に入れてコンパイルっす。
231 :
182 :2005/04/22(金) 02:13:38
>>222 さんの質問に答えときます。
僕が
>>223-230 で示したソースは Poker.java という一本のソースに入っています。
Deck (1組のトランプ) クラスや Card (1枚のカード) といったクラスは Poker クラスの「下請け」の役目を負っています。
そのようなクラスは1本のソース中に書いてしまって問題ない (むしろまとめてしまいたい) 訳で。
「皆様から使う事ができる」 public クラスは確かに 1 本のソースにつき 1 つしか書けません。
が、下請け仕事をこなすクラスなら同じファイルに書いてしまって問題ないわけです。むしろそうした方が管理する側としては都合が良い。
ともかく、Java では、「何をひとまとまりのグループとみなすか」が非常に重要な視点になってくると思うのです。
クラス、ソース、パッケージ…。僕もまだまだできてませんが、これらの使い分けが重要だと考えます。
>>220 >ありがとうございます。私も、このログを編集しながら学んでいます。
>が、私も勉強し始めたばかりで、まだ良くインターフェースと抽象クラスの
>説明はできそうにありません。
えーっと、130,131で説明を書いて、132で間違いに気づいて
133以降で再説明している場所です。
130-132は不要ですので、削除してください。
おねがいします。
>>222 えーっと、まとめます。
javaでは、基本的に、クラス名=ファイル名になります。
ひとつのファイルに、ひとつのクラスを定義することになります。
ひとつのファイルに、複数のクラスを定義することも出来ますが、
基本的には、ひとつのファイルにひとつのクラスを定義します。
補足
>>222 のいってるとおり
>・・・ということは「public なクラスだけはひとつのソースにひとつのクラスを定義する」
>が成立すると推論しますが如何
上記が成立します。
ひとつのファイルには
・publicなクラス
・上記クラスでしか使わないクラス
を収めることが出来ます。
この「上記クラスでしか使わないクラス」を、
別ファイルにするかどうかは意見の分かれるところだと思いますが、
最初は、別ファイルにして問題ないです。
もっと、大きなプロジェクトになって、クラスの数も増えてきて、
特定のクラスでしか使わないクラスを隠蔽したいという要望が出来てきたら
有効ですが、それまでは別ファイルでいいと思います。
>>223 Poker実行してみました。ソース見る限り、バグもなさそうです。
ストレートの判定にならってないソート使ってますね。
あと、continueとか。
まあいいや、それはそれとして。
全体的な感想ですが、ちょっと分かりづらいです。
流れが追いにくい感じがします。
あと、アルゴリズムも複雑ですね。
処理効率やスピードよりも、流れの追いやすさ(メンテのしやすさ)に
重点を置いてプログラムを作るといいと思います。
(最終的に、それでおそかったら高速化すればいいし)
と、いうわけで、完成版のソースです pokerTono というパッケージを作成してください。 そのなかに Poker.java Card.java を作成してください。 まずは、短いCard.javaから package pokerTono; public class Card { //トランプのマーク public String mark; //トランプの数字 public int no; public String getMark() { return mark; } public void setMark(String argMark) { mark = argMark; } public int getNo() { return no; } public void setNo(int argNo) { no = argNo; } }
次は、poker.javaです。 package pokerTono; public class Poker { //役の名称 private static String[] yakuStr = { "ロイヤルストレートフラッシュ", "フォーカード", "ストレートフラッシュ", "フルハウス", "ストレート", "フラッシュ", "スリーカード", "ツーペア", "ワンペア", "ぶた" }; //マークの名称 private static String[] markStr = { "ス", "ダ", "ク", "ハ" }; //数字(表示用) private static String[] noStr = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
//メイン public static void main(String[] args) { //デッキを作る Card[] deck = new Card[52]; //52枚のカードに数とマークを割り振る。 for (int i = 0;i <= 3; ++i) { for (int j = 1;j <= 13; ++j) { Card card = new Card(); card.setMark(markStr[i]); card.setNo(j); deck[((i * 13) + j - 1)] = card; } } //役の数をカウントする配列 int x[] = new int[10]; //ポーカーを1000回行う for (int i = 1; i <= 1000; ++i) { //ポーカーを行う int yaku = poker(deck); //どの役だったかをカウント x[yaku] = x[yaku] + 1; } //役ごとの統計を表示 for (int i = 0; i < 10; ++i) { System.out.println(yakuStr[i] + ":" + x[i] + "回"); } }
//ポーカーを一回行う public static int poker ( Card[] argDeck ) { //シャッフル int deckLength = argDeck.length; for (int i = 0; i < 200; ++i) { int x = (int) (Math.random() * deckLength); int y = (int) (Math.random() * deckLength); Card card = argDeck[x]; argDeck[x] = argDeck[y]; argDeck[y] = card; } //手札を5枚もらう Card[] hand = new Card[5]; int handLength = hand.length; for (int i = 0; i < handLength; ++i) { hand[i] = argDeck[i]; } //手札を表示する for (int i = 0; i < handLength; ++i) { printCard(hand[i]); } //役を判定する int yaku = getYaku(hand); //役を表示する System.out.println(yakuStr[yaku]); //役を返却する return yaku; }
//引数で指定されたカードの数とマークを表示する。 public static void printCard ( Card argCard ) { System.out.print( "[" + argCard.getMark() + noStr[argCard.getNo() - 1] + "]"); }
//役の判定 public static int getYaku ( Card[] argHand ) { //手札をソート用の配列にいれる。 Card[] sortHand = new Card[5]; for (int i = 0; i < 5; ++i) { sortHand[i] = argHand[i]; } //手札をソートする for (int i = 0;i < (5 - 1); ++i) { for (int j = (5 - 1);j > i; --j) { if (sortHand[j].getNo() < sortHand[j - 1].getNo()) { Card tmp = sortHand[j]; sortHand[j] = sortHand[j - 1]; sortHand[j - 1] = tmp; } } } //手札のどの数字が何個あるか調べる int[] handNo = new int[13]; for (int i = 0; i < 5; ++i) { int no = sortHand[i].getNo(); handNo[no - 1] = handNo[no - 1] + 1; }
//ペア系の判定 int pair = 0; int three = 0; int four = 0; for (int i = 0; i < 13; ++i) { if (handNo[i] == 2) { pair = pair + 1; } if (handNo[i] == 3) { three = three + 1; } if (handNo[i] == 4) { four = four + 1; } } //ストレートの判定 boolean isStraight = false; if (sortHand[0].getNo() + 1 == (sortHand[1].getNo()) && sortHand[0].getNo() + 2 == (sortHand[2].getNo()) && sortHand[0].getNo() + 3 == (sortHand[3].getNo()) && sortHand[0].getNo() + 4 == (sortHand[4].getNo()) ) { isStraight = true; } boolean isRoyal = false; if (sortHand[0].getNo() == 1 && sortHand[1].getNo() == 10 && sortHand[2].getNo() == 11 && sortHand[3].getNo() == 12 && sortHand[4].getNo() == 13 ) { isRoyal = true; }
//フラッシュの判定 boolean isFrash = false; if (sortHand[0].getMark().equals(sortHand[1].getMark()) && sortHand[1].getMark().equals(sortHand[2].getMark()) && sortHand[2].getMark().equals(sortHand[3].getMark()) && sortHand[3].getMark().equals(sortHand[4].getMark()) ) { isFrash = true; } //役の判定 int yaku; if (isFrash && isRoyal) { yaku = 0; } else if (four == 1) { yaku = 1; } else if (isFrash && isStraight) { yaku = 2; } else if (three == 1 && pair == 1) { yaku = 3; } else if (isStraight || isRoyal) { yaku = 4; } else if (isFrash) { yaku = 5; } else if (three == 1) { yaku = 6; } else if (pair == 2) { yaku = 7; } else if (pair == 1) { yaku = 8; } else { yaku = 9; } return yaku; } }
それでは、解説です。 //デッキを作る Card[] deck = new Card[52]; //52枚のカードに数とマークを割り振る。 for (int i = 0;i <= 3; ++i) { for (int j = 1;j <= 13; ++j) { Card card = new Card(); card.setMark(markStr[i]); card.setNo(j); deck[((i * 13) + j - 1)] = card; } } deckという名前のCardの配列を作って中身を設定します。
メイン処理です。deckを使って、ポーカーを行い、その結果を集計します。 //役の数をカウントする配列 int x[] = new int[10]; //ポーカーを1000回行う for (int i = 1; i <= 1000; ++i) { //ポーカーを行う int yaku = poker(deck); //どの役だったかをカウント x[yaku] = x[yaku] + 1; } //役ごとの統計を表示 for (int i = 0; i < 10; ++i) { System.out.println(yakuStr[i] + ":" + x[i] + "回"); } }
>//ポーカーを一回行う >public static int poker ( ポーカーを実際に行うメソッドです。 //シャッフル //手札を5枚もらう //手札を表示する //役を判定する //役を表示する //役を返却する こんな感じでやっています。
//シャッフル int deckLength = argDeck.length; for (int i = 0; i < 200; ++i) { int x = (int) (Math.random() * deckLength); int y = (int) (Math.random() * deckLength); Card card = argDeck[x]; argDeck[x] = argDeck[y]; argDeck[y] = card; } シャッフルは、カードの中から2枚をランダムで選び、 それを交換するというやり方でやっています。 それを複数回(プログラムでは200回)繰り返すことで デッキをシャッフルしています。
248 :
182 :2005/04/22(金) 14:41:09
>>235 先生の役判定のところは「なるほど」でした。
今見ると僕のは見苦しいっすねぇ…。恥ずかしい。
シャッフルのアルゴリズムは僕の方が良いと思うのですが。
せんせ〜!
>>54 のプログラムをコンパイルしようとすると、
以下のようなエラーがでてきて実行できません。
色々試してみたのですが解決できませんでした。
どうかアドバイスください<(_ _)>
MainJava.java:2: シンボルを見つけられません。
シンボル: クラス SubJava
場所 : testJava の パッケージ
import testJava.SubJava;
^
MainJava.java:6: シンボルを見つけられません。
シンボル: 変数 SubJava
場所 : testJava.MainJava の クラス
kotae = SubJava.kakezan(1, 5);
^
MainJava.java:8: シンボルを見つけられません。
シンボル: 変数 SubJava
場所 : testJava.MainJava の クラス
kotae = SubJava.tasizan(1, 5);
^
エラー 3 個
亀レスでごめん。 オススメのエディタの話なんだけど、DevBoosterって知ってる人いる? これ結構使いやすいんだよ。 Ecripse使うほどではないけど、 メモ帳では辛い行数になってきたころに使うといい。
>>249 先生は一見神様の様だけど、エスパーでは無いので
とりあえずその書いたソースをコピペするといいと思うよ。
見ながら自分で書いたならスペルミスの可能性、
ここからコピペったなら余計な物がくっついてたり足りなかったりする可能性、
それでも無ければPackageやらが間違ってるかもしれないし。
後、一応念のために確認しておくと、
>>54 だけじゃ動かない。
今日の夜は先生のポーカーのソースを解読しまっすヽ(`Д´)ノ
>>248 >先生の役判定のところは「なるほど」でした。
>今見ると僕のは見苦しいっすねぇ…。恥ずかしい。
先生のソースは、手順が単純でしょ?
(っていうか、先生が教えながら作った生徒のソースだけど)
それに、実際にトランプで役を判定するときの手順に
にてると思う。
だから、すんなり、頭に入るし、なによりも
バグがみつけやすいし、改造がしやすい。
ってことは、保守性が高いってことなんだよね。
つづきです。 >シャッフルのアルゴリズムは僕の方が良いと思うのですが。 うーん、一見効率がよいように見えるけど、果たしてそうだろうか? まず、先生のアルゴリズムを文章にしてみよう 「ランダムな2枚のカードを選び、位置を交換する。これを複数回繰り返す。」 どうだろうか?シャッフルしている感じがするよね。 それに対して、182のアルゴリズムは 「デッキの先頭から順番に、ランダムな位置のカードと交換していく。」 どうだろうか、普段しているシャッフルとは、ちょっと違う感じがしない? 違和感があるっていうか。 結局、結果的には、カードが満遍なく混ざることには代わりがない。 (実際、数学的に見たら違うのかもしれないけど・・・まあ、みためは混ざっている) でも、なんか分かりにくい気がします。 ちなみに、182が作った奴のほうが、少ないループ回数で全部のカードを 一回以上交換できるので合理的な気はします。 でも、それが、「本当にシャッフルしているっぽいか?」っていわれると、 ちょっと違和感がある感じがします。 まあ、ぶっちゃけ、どっちでもいいと思う。まざるし。
つづき ただ、実際に現実にあるものをプログラムするには、 なるべく、現実に近い形でプログラムするといいと思います。 そのほうが、ほんとっぽいし、ソースを見た上でも理解しやすいからです。 たとえば、トランプの手札を取る部分を 「1から52までのランダムな数を選び、その数に対応するカードを 手札に加える。もし、そのカードが手札にすでにあった場合は、 再度ランダムな数を選びなおす。これを手札が5枚になるまで繰り返す。」 とかいうアルゴリズムで、作ったらどうでしょう? 確かに、このアルゴリズムでも、ランダムな5枚は得られるし、 デッキを作ったりシャッフルする手間も省けるし、 いい事尽くめかもしれません。 でも、これって普段やってるトランプのルールとはちがうよね? なんていうか、いんちきくさい。
つづき と、いうわけで、先生は、先生のアルゴリズムのほうが 単純だし無駄があるかもしれないけど いいと思います。 が、どっちもどっちといわれれば、どっちもどっちだし、 182の方が素敵といわれれば、そんな気もします。 まあ、この辺の解釈は人それぞれだし、なんともいえないというのが 正直なところです。 微妙な説明ですが、なんとなくいいたいことは分かってくれたと思います。 で、結論として182の方がいけてると思ったらそれはそれでいいとおもいます。
>>249 えーっと、
>>53 のソースもいるよ。
testJavaっていうパッケージを作って、その中に
・MainJava.java
・SubJava.java
っていう二つのクラスを作る必要があります。
意味分かった?
>>250 なんか、統合環境なんだね。
使うとしたら、eclipseの代わり?
先生はエディタは秀丸(安定してるから)、統合環境はeclipse(業務で使うことが多いから)って
感じです。
統合環境は、eclipseに慣れておくと将来プロになったときに良いかもしれないです。
ならなくても、まあ、使いやすいしeclipseでいいのではないでしょうか?ただだし。
まあ、好みがあるんで、このぐらいでやめときましょう。
っていうわけで、先生寝るぜ! 先生の指示の元に生徒が作ったソースなんで、正直微妙なところもあるけど (変数の名前とか) まあ、90点レベル、問題ないソースだと思います。 「ここ無駄じゃない?」とか、 「ここは、これじゃだめなの?」とか、 「ここ間違ってる!」とか、(ないはずだけど) あったら指摘してください。 あと、ソースはコピーしたら、マウスの右ボタンで出るメニューに ソースのフォーマットをきれいにするみたいなのがあるから それでインデントをきれいにするといいと思います。 (手元にeclipseがないので説明適当でごめんなさい。)
>>251 >今日の夜は先生のポーカーのソースを解読しまっすヽ(`Д´)ノ
がんばって、やってみてください。
ちょっと改造して、実際動かしてみると面白いよ。
10000回くらいまわして、ロイヤルストレートフラッシュが出るかどうかとか
実験すると楽しいと思います。
ちなみに、先生が試したら、ほぼ
「普通科3年の山下君のレポート」と同じ結果になりましたw
興味がある人は検索してみてください。
「スリーカードって結構でやすいんだ」とか、新たな発見があって
おもしろいかも?
260 :
182 :2005/04/23(土) 01:45:54
>>258 先生、例題ソースを見て思った事が。
「あるカードのマークや数字は、カードが一度生れ落ちたら最後、死ぬまで変わらない」ですよね?
こういう場合、Card クラスに set メソッドがあるのは設計上良くないのでは?
コンストラクタで設定したら最後、変更が効かないように作っておくべきでは…。
それから、役判定は判定用のクラスを作って、AWT のレイアウトマネージャみたく作っておけば、ローカルルールにすぐに対応できて便利かな、と思いました。
それから質問です。
ジョーカーのような、他のカードと性質が異なるカードを混ぜたい場合、どのようにクラス化すればしっくり行くでしょう?
ジョーカーにはマークや数字の概念がありませんから…。
if 文でジョーカーだけを特別扱いするコードにすると、いかにも「ダサダサ」になってしまうんですよ。
ではおやすみなさい。
おはよー
>>182 >「あるカードのマークや数字は、カードが一度生れ落ちたら最後、死ぬまで変わらない」ですよね?
>こういう場合、Card クラスに set メソッドがあるのは設計上良くないのでは?
>コンストラクタで設定したら最後、変更が効かないように作っておくべきでは…。
そのとおりです。コンストラクタを使うことで、すっきりすると思います。
ただまあ、授業でまだならってないから使ってないだけです。
この辺は、あとで解説します。
>それから、役判定は判定用のクラスを作って、AWT のレイアウトマネージャみたく作っておけば、
>ローカルルールにすぐに対応できて便利かな、と思いました。
いいですね。それはいい考え方だと思います。
今回はまだ規模が小さいのでまとめてありますが、規模が大きくなったら
有効な手段だと思います。
>それから質問です。 >ジョーカーのような、他のカードと性質が異なるカードを混ぜたい場合、どのようにクラス化すればしっくり行くでしょう? >ジョーカーにはマークや数字の概念がありませんから…。 マークはJoker、数字はJokerを表す数を設定すればいいと思います。 //マークの名称 private static String[] markStr = { "ス", "ダ", "ク", "ハ","JO" }; マークはこれで良いとして、数字のほうは //数字(表示用) private static String[] noStr = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K","","KER" }; こんな感じ? >if 文でジョーカーだけを特別扱いするコードにすると、いかにも「ダサダサ」になってしまうんですよ。
つづき で、数字なんだけど、15をJokerを表す数にします。 そうすれば、13とつながらないので、ストレート判定のときに楽? という、やり方もありかな? でもまあ、無駄な気もするんで14でもいいかな? //数字(表示用) private static String[] noStr = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K","KER" }; この辺は、どんな風に役判定を作るかですね。
つづき ほかにも、Jokerを0にするというのもありでしょう。 そうすれば、 //数字(表示用) private static String[] noStr = { "KER","A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; noStrの添え字にカードの数字がそのままつかえます。 まあ、ぶっちゃけ決め事なので何でも良いです。 基本的にカードクラスは、カードの内容を保存するだけなので Jokerだから特別に・・・ということは必要ないです。 問題は、表示の部分と役判定の部分ですね。
つづき 表示の部分は、マークに"JO"数字に”KER"と設定することにより [JOKER] と表示できるようになりました。 まあ、こんなことしなくても //引数で指定されたカードの数とマークを表示する。 public static void printCard ( Card argCard ) { System.out.print( "[" + argCard.getMark() + noStr[argCard.getNo() - 1] + "]"); } にif文を入れてJOKERだったら、特別な表示にしてもいいと思います。
それよりも、問題は役判定ですね。 これはまあ、面倒だけど地道にIF文使うしかないでしょうw (すごいアルゴリズムがあるのかもしれませんが・・・) 思いつきでかくと フラッシュ判定 ・Jokerを除いたすべてのマークが一緒ならフラッシュ ストレート判定 ・最初にJokerがあるかみて、あったらすべての組み合わせを判定? ペア判定 ・Joker以外の数字が何枚かを数えて、最後にJokerを一番枚数の多いとこに足す こんな感じになるかなあ。 >if 文でジョーカーだけを特別扱いするコードにすると、いかにも「ダサダサ」になってしまうんですよ。 ストレートはどうしても、こんな感じになる気がしますね。 面白そうなので、挑戦してみてはどうでしょう? とりあえず、Joker1枚でやってみよう。(最終目標は2枚)
267 :
182 :2005/04/23(土) 17:21:55
>>261-266 先生ありがとうございます。
僕もひとつやり方を思いつきました。
こいつぁ文字列マッチングと同等テクが使えるんではないかって。
ジョーカーを「任意の一文字を表すメタ文字」だと思えばイケると思います。ジョーカーの数を 2枚にするのも視野に入るし。
文字列マッチングと異なるのは「ジョーカーを任意の場所で使える」ってとこかな…。
難しそうだけど、挑戦してみます。
>>267 >こいつぁ文字列マッチングと同等テクが使えるんではないかって。
>ジョーカーを「任意の一文字を表すメタ文字」だと思えばイケると思います。ジョーカーの数を 2枚にするのも視野に入るし。
たしかに、正規表現使えば簡単にできる気がしますね。
(まだ、授業でやってないけど)
とりあえず、普通に作ってみて、そのあと、工夫してみたバージョンを作ると
勉強になると思いますよ。
せ、先生・・・? と、とりあえず保守
授業再開はあさってからの予定ですYO! ポーカーの解説の続きも行います。 生徒と作戦を立てて、GWは授業三昧にすることにしました。 みんなも引きこもって勉強だ!(笑) なんていってみるテスト
//手札を5枚もらう Card[] hand = new Card[5]; int handLength = hand.length; for (int i = 0; i < handLength; ++i) { hand[i] = argDeck[i]; } //手札を表示する for (int i = 0; i < handLength; ++i) { printCard(hand[i]); } 手札をもらいます。デッキから5枚カードを取って 手札用の配列hand[]にいれます。
//役を判定する int yaku = getYaku(hand); //役を表示する System.out.println(yakuStr[yaku]); //役を返却する return yaku; 役判定をして、表示します。 役判定は長くなるので別メソッドに分けてあります。
役の判定です。 //手札をソート用の配列にいれる。 //手札をソートする //手札のどの数字が何個あるか調べる //ペア系の判定 //ストレートの判定 //フラッシュの判定 //役の判定 全体の流れはこんな感じです。 まず最初に、手札の内容をソートして、同じ数の枚数を数えます。 その後、ペア、ストレート、フラッシュの判定をして、 最後にそれらを総合して役を判定します。
//手札をソート用の配列にいれる。 //手札をソートする 手札のソートは、ソート用の配列を作ってそこで行います。 なぜ、手札を直接ソートしないのか?というと、なんとなくです。 今回のプログラムでは関係ありませんが、役判定の後に 手札を画面表示したい場合など、ソートされては困るので 別にソート用の手札を作っています。 ソートの手法ですが、バブルソートというアルゴリズムを使用しています。 興味がある人は調べてみてください。 javaには、ソート用のメソッドが用意してあり、通常は自分でソートをする必要は ないのですが、まあ、練習ということで。
//手札のどの数字が何個あるか調べる int[] handNo = new int[13]; for (int i = 0; i < 5; ++i) { int no = sortHand[i].getNo(); handNo[no - 1] = handNo[no - 1] + 1; } 同じ数字のカードが何枚あるか調べます。 ここは、そんなに難しくないですね。
//ペア系の判定 int pair = 0; int three = 0; int four = 0; for (int i = 0; i < 13; ++i) { if (handNo[i] == 2) { pair = pair + 1; } if (handNo[i] == 3) { three = three + 1; } if (handNo[i] == 4) { four = four + 1; } } ペア系の判定です。 最初に、ペア、スリーカード、フォーカード用の変数を作っておきます。 >for (int i = 0; i < 13; ++i) { トランプの数字の数だけループして、その数の枚数にあわせて ペア、スリーカード、フォーカード用の変数を+1していきます。 スリーカードやフォーカードが2になることは絶対無いので、 if (handNo[i] == 4) { four = 1; } というようにしてもいいと思います。こっちのほうが計算しない分はやいでしょう。 また、変数自体をbooleanにしてもいいと思います。
//フラッシュの判定 boolean isFrash = false; if (sortHand[0].getMark().equals(sortHand[1].getMark()) && sortHand[1].getMark().equals(sortHand[2].getMark()) && sortHand[2].getMark().equals(sortHand[3].getMark()) && sortHand[3].getMark().equals(sortHand[4].getMark()) ) { isFrash = true; } 全部のマークが同じならフラッシュです。 ちょっと冗長ですが、確実な方法ですね。 ループを使って判定してもいいと思います。 boolean isFrash = true; for (int i = 0; i < 4; ++i) { if (!sortHand[i].getMark().equals(sortHand[i + 1].getMark())) { isFrash = false; } } こんな感じかな?(確認してないです。) 最初にtrueにして、マークが違ってたらfalseにしています。
//ストレートの判定 boolean isStraight = false; if (sortHand[0].getNo() + 1 == (sortHand[1].getNo()) && sortHand[0].getNo() + 2 == (sortHand[2].getNo()) && sortHand[0].getNo() + 3 == (sortHand[3].getNo()) && sortHand[0].getNo() + 4 == (sortHand[4].getNo()) ) { isStraight = true; } boolean isRoyal = false; if (sortHand[0].getNo() == 1 && sortHand[1].getNo() == 10 && sortHand[2].getNo() == 11 && sortHand[3].getNo() == 12 && sortHand[4].getNo() == 13 ) { isRoyal = true; } これはまあ、みたまんまです。
あ、解説の順番逆だった・・・ まあいっか。
最後の約の判定は、まあ見たまんまですね。 yaku = 0; などとしているところは、0が何を意味しているかがこのソースだけでは分からないので、 役の名前の定数を作るとみやすくなると思います。 yaku = YAKU_ROYAL_STRAIGHT_FRASH;
と、いうわけで、ポーカー編はおしまい。 質問が合ったらどうぞ。
もうすこし小さなプログラムで解説してほしいなぁとか言って見たり。。。 ジャンケンとか。。。。ずっとスレ見てたけど もう、内容に着いていけないよう
>>282 じゃあ、じゃんけんを作ってみる?
と、いうわけで問題
STEP1
実行すると「ぐー」「ちょき」「ぱー」のどれかが表示されるプログラムをつくりなさい。
実行例:
ぐー
STEP2
実行すると二人がじゃんけんするプログラムをつくりなさい。
実行例:
CPU1:ぐー
CPU2:ちょき
「CPU1のかち!」
>>283 せんせー
じゃんけん、ifだらけになっちゃいました……(;´Д`)
285 :
182 :2005/05/02(月) 04:09:13
>>284 横レスすみませぬ。僕は先生じゃないですけど…。
対象をモデル化したとき、それがエレガントであればあるほど if 文は減る傾向にあります。
この場合、「ぐー」「ちょき」「ぱー」を整数で表しているとして、多分、じゃんけん特有の「三すくみ」の関係を上手く表現できてないからだと思います。
上手く表現するにはどうすれば良いかって?
「ぐー」「ちょき」「ぱー」を4進数で表してみるとか、勝敗をビット演算で算出してみるとか、そういうのがあると思います。
極端な話、対象(この場合は「じゃんけん」)を的確に表現できる体系(モデル)を用意できれば良い、という話に帰結できると思うのです。
実装は Comparable インターフェイスの compareTo メソッドかなぁ…。
とか言ってる僕も、ポーカーの正規表現をサポってるんですけどね!(汗
それに先生はこんな答え方はしないと思うんですけどね!(汗
>>284 >せんせー
>じゃんけん、ifだらけになっちゃいました……(;´Д`)
とりあえず、できたんだったらソースキボンヌ
(まあ、間違ってると思われるソースは上げづらいとは思いますが・・・)
ソース出す
↓
先生添削
↓
新しいソース出す
っていうループでやってくと、他の人にも参考になるのでその方向でお願いします。
(先生の参考にもなるし)
綺麗に作れる人>>とりあえず作れる人>>>>(こえられない壁)>>作れない人
っていうことで、壁は越えている状況なので、あとはこつを覚えれば
色々作れるようになると思いますよ!
>>286 >それに先生はこんな答え方はしないと思うんですけどね!(汗
そうでもないかなあ・・・とおもいましたが、後半難しく考えすぎw
もうすこし182は、アルゴリズムを単純に考えるといいとおもう。
>対象をモデル化したとき、それがエレガントであればあるほど if 文は減る傾向にあります。
これはまあ、そのとおりですね。無駄なif文が多いということは、無駄な判定が多いということ
逆に言えば、判定条件が複雑ということです。
判定条件を単純にすれば、すっきりするとおもいます。
>この場合、「ぐー」「ちょき」「ぱー」を整数で表しているとして、
>多分、じゃんけん特有の「三すくみ」の関係を上手く表現できてないからだと思います。
>上手く表現するにはどうすれば良いかって?
>「ぐー」「ちょき」「ぱー」を4進数で表してみるとか、勝敗をビット演算で算出してみるとか、そういうのがあると思います。
>極端な話、対象(この場合は「じゃんけん」)を的確に表現できる体系(モデル)を用意できれば良い、という話に帰結できると思うのです。
>実装は Comparable インターフェイスの compareTo メソッドかなぁ…。
難しく考えすぎだYO!
>とか言ってる僕も、ポーカーの正規表現をサポってるんですけどね!(汗
えー、そうなん。ていうか、先生もちょっと考えてみたけど
普通にif文使って組んだほうが簡単で分かりやすいとおもった。
(または、先生が素敵な正規表現をおもいついていない)
と、いうわけでヒント 「ぐー」「ちょき」「ぱー」は、数字の1,2,3で表す。 やらなきゃならない判定は、 ・「ぐー」と「ちょき」なら「かち」 ・「ぐー」と「ぱー」なら「まけ」 ・「ぐー」と「ぐー」なら「ひきわけ」 の3種類 (なんで、if文はそんなにいっぱいにならないとおもうんだけど・・・)
1MB 【vip】148 DL:浜田浜田 PASS:浜田浜田 じゃんけん
290 :
284 :2005/05/02(月) 10:50:20
>>286 ififififelseif orz
public class Janken {
public static void main(String[] args) {
//1から3のランダムな数をそれぞれに入れる
int CPU1 = (int)(Math.random() * 3)+1;
int CPU2 = (int)(Math.random() * 3)+1;
//ここからSTEP1のぐーちょきぱーのどれかを表示する
if(CPU1 == 1)System.out.println("CPU1 = " + CPU1 + " : ぐー");
else if(CPU1 == 2)System.out.println("CPU1 = " + CPU1 + " : ちょき");
else if(CPU1 == 3)System.out.println("CPU1 = " + CPU1 + " : ぱー");
if(CPU2 == 1)System.out.println("CPU2 = " + CPU2 + " : ぐー");
else if(CPU2 == 2)System.out.println("CPU2 = " + CPU2 + " : ちょき");
else if(CPU2 == 3)System.out.println("CPU2 = " + CPU2 + " : ぱー");
//ここからSTEP2のじゃんけんの判定
if(CPU1 == CPU2)System.out.println("あいこ");
else if(CPU1 == 1 & CPU2 == 2)System.out.println("CPU1の勝ち");
else if(CPU1 == 1 & CPU2 == 3)System.out.println("CPU2の勝ち");
else if(CPU1 == 2 & CPU2 == 1)System.out.println("CPU2の勝ち");
else if(CPU1 == 2 & CPU2 == 3)System.out.println("CPU1の勝ち");
else if(CPU1 == 3 & CPU2 == 1)System.out.println("CPU1の勝ち");
else if(CPU1 == 3 & CPU2 == 2)System.out.println("CPU2の勝ち");
}
}
えーと
>>147 を覚えていたので、ぱっと見でSTEP1は浮かびました。
自分でキター!と思った所は「あいこは1個でいいじゃん!」って気づいた所だけです(つД;)
とりあえず動いたと言うことで……さ、さぁ、みんなも恥ずかしがらずに!
291 :
290 :2005/05/02(月) 10:54:32
ハッ! もしかしてSTEP2の所…… if(CPU1 == CPU2){System.out.println("あいこ");} else if(CPU1 == 1 && CPU2 == 2 || CPU1 == 2 & CPU2 == 3 || CPU1 == 3 & CPU2 == 1)System.out.println("CPU1の勝ち"); else if(CPU1 == 1 & CPU2 == 3 ||CPU1 == 2 & CPU2 == 1 ||CPU1 == 3 & CPU2 == 2)System.out.println("CPU2の勝ち"); } これでいいんじゃ……(´・ω・`)
292 :
290 :2005/05/02(月) 11:02:23
>>291 あ、&&が&になってる。脳内変換おながいします。
ifのとこをelseにもってきたら(CPU1 == CPU2)書かなくていいので文字が少なくなりました(ノ∀`)
3連続でゴメンナサイ
>>289 意味不明・・・どっかにアップしたってこと?
>>290 >>291 >>292 ifには必ず{}をつけましょう。
STEP1
「ぐー」「ちょき」「ぱー」を配列に入れて表示をすっきりさせよう。
STEP2
だいたいOKです。
・あいこ
・CPU1のかち
・CPU1のまけ(CPU2のかち)
の3種類しかないので、
if(CPU1 == CPU2){
System.out.println("あいこ");
}else if(CPU1 == 1 && CPU2 == 2
|| CPU1 == 2 & CPU2 == 3
|| CPU1 == 3 & CPU2 == 1){
System.out.println("CPU1の勝ち");
}else{
System.out.println("CPU2の勝ち");
}
これでいいんじゃないかな。
>>あ、&&が&になってる。脳内変換おながいします。
ちゃんと動かしてから発表しよう!
294 :
290 :2005/05/02(月) 16:57:49
>>293 早くも添削が!
ifについてなんですが、Perlをやっていた(cgiを改造する程度)ので、{}つけないと気持ち悪いんですが、
方々のJavaのサイトを見ていたら、こぞって省略出来る!と書いてあったので
省略した方がJavaらしいのかなぁ、とか思って消してみました。
省略は出来るけど、しない方が間違いが無いからいいよ、って理解でいいんでしょうか。
というわけで先生の添削にしたがっt……
あああああああわかった!
public class Janken {
public static void main(String[] args) {
int CPU1 = (int)(Math.random() * 2)+0;
int CPU2 = (int)(Math.random() * 2)+0;
String arr[] = {"ぐー" , "ちょき" , "ぱー"}; //0=ぐー 1=ちょき 2=ぱー になる
//ここからSTEP1 ちょっとすっきり!
System.out.println("CPU1 : " + arr[CPU1]);
System.out.println("CPU2 : " + arr[CPU2]);
//ここからSTEP2 あいこなのかい?それともCPU1の勝ちなのかい?それともそれ以外かい?
if(CPU1 == CPU2){System.out.println("あいこ");}
else if(CPU1 == 1 && CPU2 == 2 || CPU1 == 2 && CPU2 == 3 ||
CPU1 == 3 && CPU2 == 1){System.out.println("CPU1の勝ち");}
else{System.out.println("CPU2の勝ち");}
}
}
こうだー!(´∀`) タブン
>>280 >yaku = YAKU_ROYAL_STRAIGHT_FRASH;
まだ定数って教えてなかったですね。ごめんなさい。
そのうちでてくるので、今は忘れてください。
>>294 >ifについてなんですが、Perlをやっていた(cgiを改造する程度)ので、{}つけないと気持ち悪いんですが、
>方々のJavaのサイトを見ていたら、こぞって省略出来る!と書いてあったので
>省略した方がJavaらしいのかなぁ、とか思って消してみました。
>省略は出来るけど、しない方が間違いが無いからいいよ、って理解でいいんでしょうか。
そのとおりです。
「省略は出来るけど、しない方が間違いが無い」
というわけで、省略しないでください。
プログラムのほうは、今までの授業内容から言えば、文句なしのできです。
だいぶすっきりしたでしょ?
しいていうとすれば、変数名
まだならってないことなのですが、cpu1と小文字にしましょう。
そんなもんかな。
と、いうわけで、簡単練習問題シリーズ第2弾 じゃんけんを3回勝負にしてみてください。 ルール ・CPU1対CPU2の勝負 ・3回じゃんけんした結果で勝敗を決めるのではなく、 あいこの場合は、じゃんけんを続けて、2本先取したほうの勝ち 実行例 ・第1回戦 CPU1「ぐー」 CPU2「ちょき」 ->CPU1の勝ち ・第2回戦 CPU1「ぐー」 CPU2「ちょき」 ->CPU1の勝ち ・第3回戦 CPU1「ぐー」 CPU2「ぐー」 ->あいこ ・第4回戦 CPU1「ぐー」 CPU2「ちょき」 ->CPU1の勝ち CPU1の勝利!!
余談 プログラムを作るコツっていうか、作業の流れ ・とりあえず、やりたいことを思い浮かべる (いっぱいあるときは、紙に書く。練習問題のルール程度の箇条書きで) ・とりあえず、適当に作る (if文が多くても気にしない、うごけばOK) ・テストしてみて、間違いがないか調べる ・無駄っぽいところを探す (似たような処理があったりしてないか?つかってない変数はないか?) ・無駄があったら、なおして、テストに戻る。無駄がなくなったら完成 こんな感じでやるといいと思う。 普通は、本とか読むと ・設計をする ・作る ・テストする ・完成 って、なってるけど、その方法だと完璧な設計をしなきゃならないんだよね。 初心者には、完璧な設計なんてまず無理なので、最初は適当に作り始めて 何回も実行して、改造していけばいいと思う。 そのうち、こつが分かってきて、設計ができるようになるとおもうので。
>>297 寝る前に書き込み。
改行が多すぎるって怒られたので2つに分けます。
public class Janken2 {
public static void main(String[] args) {
int round = 1; //何回戦目か 勝負をした時点でカウントアップ
int win1 = 0; //cpu1の勝ち数
int win2 = 0; //cpu2の勝ち数
String arr[] = { "ぐー", "ちょき", "ぱー" }; //0,1,2
while (win1 < 2 && win2 < 2) {
int cpu1 = (int) (Math.random() * 2) + 0;
int cpu2 = (int) (Math.random() * 2) + 0;
System.out.println(round + "回戦目");
System.out.println("cpu1「" + arr[cpu1] + "」cpu2 「" + arr[cpu2] + "」");
その2 if (cpu1 == cpu2) { System.out.println("あいこなのでもう1回\n"); } else if ((cpu1 == 0 && cpu2 == 1) || (cpu1 == 1 && cpu2 == 3) || (cpu1 == 2 && cpu2 == 1)) { win1++; System.out.println("cpu1の勝ち 現在" + win1 + ":" + win2 + "\n"); } else { win2++; System.out.println("cpu2の勝ち 現在" + win1 + ":" + win2 + "\n"); } round++;//勝負が終わったのでラウンド数+1 } if (win1 > win2) { System.out.println("cpu1 " + win1 + "勝 : cpu2 " + win2 + "勝でcpu1の勝ち"); } else { System.out.println("cpu1 " + win1 + "勝 : cpu2 " + win2 + "勝でcpu2の勝ち"); } } } 半角スペースを全角に変換するのを忘れましたorz おやすみなさーい
変数名全部大文字にすると定数と間違えるんだっけ? あ、一つ教えてください。変数名の最初の文字は大文字でもいいですか? それとも全部小文字がいいですかね。 例 DATA→ダメなのは分かります。 Data→ダメですかね? gameData→こういうのなら全然OKですよね?
えーっと、突然ですが新しいのを覚えましょう。
while (条件) {
}
条件がtrueの間{}の中を繰り返します。
>>299 でも使われてるし便利なので覚えよう。
>>301 >変数名全部大文字にすると定数と間違えるんだっけ?
>あ、一つ教えてください。変数名の最初の文字は大文字でもいいですか?
>それとも全部小文字がいいですかね。
えーっと、言語仕様では何でもいいんだけど、一般的に変数の名前の付け方には
ルールがあります。
■絶対守ったほうがいいルール
・定数は大文字で、単語と単語の区切りは_
例:GET_TEXT
・変数、メソッド名は小文字で、単語と単語の区切りは後に続く単語の先頭を大文字に
例:getText
・クラスは変数と同じルールで先頭大文字
例:GetText
■まあまあ守ったほうがいいルール(このスレでは絶対守る)
・boolean型の変数の先頭はisにする。isXx で、Xxかどうかをあらわす(Xxならtrue)
例:isGetData ← getDataに成功してたらtrue
isStraight ← ストレートならtrue
悪い例:isFlag ← 何のフラグか分からない
isCheck ← チェックに成功したらtrueなのか失敗したらtrueなのか分からない
■どっちでもいいルール(このスレでもどっちでもいい)
・グローバル変数(クラス変数)の先頭または最後に_をつける
例:_passWord, passWord_
■すたれつつあるルール(このスレではやらない)
・変数の型を先頭または最後につける
例:charPassWord passWordChar
>>299 それでは、おまちかねのプログラムを見てみましょう
文句なし!
90点レベルだとおもいます。
あ、ごめん >String arr[] = { "ぐー", "ちょき", "ぱー" }; //0,1,2 ここは String[] arr = { "ぐー", "ちょき", "ぱー" }; //0,1,2 こっちのほうがいいかな。 まあ、どっちでもいいんだけど、このスレでは下の書き方で 一般的にも下の書き方のほうが多いとおもいます。
先生も作ってみた。 public class Janken { public static void main(String[] args) { int round = 0; int[] score = { 0, 0 }; int win; String[] player = { "CPU1", "CPU2" }; String[] arr = { "ぐー", "ちょき", "ぱー" }; while (score[0] < 2 && score[1] < 2) { int[] te = new int[2]; te[0] = (int) (Math.random() * 2); te[1] = (int) (Math.random() * 2); round++; System.out.println(round + "回戦目"); System.out.println(player[0] + "「" + arr[te[0]] + "」" + player[1] + "「" + arr[te[1]] + "」");
if (te[0] == te[1]) { System.out.print("あいこなのでもう1回"); } else { if ((te[0] == 0 && te[1] == 1) || (te[0] == 1 && te[1] == 3) || (te[0] == 2 && te[1] == 1)) { win = 0; } else { win = 1; } score[win] = score[win] + 1; System.out.print(player[win] + "の勝ち"); } System.out.println(" 現在" + score[0] + ":" + score[1]); System.out.println(""); } if (score[0] > score[1]) { win = 0; } else { win = 1; } System.out.println(player[0] + "=" + score[0] + "勝 : " + player[1] + "=" + score[1] + "勝で" + player[win] + "の勝ち"); } }
プレイヤーを配列であらわしてみました。 この方法の利点として、printlnがひとつにまとまっています。 配列を利用することによって、このように簡単にまとめることが できるようになりました。 そして、同じ処理をひとつにまとめることによって、 保守性があがるというわけです。 逆に、ソースが難しくなった感じがします。 cpu1,cpu2といった変数ではなく、te[0],te[1]といった配列になったので。 このへん、どっちを採用するかは、微妙なところですね。 まあ、参考ということで。
309 :
299 :2005/05/04(水) 02:10:50
>>308 ヤター(´∀`)
配列の書き方は了解です。
よくよく見るとメインメソッドの所とかEclipseに任せると String[] argsになりますね。
自分的にはString args[]の方が意味合いがわかりやすい感じがしてたんですけど
Java関連の本やらWebやらみるとやっぱり前者が多いのでそっちに合わせます。
先生のソース、全体的にぱっと見たら正直頭に入りづらい気もしたんですが、
String[] player = { "CPU1", "CPU2" };
String[] arr = { "ぐー", "ちょき", "ぱー" };
とかのとこ見るとすっきりしている様な気も。
でも多分まだよく理解してないので、そういう方法もあるよー、くらいで覚えます。
後、自分と同じ様なレベルの方に小ネタ。
このスレに従っているならEclipseを導入してると思いますが、
例えば自分のインデントが全くないソースとかをEclipseにコピペして、
Ctrl+A(全選択)した後にCtrl+Shift+Fを押すと勝手にインデントしてくれます、便利。
Ctrl+Iがインデントの訂正、になってますがCtrl+Shift+Fの方が見やすい気も。
その辺は好きな方でドゾー
見ながら打ち込んだ方がいいのはいいと思いますけども(´・ω・`)
と、いうわけで問題第3弾 1から10までの数字の書いてあるカードをよくまぜて、 上から1まいずつとって、その数字を比べる 例 CPU1:「3」 CPU2:「5」 CPU2の勝ち! ※同じデッキからカードを取るため、引き分けはなし。
せんせー、ひ、ヒント……これでググれ!とかOTL
>せんせー、ひ、ヒント……これでググれ!とかOTL えーっと、基本的に、このスレ最初から見れば作れる 問題しか出してないよー。 STEPに分けてみたので、順番に作っていこう! ポーカーのソースが参考になるよ。 STEP1 1から10までのカードをあらわす配列を作り、値を設定 (以降、デッキと呼ぶ) STEP2 デッキをシャッフル STEP3 CPU1,CPU2の手札をいれる変数を作り、 デッキの1枚目、2枚目を設定 STEP4 CPU1、CPU2の手札の数字を比べる
313 :
182 :2005/05/05(木) 09:27:20
作ってみました。コードの意味的にはかなり手抜き部分が多いですが… 「Battle.java」1本に入れてコンパイルしてくらさい。 ---- start --------------------------------------- public class Battle { public static void main( String[] args ) { Deck deck = new Deck(); for (int i = 0; i < 10; i++) { // 手抜き deck.suffle(); Card cpu1 = deck.getCard(); Card cpu2 = deck.getCard(); System.out.println("CPU1:" + cpu1.toString() + " " + CPU2:" + cpu2.toString()); if (cpu1.compareTo(cpu2) > 0) { System.out.println("CPU1 の勝ち"); } else if (cpu1.compareTo(cpu2) < 0) { System.out.println("CPU2 の勝ち"); } else { System.out.println("ありえない。バグってます"); } System.out.println(); } } }
314 :
182 :2005/05/05(木) 09:28:29
class Deck { private static final int RANKS = 10; private Card[] cards = new Card[RANKS]; private int order = 0; Deck() { for (int i = 0; i < RANKS; i++) { cards[i] = new Card(i + 1); } } void suffle() { for (int i = 0; i < RANKS; i++) { int idx = (int)(Math.random() * (RANKS - i)); Card tmp = cards[i]; cards[i] = cards[i + idx]; cards[i + idx] = tmp; } order = 0; }
315 :
182 :2005/05/05(木) 09:29:18
Card getCard() { if (order + 1 >= RANKS) { System.err.println("もうカードが無いよ"); // 手抜き処理… return null; } return cards[order++]; } // テストドライバ public static void main( String[] args ) { Deck deck = new Deck(); for (int i = 0; i < deck.cards.length; i++) { System.out.println(deck.cards[i].toString()); } } }
316 :
182 :2005/05/05(木) 09:30:46
class Card implements Comparable { private int rank; Card( int rank ) { this.rank = rank; } int getRank() { return rank; } public int compareTo( Object o ) { Card other = (Card)o; return other.rank - this.rank; } public String toString() { return "[" + rank + "]"; } } ------------------------------------------------ 元ネタは前に作ったポーカーです。
317 :
182 :2005/05/05(木) 09:36:16
あぎゃー!致命的ミス。
>>316 の
return other.rank - this.rank;
を
return this.rank - other.rank;
に修正下さい。
勝敗が逆になってしまふ…。
先生自宅だ!java入ってないから動かせないので、
>>314 のソースはまだ実行してないのですが、とりあえず、よさそうです。
で、新ルール
「ならってない命令はつかわない」
今、このスレで習っている命令をうまく組み合わせるって言うのも
勉強のひとつなので、あと、このスレしか見てない人が理解できないから。
あと、これは、先生の問題の出し方が悪かったのですが、
カード、デッキについては、今回はクラスを使わないでやりましょう。
と、いうわけで、STEP1の
>1から10までのカードをあらわす配列を作り、値を設定
>(以降、デッキと呼ぶ)
は、下記のようになります。
int[] deck = new int[10];
for (int i = 0; i < 10; ++i) {
deck[i] = i + 1;
}
>>182 も時間があれば、上の内容でもう一度作ってみてください。
(
>>182 の実力ならすぐできると思います。)
>>313 ソース見てみました。(動かしてないけど)
>for (int i = 0; i < 10; i++) { // 手抜き
手抜きって言うコメント入れるくらいなら、
勝負を10回繰り返すってコメントにしてほしかったです。
Cardクラスの作り方も良いですね。
DeckクラスのgetCardの
>if (order + 1 >= RANKS) {
>System.err.println("もうカードが無いよ"); // 手抜き処理…
の部分は、今回のプログラムでは2枚しか引かないので何でも良いのですが
どうせ作るならデッキをシャッフルしなおして先頭の1枚を返すとかにすると
良かったのでは?(まあ、どうせ呼ばないから何でも良いけど)
320 :
182 :2005/05/05(木) 17:38:45
先生、どもです。 > で、新ルール > 「ならってない命令はつかわない」 > 今、このスレで習っている命令をうまく組み合わせるって言うのも > 勉強のひとつなので、あと、このスレしか見てない人が理解できないから。 むむう、失礼しました。ということは、コンストラクタはまだダメ、ってことですね…。以後、了解です。 もしかして implements Conparable もまだ禁止? implements 自体はこの講座で既に出ているので良いかと思ったのですが…。 > どうせ作るならデッキをシャッフルしなおして先頭の1枚を返すとかにすると > 良かったのでは?(まあ、どうせ呼ばないから何でも良いけど) 作りとしては、1回の勝負毎にデッキ全体をシャッフルして、CPU1 と CPU2 が上から1枚ずつ取ってます。 シャッフルのアルゴリズムには自信があります。なぜなら、こいつはソートアルゴリズムと逆の操作を行っているからです。 デッキからカードが尽きた場合にどうするかは悩んだんですが、「メッセージを出さずに null を返すだけ」にするのが正解だったな、と今は思います。 デッキからカードが尽きたかどうかは、カードを引く側が判断して、然るべき事後処理を行うべきだ、と。 そうすれば、カードをデッキに戻さずに CPU1 と CPU2 が順々にカードをめくって勝負する、というよう形に変更した場合の表現が自然になるように思いました。 これから飲み会なので、帰ってきたらコードを書き直してみます。それでは。
>>320 >implements 自体はこの講座で既に出ているので良いかと思ったのですが…。
質問の答え系のは禁止の方向で。
>シャッフルのアルゴリズムには自信があります。
>なぜなら、こいつはソートアルゴリズムと逆の操作を行っているからです。
「ソートアルゴリズムと逆の操作を行っている」から
っていう理由が良く分からないけど、混ざってるしループの回数も少ないので良いかと思います。
この辺は、この前も書きましたがこのみでよいかと。
>デッキからカードが尽きた場合にどうするかは悩んだんですが、
エラー処理をどこにおくかですね。
今のままだと、エラー処理が中途半端なので・・・
エラーにするなら、引いた側にエラー処理を入れる、エラーにしないなら
今の場所で適切なカードを渡すっていう風にするといいと思います。
>これから飲み会なので、帰ってきたらコードを書き直してみます。
がんばってください!
先生だったら飲んだらプログラム無理w
322 :
182 :2005/05/06(金) 02:56:04
先生。書き直しました(すんません、ベロベロに酔ってます)。 ---- start ---------------------------------------- public class Battle2 { private static final int RANKS = 10; public static void main( String[] args ) { int[] deck = new int[RANKS]; int order = 0; for (int i = 0; i < RANKS; i++) { deck[i] = i; } for (int i = 0; i < 10; i++) { // 10回勝負! for (int j = 0; j < RANKS; j++) { // シャッフル int idx = (int)(Math.random() * (RANKS - j)); int tmp = deck[j]; deck[j] = deck[j + idx]; deck[j + idx] = tmp; } order = 0; int cpu1 = deck[0]; int cpu2 = deck[1]; System.out.println("CPU1:[" + cpu1 + "] CPU2:[" + cpu2 + "]");
323 :
182 :2005/05/06(金) 02:57:18
if (cpu1 > cpu2) { System.out.println("CPU1 の勝ち"); } else if (cpu2 > cpu1) { System.out.println("CPU2 の勝ち"); } else { System.out.println("ありえない。バグってます"); } System.out.println(); } } ------------------------------------------------- (やべ、タブを変換し忘れた…)
先生教えてください。 j2se1.4.2をEドライブのjavaディレクトリに入れて以下のように環境を設定したんですが どうもパスが通らないです。もしかしてWindowsが入ってるドライブがCなので ドライブが違うとPATHが通らないのですか(;´Д`) CLASSPASS .;%JAVA_HOME%\lib\tools.jar JAVA_HOME E:\java PATH ;%JAVA_HOME%\bin
訂正 >CLASSPASS .;%JAVA_HOME%\lib\tools.jar CLASSPATH .;%JAVA_HOME%\lib\tools.jar
追記 私はWindowsXP SP2です
解決しなかったので、Cに入れ直しました。
329 :
◆WtRerEDlHI :2005/05/07(土) 08:42:16
>>325 SET JAVA_HOME=D:\j2sdk1.5.2_06
SET PATH=%PATH%;%JAVA_HOME%\bin
SET CLASSPATH=.;%JAVA_HOME%\lib\tools.jar
っていう順番にしないとだめだよ。
JAVA_HOMEに値を入れて、その値を下の2行で使っているので。
OSは特に関係ないです。まあ、Cに入れて動いたんだったら良いかな。
順番が重要なんですね。ありがとうございました。
>>182 の作ったソース動かしてみました。
間違ってる・・・
for (int i = 0; i < RANKS; i++) {
deck[i] = i;
}
1〜10までの数字がカードに入らなきゃだめなのに
0〜9になっています。
>>318 に答えあるのにw
int[] deck = new int[10];
for (int i = 0; i < 10; ++i) {
deck[i] = i + 1;
}
と、いうわけで次からは回答
public class Game { public static void main(String[] args) { int[] deck = new int[10]; for (int i = 0; i < 10; i++) { deck[i] = i + 1; } //シャッフル int deckLength = 10; for (int i = 0; i < 200; ++i) { int x = (int) (Math.random() * 10); int y = (int) (Math.random() * 10); int swapCard = deck[x]; deck[x] = deck[y]; deck[y] = swapCard; } //手札 int[] hand = new int[2]; for (int i = 0; i < 2; ++i) { hand[i] = deck[i]; System.out.println("CPU" + (i + 1) + "[" + hand[i] + "]"); } //勝負 int max = 0; for (int i = 1; i < 2; ++i) { if (hand[i] > hand[max]) { max = i; } } System.out.println("CPU" + (max + 1) + "の勝ち"); } }
デッキ作る部分は前回答え書いたので解説は省略 シャッフルは、ポーカーのときと同じなので、これも解説省略 //手札 int[] hand = new int[2]; for (int i = 0; i < 2; ++i) { hand[i] = deck[i]; System.out.println("CPU" + (i + 1) + "[" + hand[i] + "]"); } CPUの手札を表す配列handを定義して、デッキの先頭からセットします。
334 :
◆WtRerEDlHI :2005/05/08(日) 14:05:23
次は勝負の部分、あれ?っておもった人も多いはず。 どっちが大きいか?ではなく、handの中で、一番大きいのはどれか? を、さがしています。 //勝負 int max = 0; for (int i = 1; i < 2; ++i) { if (hand[i] > hand[max]) { max = i; } } System.out.println("CPU" + (max + 1) + "の勝ち"); }
335 :
◆WtRerEDlHI :2005/05/08(日) 14:12:14
と、いうわけで練習問題 CPUの数を4人に増やしてみよう!
336 :
◆WtRerEDlHI :2005/05/08(日) 14:16:00
まあ、べつに回答を待つわけでもない問題なので即答えの発表 プレイヤー数を表す2を4に変えればOK //手札 int[] hand = new int[4]; for (int i = 0; i < 4; ++i) { hand[i] = deck[i]; System.out.println("CPU" + (i + 1) + "[" + hand[i] + "]"); } //勝負 int max = 0; for (int i = 1; i < 4; ++i) { if (hand[i] > hand[max]) { max = i; } } System.out.println("CPU" + (max + 1) + "の勝ち"); }
337 :
◆WtRerEDlHI :2005/05/08(日) 14:22:26
で、ここで面倒なのが2を使ってる場所が3箇所あったということ 毎回、数が変わるたびになおしていると、 直し漏れがあったりしてバグの原因になる。 そこで、プレイヤー数を表す変数を作っておく。 ついでに、カードの数も作っておく
338 :
◆WtRerEDlHI :2005/05/08(日) 14:23:00
public class Game { public static void main(String[] args) { int[] deck = new int[10]; int maxHand = 4; int maxCard = 10; for (int i = 0; i < 10; i++) { deck[i] = i + 1; } int deckLength = maxCard; for (int i = 0; i < 200; ++i) { int x = (int) (Math.random() * maxCard); int y = (int) (Math.random() * maxCard); int swapCard = deck[x]; deck[x] = deck[y]; deck[y] = swapCard; } int[] hand = new int[maxHand]; for (int i = 0; i < maxHand; ++i) { hand[i] = deck[i]; System.out.println("CPU" + (i + 1) + "[" + hand[i] + "]"); } int max = 0; for (int i = 1; i < maxHand; ++i) { if (hand[i] > hand[max]) { max = i; } } System.out.println("CPU" + (max + 1) + "の勝ち"); } }
339 :
◆WtRerEDlHI :2005/05/08(日) 14:24:36
これであとは、 int maxHand = 4; int maxCard = 10; の値を変えれば、自由にCPUの数やカードの最大値を かえることが出来る 保守性があがった!
340 :
◆WtRerEDlHI :2005/05/08(日) 14:30:00
ただ、問題がある。それは、 int maxHand = 4; int maxCard = 10; の部分が、普通の変数であるということ。このソースを始めてみた人は maxHandの値が常に4なのか、それとも変動するのかわからない。 (ソースを全部調べることになる。) そこで、新しくfinalというのを覚えます final int MAX_HAND = 4; final int MAX_CARD = 10; 値の変わらない変数を定義することが出来ます。 この、値の変わらない変数を定数といいます。 定数は大文字で、単語と単語の区切りは_ であらわします。 これにより、変数名を見ただけで、定数と分かるようになり、ソースの可読性があがります。
341 :
◆WtRerEDlHI :2005/05/08(日) 15:13:16
あと、今回はmainしかありませんが、普通は他のメソッドでも使えるため、 また、後で変更するときにソースの上にあると分かりやすいという理由から クラス変数にします。 で、まとめるとこんな感じ
342 :
◆WtRerEDlHI :2005/05/08(日) 15:13:49
public class Game { private static final int MAX_HAND = 4; private static final int MAX_CARD = 10; public static void main(String[] args) { int[] deck = new int[10]; for (int i = 0; i < 10; i++) { deck[i] = i + 1; } int deckLength = MAX_CARD; for (int i = 0; i < 200; ++i) { int x = (int) (Math.random() * MAX_CARD); int y = (int) (Math.random() * MAX_CARD); int swapCard = deck[x]; deck[x] = deck[y]; deck[y] = swapCard; } int[] hand = new int[MAX_HAND]; for (int i = 0; i < MAX_HAND; ++i) { hand[i] = deck[i]; System.out.println("CPU" + (i + 1) + "[" + hand[i] + "]"); } int max = 0; for (int i = 1; i < MAX_HAND; ++i) { if (hand[i] > hand[max]) { max = i; } } System.out.println("CPU" + (max + 1) + "の勝ち"); } }
シャッフルのところが理解出来ない…… 漏れ頭悪いのかな……(つД;) 入門書を読み直してきます(´Д`)
>>343 どのへんが理解できない?
具体的に教えてくれるとうれしい。
あと、ミス発見
>int deckLength = MAX_CARD;
この変数つかってないですね。すみません。
このことだったら、ごめん・・・。
345 :
182 :2005/05/13(金) 03:34:32
生意気にも先生自身に質問。
僕は、「Java は Generic(汎用的)でない」という印象を持ってます。1.5 でいくらか改良されたようですが。
「オブジェクト指向は汎用指向ではない」と言い換えても構いません。
C++ の STL の方がまだマトモだって気がします。
でも、STL は C++ の言語仕様とは全く逆行しているような代物だ…。だからこそ成功した、ってくらいに。
相反するものを内包した C++ はやりたくない。
かといって、無理やり Generic を導入したような Java も受け入れがたい(Java の仕様が求められた時代背景は充分に理解しているつもりです)。
悩んでます。
先生はどうです?
>>331 における間違いは、了解です。酔ってました。すんませんです。
>>343 はシャッフル分かった?
>「オブジェクト指向は汎用指向ではない」と言い換えても構いません。
汎用という言葉が何を指しているのか、って事にもよるんだけども、
文字通り、広く一般的に用いることができる・・・と、いうのであれば
先生は、汎用的だと思う。
まず第一に、VMの存在
従来の、特定のマシンの上でしか動かないほかの言語に比べ、
Javaは、VMの用意されているすべてのマシン上で同じソースを実行することができる。
これは、今までになかった考え方。とはいえ、現実では最も一般的なWindowsの実行ファイルが
作成できないという致命的な欠点も持っている。また、VMのインストールも、
DLLやランタイムのインストールとは比べ物にならないほど面倒で大きい。
ただ、業務で考えれば、将来を含め複数のマシンで実行が可能なのはすばらしい。
つづき 第二に、これが聞きたかったんだろうけど、言語仕様について オブジェクト指向は、拡張性に優れ、部品ごとに管理、再利用が簡単だし、 明確にルール付けがされているので、一度プログラムを作ってしまえば、 その再利用や拡張が簡単に行える。 一度作ってしまえば、あとは、そのパッケージを呼ぶだけで ほかのプログラムでも変更なしに使える仕組みが確立されているって言うのは かなりの利点だと思う。また、言語使用もそういったことを最初から意識して 作ってあるので、分かりやすいと思う。 って、思いつくままかいていて思ったのだが いまいち、「汎用」の意味が分かってない気がしてきた。 こんな意見で役に立った?
ちなみに、今言語を覚えたいって言うなら、 先生のおすすめは、 1.Java 2..net(C#) 3..net(VB) かなあ。 まず、必要だと思われるのが ・統合環境がそろっている ・オブジェクト指向である この2点は大事だと思う。開発効率や再利用性が重視されていることは 大事だし便利、あと、いまさらオブジェクト思考じゃない言語を覚えるくらいなら オブジェクト指向の言語を覚えたい。 次に、応用が利くかどうか javaは、覚えてしまえば、ウェブアプリ作成、携帯アプリ作成など、 いろいろと応用が利く。また、FLASHで採用されているActionScriptなどにも似ているので 応用が利くだろう。VBやCを覚えるにしても、無駄にはならないはずだ。 ただ、欠点があって、Windows用のソフトを作れない。これ最悪。 なんで、C#が時点、そのつぎはVBかな。 まあ、なんでもいいから、言語を一個覚えちゃうと後はらくだと思う。 で、その最初に覚える言語がオブジェクト指向言語だったら、 オブジェクト指向じゃない言語も覚えやすい。
つづき 極論になっちゃうけど、結局は、言語には意味がなくて 最終的完成するプログラムに意味がある。 なんで、自分の作りたいものが明確なら、それに特化した 言語を最初から覚えるのが手っ取り早いと思う。 そうじゃないなら、先生はJavaおすすめ。
350 :
java初心者 :2005/05/13(金) 19:39:02
Javaを勉強し始めましたm(_ _)m JMaker(Java 2 SDK GUI 版開発エディタ )を使っています。 で、参考書をみながら言語を打ってコンパイルしようとしたら 「Java 2 SDKのbinパスが不正なためコンパイルできません。 binパスを確認してください。」 とでました;; Yahooとかでbin設定やらなんやら検索したのですが、 細かい、こういうとこの設定方法は載っていませんでした。 載っていると思うのですが、探しましたたが見つかりませんTT C\java\ の中に jmake042(の中にJMakerがあります)が入ってます。 ツール→環境設定 のbin設定がわかりませんTT 初心者のあんぽんたんな質問すいませんTT ご教授お願いしますm(_ _)m
>>350 Java2 SDK はインストールしてありますよね?
ならば,そのときにSDKをインストールしたフォルダを参照すべし。
標準なら,
C:\Program Files\Java\jdk1.5.0_03\bin
になるはず。(1.5.0_03の部分はバージョンによって違う)
352 :
デフォルトの名無しさん :2005/05/13(金) 22:09:31
ぼきはC言語以外信じません!
353 :
343 :2005/05/14(土) 00:06:47
>>344 久々にスレをみる時間が……
配列 0 1 2 3 4 5 6 7 8 9
for いっぱい{
random1で(仮に)1が選ばれる
random2で(仮に)5が選ばれる
1と5を入れ替える
}
何度もやった結果、
配列 2 6 8 1 3 4 5 9 0 7
と、いう順番になりましたとさー
だと思ったんですが、これだと
random1 = 1; random2=1;と言う可能性も出てきますよね。
ということは根本的に考え方が間違ってるのかしらとかそんな感じです
ループの中に if(random1 == random2){break;}
とか入ってればそれで終わったんでつが……(´・ω・`)
>>350 >>2 sage進行
2ch自体初心者なのであれば メールアドレスを書く所に sage と書く。
このスレを荒らしたく無いならやるべし。というかやってください。
>>347 >って、思いつくままかいていて思ったのだが
>いまいち、「汎用」の意味が分かってない気がしてきた。
これは、先生が
>>182 の質問の意味を分かってないってことね。
念のため。182が汎用という言葉のいみをわかってないと
いっているのではないです。
>>353 for いっぱい{
random1で(仮に)1が選ばれる
random2で(仮に)5が選ばれる
1と5を入れ替える
}
ずばりそのとおりです。
結果、random1とrandom2で同じ数を選ばれる場合もありますが
それはそれで、想定の範囲内です。
ランダムに順序を入れ替えるということは、入れ替えないときもあるというのを
含んでいるので。
>ループの中に if(random1 == random2){break;}
たしかに、それが入っていれば・・・と、いうよりは、
if (random1 != random2) {
入れ替え処理
}
となっていれば、よかったのかもしれませんが、
・純粋に面倒
・そんな処理を入れなくても意味は通じる
・たまに、無駄な入れ替えをするコストよりも、毎回判定するコストのほうが大きい気がする
という理由により、特に判定は入れてないです。
つづき あと、話はそれますが、なるべくbreakは使わない方向で プログラムを作る癖をつけましょう。 (実際、この講座でも出てきてないし) for いっぱい{ random1で(仮に)1が選ばれる random2で(仮に)5が選ばれる if(random1 == random2){break;} 1と5を入れ替える } よりは、 for いっぱい{ random1で(仮に)1が選ばれる random2で(仮に)5が選ばれる if(random1 != random2){ 1と5を入れ替える } } こっちを書けるようになると良いです。
つづき 日本語にすると、前者は 「繰り返し処理をいっぱい行う。random1とrandom2を選び、 random1とrandom2が同じ場合は、処理中断する。 random1とrandom2の値を入れ替える。」 となり、ちょっと分かりつらいです。 後者は、 「繰り返し処理をいっぱい行う。random1とrandom2を選び、 random1とrandom2が異なる場合は値を入れ替える。」 となり、シンプルです。 breakがはいると、頭の中で「ちょっとおいといて・・・」みたいな 箇所ができるので、理解が難しくなる場合が多いです。 最初のうちは、break使わない方向で。 なれてくると、breakを使ったほうが得な場合が出てきますが それまでは、練習もかねてbreakは忘れてください。
と、いうわけで343は、理解できてる! と、いうことで・・・ ポーカー作ってみよう! また、分からないとこがあったら聞いてください。 ポーカーのソースを打ち込んでみた後に、 自分で最初から作ってみると勉強になると思います。
>>359 高速レスがw
息抜きにlinuxの設定を必死でやってついに2chに接続(´∀`)
セキュリティ的にはどうなんだ自分。何もしてないぞ。
書き込んでるのはWindows機ですが(´ω`)
>ランダムに順序を入れ替えるということは、入れ替えないときもある
「でも200回もやればいい加減混ざるだろ、トランプだって」
って事ですか。冷静に考えたらその通りですねorz
実際のトランプ考えればそうなる可能性だって十分にありえたりすると。
!=演算子での判定については了解です。
特別break;を使いたいとかそう言う訳でも無いので、
自然にそう考える癖だけつける様にします。
ちょっと綺麗なソースになるかは置いといて、
ポーカーにチャレンジしてみまっす(´∀`)(やっとここまで来た……)
361 :
java初心者 :2005/05/14(土) 03:24:32
351さん ありがとうございましたm(_ _)m 解決できました^^v がんばります!
362 :
◆WtRerEDlHI :2005/05/14(土) 13:43:50
>>361 >ちょっと綺麗なソースになるかは置いといて、
>ポーカーにチャレンジしてみまっす(´∀`)(やっとここまで来た……)
がんばって!
分からないとこあったら質問してください。
>>java初心者
このスレはsage進行です。書き込みするときは、メールのとこに
sage
と書いてください。
>>348 と書いてますが、delphiってどうですか?
delphiは微妙かなー VB6よりは素敵だけど、言語が普及してるか?っていうのを考えると .netのVBの法がいいと思う。.netのVBはC#にも応用ができるしね。 別に無料ってわけでもないし。いい言語だとは思うのですが、 微妙だと思います。 .netの強みは、やっぱMicrosoftなんで、APIとか標準で全部使えるって事だよね。 DirectXとか。 そういう点が、Delphiは低い。 ただ、単体で動く(ランタイムとかの必要がない)実行ファイルを手軽に作れるのは いいと思う。 まあ、すべて先生の個人的な意見なので 自分の好きなのをやればいいと思うよー。 まずは、ひとつ言語を覚えて、そのあとに、作りたいプログラムができたら それにあわせて、言語をかえれば良いんじゃないかな。
誠に個人的なことでありますが、少々添削更新しました。
http://nori.voxx.jp/ で、一つ質問があります。
ここはJava講座となっていますが、本当にJavaの基礎のみ学ぶスレでしょうか?
または、Javaと言えばWebアプリケーション!みたいな勢いで
JSPやサーブレット、Strutsなんかもやっていくのでしょうか。
>>365 更新お疲れ様です!
講座については、あんまし考えてなくて・・・
DBを扱う何かをやりたいんだけど、環境をそろえるのが難しいので
どうしようかなあ・・・と、考え中
System.out.printlnだけだと、つまらないし
何か新しいことしたいけど、それにはいろいろ覚えることが増えるので
どうしようかなあ・・・って感じです。
携帯アプリとか手軽で良いかな?とかもおもったり。
今のままだと、出力だけで入力が無いからつまんないんだよね
ゲームとか作りながらとかだと、面白いんだろうけど
そこまで、基本が学べてないからなあ。
とはいえ、今のレベルならポーカーくらいは作れちゃうわけだけどw
もうすこし、基本を覚えてそれからですかね。
と、いうわけで、今日からは新しい問題をやっていこう! ○×ゲームを作ります。 コンピュータが対戦するものです。 実行結果のイメージとしては ○・・ ・・・ ・・・ ○・・ ・×・ ・・・ ○・・ ○×・ ・・・ ○・・ ○×・ ・×・ ○・・ ○×・ ○×・ ○の勝ち! という感じ
いきなり全部は難しいので、少しずつ考えていきましょう。 まずは、データの持ち方と、それを画面に表示する方法を考えよう。 3×3のマップがあって、その中には、 「・」 「○」 「×」 の三種類の状態があります。 これを、どのように処理すれば良いでしょうか? 考えてみてください。 STEP1 マップを作る STEP2 マップを表示する マップを表示する部分は、メソッドで作ってください void printMap(引数) という感じにします。 そうすると、 ○・・ ・×・ ・・・ が表示されることにします。
いろいろなやり方があると思うので、考えてみてください。 できたら発表してくれるとうれしいです。 (参考になるので) ただ説明するよりも、いろんな考え方が分かると勉強になるので どんどん発表してみてください。
先生、ゲームより何かもっと実用的なプログラムを教えて下さい。 HTMLのpretty-printするプログラムとか作りたいです。
374 :
360 :2005/05/18(水) 23:40:28
ポーカー出来ましたー(´∀`)
と、言っても結局どこまで効率化すればいいかわからず、
ある程度やったとこで先生のソースみてがっくり来ましたけどw
そして次の例題が出てましたが、ちょっと知人に例題を出されたので
そっちを先にかたづけてきます(`・ω・´)
>>373 それ、どっちかてーと正規表現だけ覚えた方が速い様な。
XML,XSLTとかなら別ですけども。
どうしてもJavaでHTMLを扱いたいならアレですけど。
いやでも先生がいい例題だと思ったならどうぞやって下さいませ。
>>373 >先生、ゲームより何かもっと実用的なプログラムを教えて下さい。
>HTMLのpretty-printするプログラムとか作りたいです。
テーマとしては面白いけど、まだそこまでのレベルじゃないんだよなー。
ファイルの読み書きなんかは、後半やる予定なので
そのときに、もしかしたら・・・どうだろ。
(今のところは、外字や水準外の文字を摘出する奴を作る予定でした。)
pretty-printのルールとか難しいからなあ。
あんまし、使い道なさそうだし・・・。
でも、テーマとしては面白いと思います。
HTMLをウェブ上から取得・・・は、難しいので
ローカルに保存してあるHTMLファイルを読み込んで、
整形して標準出力に書き出し・・・とかになるのかな?
フレームは、完全にあきらめるとして、
テーブルとかも、難しいね。無理・・・ではないけど、
上から順に処理すればいいわけじゃないから、かなり難しい。
あと、タグの処理とかも大変だと思うなあ。
と、いうわけで、当分は無理だけど、自分で作ってみて分からないとことか
質問してくれれば、できる限りは答えますよ。
(さすがに、ファイルの読み書きの基礎が分からないとかそういうレベルだったら
まずは、一緒に基本をこのスレでまなんで、技術をつけてから作りましょう。)
お、書き込んでる間に360が >ポーカー出来ましたー(´∀`) >と、言っても結局どこまで効率化すればいいかわからず、 >ある程度やったとこで先生のソースみてがっくり来ましたけどw おめでとう。でもまあ、できただけえらいと思います。 できたら、どういう風にがっくりきたかっていうのを、次からは教えてほしいな。 まあ、今回は良いけど。 どんな風な間違いをするかっていうのは、なかなか先生気がつかないんだよね。 あと、ほかの考え方とか。(良いか悪いかは別として) たとえば、シャッフルなんかでも、いろんなやり方があったでしょ? ああいう風に、いろんなやり方を知りたい。 先生にとっても、みんなにとっても参考になると思います。 と、いうわけで、皆がんばって問題できたらアップしよう! >そして次の例題が出てましたが、ちょっと知人に例題を出されたので >そっちを先にかたづけてきます(`・ω・´) これも、特別にアップしても良いよw
えー、で、話は変わって、なんでゲーム作ってるかについて。 1.身近な題材なのでイメージがつかみやすい たとえば、ポーカーとか、○×ゲームとかいちいち基本設計っていうか 仕様の説明がいらない。プログラムの作業で大事な 「仕様を理解する」「仕様を決める」というプロセスを簡略化できる。 2.今まで覚えた内容をいかせる それでいて、結構むずかしい題材を考えたつもり。 3.拡張ができる たとえば、ポーカーだったらジョーカー入れたらどうなる? とか、いろいろ考えられる。暇なら、自分で改造できるし。 そのうち、入力とかできるようになったら、自分でゲーム作れるしね。 と、いうわけで、最近はゲームばっかりですが、昔は自給計算とかしてたよw まあ、そんな感じで、「完成されたものを作る」と、いうよりは、 「言語を覚える、理解する」というところに重点を置いてるので 必然的に、こんな感じになると思います。これからも。
あー、今気がついた。 HTMLのpretty-printって、HTMLで表示される内容じゃなくって、 HTML自体のpretty-printかあ。 なんか、先生勘違いした。 それだったら、比較的簡単にできそうですね。 STEP1 ローカルにあるファイルを読込してバッファに保存 (このとき、どの単位でバッファに保存するかが考えどころ) STEP2 ・開始タグあるいは本文だったら、インデントして表示 ・終了タグだったら、インデントをもどして表示 (このとき、<BR>などの単体タグにも考慮?) こんな感じでループしていけばできそう・・・? 難しいのは、読み込んだ文字を区切るところ(タグもしくは本文という単位で区切る) だけなきがする。 あと、<BR>とかの終了タグがないタグの処理が面倒。 そんな感じで、できそう?もしできたら、おしえてくださいね。
379 :
360 :2005/05/19(木) 07:32:07
>>376 ええと、じゃんけん拡張版だそうです。
2人から10人で1回から999回のじゃんけんを行う。 あいこも1回と数える
1回ごとの勝負の表示結果は無くても良
全員の勝敗数、勝率を表示
勝ち数をグラフで表示
こんな感じで。
じゃんけんなんて仕事では作らないけど、
「もしクライアントと交渉の結果、こういうのを作る事になったらどうするか」だ、そうです。
入力部分は、とりあえずコマンドライン引数に入れろって話です。
さて仕事仕事……遅刻しそう……(´Д`)
>>379 作ってみた。
public class Janken2 {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("コマンドライン引数が2つ必要です");
System.exit(1);
}
int player = 0;
int round = 0;
try {
player = Integer.parseInt(args[0]);
round = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
System.out.println("コマンドライン引数は整数のみです");
System.exit(1);
}
if (player < 2 || player > 10) {
System.out.println("人数は2から10です");
System.exit(1);
}
if (round < 1 || round > 999) {
System.out.println("回数は1から999です");
System.exit(1);
}
int[] win = new int[player]; int[] loss = new int[player]; for (int i = 0; i < round; i++) { int[] te = new int[player]; for (int j = 0; j < te.length; j++) { te[j] = (int) (Math.random() * 3); } boolean[] arr = new boolean[3]; for (int j = 0; j < te.length; j++) { arr[te[j]] = true; } int arrNum = 0; for (int j = 0; j < arr.length; j++) { if (arr[j]) { arrNum++; } }
if (arrNum == 2) { for (int j = 0; j < te.length; j++) { if (!arr[0]) { if (te[j] == 1) { win[j]++; } else { loss[j]++; } } else if (!arr[1]) { if (te[j] == 2) { win[j]++; } else { loss[j]++; } } else { if (te[j] == 0) { win[j]++; } else { loss[j]++; } } } } }
for (int i = 0; i < player; i++) { System.out.println("player" + i + " : win " + win[i] + " : loss " + loss[i] + " : draw " + (round - win[i] - loss[i]) + " : avg " + (double) win[i] / round); } System.out.println(); for (int i = 0; i < player; i++) { System.out.print("player" + i + " :"); for (int j = 0; j < win[i]; j++) { System.out.print("*"); } System.out.println(); } } }
384 :
380 :2005/05/19(木) 16:13:44
>>382 の
if (arrNum == 2) {
は美しくないと感じたので
if (!(arr[0] ^ arr[1] ^ arr[2]) & (arr[0] | arr[1] | arr[2])) {
に変更します。
よって、
>>381 の下記部分は削除になります。
int arrNum = 0;
for (int j = 0; j < arr.length; j++) {
if (arr[j]) {
arrNum++;
}
}
先生!
>>384 の
if (!(arr[0] ^ arr[1] ^ arr[2]) & (arr[0] | arr[1] | arr[2]))
意味がわかりません。
全体的に理解不能な漏れは一体。
>>379 プログラムありがとう!早速見てみますね。
よくできてるっぽいじゃん(ぱっとみ)
家にはJavaないので、動かしてみたりできないけど
それはそれとして、動きをおっていきたいと思います。
>>385 まだならってないし、ちょっと難しい使いかたしてますね。
後で解説します。
>>386 先生が理解するプロセスを書いていくので一緒に理解しよう!
習ってないのが、少し使われているので、その辺は軽く意味合いだけ 解説します。 えーっと、まずは >if (args.length != 2) { >System.out.println("コマンドライン引数が2つ必要です"); >System.exit(1); >} 引数のエラーチェックですね。 引数が2個無かったらおわり。 >System.exit(1); は、エラー終了って意味です。 これは、仕様的なものなんだけど、 メッセージに、引数の説明があるとよかったのでは? 例: コマンドライン引数の数が間違っています。 Janken2 プレイヤー数 ラウンド数 プレイヤー数:1-10 ラウンド数:1-999 こんな感じとか。
あ、ちなみに、ソースの先頭から見て行き当たりばったりに思ったことかいてます。 そのほうが、参考になるかと思って。 >int player = 0; >int round = 0; >try { >player = Integer.parseInt(args[0]); >round = Integer.parseInt(args[1]); >} catch (NumberFormatException e) { >System.out.println("コマンドライン引数は整数のみです"); >System.exit(1); >} playerとroundという変数を作って、引数の値をintに変換して 代入しています。 try { 本文 } catch { エラー処理 } っていうのは、本文でエラーが出たら、エラー処理を行うという意味 parseIntでエラーが出たら(たとえば、引数が数字じゃなかったら) エラー処理を行っています。 >if (player < 2 || player > 10) { >System.out.println("人数は2から10です"); >System.exit(1); >} >if (round < 1 || round > 999) { >System.out.println("回数は1から999です"); >System.exit(1); >} で、うまくintにできたら、値の範囲をチェック。このへんはまあ、いい感じですね。 エラーメッセージについては、さっきのと同じ
で、次からがメイン処理かな? >int[] win = new int[player]; >int[] loss = new int[player]; まずは、勝敗を入れる変数を作成する。 配列にして、playerの数だけ作る。 ここもまあ、いい感じ。 lossじゃ無くてloseじゃねーの?って、気もするけど。 >for (int i = 0; i < round; i++) { ここからの処理をround分くりかえす。 言い換えれば、iが現在のround数になるわけだ。 >int[] te = new int[player]; >for (int j = 0; j < te.length; j++) { >te[j] = (int) (Math.random() * 3); >} えーっと、teっていうのが、今回の手が入る変数で、 player分の配列を用意して、そこにランダムな数を入れてる 気になるのがte.lengthかな、以降も出てくるけど playerの数って事が明確になるようにplayer使うと分かりやすいんじゃないかなあ。 上の処理も、「手の箱の数分、ランダムな手を用意する」んじゃなくって 「プレイヤーの人数分、ランダムな手を用意する」って感じだし。 でもまあ、ここまではいい感じですね。
>boolean[] arr = new boolean[3]; >for (int j = 0; j < te.length; j++) { >arr[te[j]] = true; >} ここから、意味分からなくなってきた・・・。 えーっと、arrっていうのは何だろう? playerやteと違って、変数名から内容が想像できないから だと思う。 arrという配列をつくり、グー、チョキ、パーが 存在した場合、trueをいれている。 ってことですね。 ※arrには、初期値としてfalseがはいっています。 te[j]には、グー、チョキ、パーのいずれかを示す0,1,2がはいっています。 te[j]が0の場合、arr[0]=trueになります。 これをプレイヤーの数だけ繰り返すことにより、 arr[0]には、グーがあればtrueなければfalseになります。 そんな感じ。
えーっと、つぎは訂正が入った場所ですが、 とりあえず、訂正前ので動きを追いましょう。 (訂正後のはならってない文法なので) >int arrNum = 0; >for (int j = 0; j < arr.length; j++) { >if (arr[j]) { >arrNum++; >} >} arrのtrueの数を数えてarrNumにいれています。 arr[0] = true; arr[1] = true; arr[2] = false; の場合、2が入るようです。
いままでのをまとめると player プレイヤーの数:1-10 round ラウンド数:1-999 手を表す数字 0,1,2(どれがグーなのかは、まだ不明) te[player] プレイヤーの手を表す数字が入る arr[手を表す数字] その手が使われていたらtrue使われていなかったらfalse arrNum 何種類の手が使われているか たとえば、 te[0] = 0 te[1] = 1 te[2] = 1 の場合、 arr[0] = true arr[1] = true arr[2] = false arrNum = 2 になる。
なるほど、arrNumのをしらべて、3だったら、あいこになる気がします。 (グー、チョキ、パーがいるので) arrNumが1でもあいこですね。(全員グーとか) arrNumが2の時は、グーとチョキとかそういうときなので 勝ち負けの判定をしなくちゃだめな気がします。 なんとなく、以降の処理の想像がついてきました。 それでは、続きを見ていきましょう。
>if (arrNum == 2) { arrNum==2のときだけ、以降の処理をしています。 arrNum==1のときと3のときは、何もしていないようです。 あいこはカウントしていないようなので、それでいいのでしょう。 >for (int j = 0; j < te.length; j++) { プレイヤーの数だけループしています。やっぱ、player使うと分かりやすいと思う。 >if (!arr[0]) { arr[0]がfalseだったら・・・ってことは、 グーが無かった場合は以降の処理 >if (te[j] == 1) { >win[j]++; プレイヤーjの手がチョキなら、プレイヤーの勝ちをカウント >} else { >loss[j]++; >} それ以外(パー)なら、負けをカウント。 なるほど。そういうことか。 全体(arr[])を見て、グーが無い場合は、必然的に、チョキとパーの勝負 なので、チョキのプレイヤーの勝ちをカウント、パーのプレイヤーの負けをカウント 理解できました。 あとは、おんなじ感じですね。 で、round分ループして、とりあえず、勝負の部分はおしまい
for (int i = 0; i < player; i++) { System.out.println("player" + i + " : win " + win[i] + " : loss " + loss[i] + " : draw " + (round - win[i] - loss[i]) + " : avg " + (double) win[i] / round); } System.out.println(); プレイヤーでループして、プレイヤーごとの勝率を表示 for (int i = 0; i < player; i++) { System.out.print("player" + i + " :"); for (int j = 0; j < win[i]; j++) { System.out.print("*"); } System.out.println(); } } } で、プレイヤーでループして、その中でwin[]の数分ループして *を表示することによって、グラフを表してる この部分は、よくできてますね。 (999試合したら、大変なことになるけど) いい感じです。
で、
>>384 の修正だけど、修正前のほうが素敵だと思います。
if (!(arr[0] ^ arr[1] ^ arr[2]) & (arr[0] | arr[1] | arr[2])) {
これを見ただけで、意味が理解できるでしょうか?無理だよね。
前のほうが、分かりやすい。
ちなみに、^は、排他的論理和(XOR)っていうやつです。
とりあえず、
>>385 は、気にしなくていいと思います。
ちょっとだけ解説すると論理演算子と呼ばれるもので、
& 論理積(AND)
| 論理和(OR)
^ 排他的論理和(XOR)
! 否定(NOT)
の4種類があります。!は前に解説したと思います。
これらは、boolean型の計算(?)に使われるもので
x & y
の場合、x==true AND y==trueの場合trueになります。
if文で使う&&や||との違いですが、
&&のほうは、ショートサーキット演算子(短絡演算子)といいます。
&&と&の違いですが、&&は右から見ていって条件になったら以降は判定しません。
>>161 参照
&の場合は、全部計算して最後に判定するという感じになります。
つづく
つづき 処理結果が異なってきて、紛らわしいので、&と|は使わず、常に&&と||を使うようにしましょう。 通常はそれで問題ないです。 ^も、特殊な処理意外は使わないと思いますので、^は使わなくてOKです。 !は、使っても良いです。っていうか、使うと思います。 ちなみにxがboolean型の場合 if (x) if (x == true) これは同じ意味 if (!x) if (x == false) これも同じ意味です。 !xは、!を見落としがちなので、あえて==falseの方を使う人もいますが、 このスレでは、あえて!を使うことにします。 if(式)の式の部分がbooleanであることを覚えてもらうためです。
まとめ 全体的によくできていると思います。 細かい点(te.lengthとか)はまあ、ありますが。 ただ、勝負のアルゴリズムが分かりづらいですね。 冗長になっても良いので、直感的に分かりやすいロジックで 作ったほうが、最終的にメンテ効率が上がると思います。 ちなみに先生だったら 前提条件 あいこかどうかの判定 勝負だったらSTEP1以降を行う STEP1 勝ちの手、負けの手を求める グーVSチョキなら、winHand = 0, loseHand = 1 グーVSパーなら、winHand = 2, loseHand = 0 チョキVSパーなら、winHand = 1, loseHand = 2 STEP2 プレイヤー数でループして以下の処理を行う 手がwinHandだったら、winをカウント 手がloseHandだったら、loseをカウント こんな感じかなあ。ぶっちゃけloseHandはいらないけどね。 (STEP2の判定をwinHandじゃ無ければloseをカウントにする)
STEP1は、全体の手の処理
STEP2は、各プレイヤーの処理
というふうに、分かれているのですっきりすると思います。
あと、じゃんけんの部分をif文で判定しているので分かりやすいというのもあります。
前にも書いたけど、実際の手順でやるっていうのは大事です。
とかいって、実際ソースにしてみないと微妙だけどw
と、いうわけで、役に立ったかな?
>>360 ありがとうでした。
>>385 、
>>386 は理解できましたか?
なんか、こういうのも面白いんで、200行以内くらいのプログラムだったら
みんな、作ったら声かけてアップしてよ。
ただし、ならっていない命令は使わない方向で。
(ならった瞬間アップしてくれるとうれしいw)
えー、あと、これは前々から思っていたのですが新ルールを設けたいと思います。 ・質問、その他の書き込みはトリップを付ける 誰が誰かよく分からなくなってきたので。コテハンは荒れたりいやな思いしてもアレなんで 禁止で、トリップのみの方向で 書き込みのときに名前欄に#+任意の文字列で、書き込んでください。 例:#javaProgram 以上、よろしくおねがいします。 最初のうちは、誰だか分かるように番号+トリップでお願いします。 以上です。
402 :
385 :2005/05/20(金) 01:02:56
380の人はいろんなこと知っているから分かるんだろうけど、 私みたいなヘタレにはコードを最初から辿って眺めても理解できないなぁ。 まぁ先生が言ったけど、変数名から想像できない部分があったかな。 あと、コマンドライン引数から入れるとデフォルトでString型になるのかな? それでInt型に型変換したのかな? あと、手の配列の箱を作るのに、プレイヤーの数で指定しているけど、 for文で手を入れるとき、わざわざ手の配列数で入れる回数を決めるから ちょっと混乱した。
そこまでは、理解できたけど、booleanの配列が出た付近から下はわかりません。
>>385 まずは、トリップを付けるんだ。話はそれからだ。
嘘
>あと、コマンドライン引数から入れるとデフォルトでString型になるのかな?
>それでInt型に型変換したのかな?
コマンドライン引数は、
public static void main(String[] args) {
のargsにはいります。見てもらうと分かるけど、String[]で定義されてますよね?
なんで、Stringになるというわけです。
この辺は
>>111 あたりからを復習してみてください。
基本的に、ならっていない部分を使っている場所も少ないし、
先生の解説をみながら、流れを追ってみてください。
分からない場所があれば、質問してみてー。
>>403 お、トリップついてる。ありがとうです。
なんか、同時に書き込んでるみたいだね。
>そこまでは、理解できたけど、booleanの配列が出た付近から下はわかりません。
>>393 のまとめの部分までは分かった?
分からない部分とか、具体的に書いてくれればおしえますよ。
あとは、先生の解説の
>>394 をもう少し詳しくとか、そんなのでもいいよ。
>>399 に従い
>>382 を変更して見ました。
if (arrNum == 2) {
int winHand;
if (!arr[0]) {
winHand = 1;
} else if (!arr[1]) {
winHand = 2;
} else {
winHand = 0;
}
for (int j = 0; j < player; j++) {
if (te[j] == winHand) {
win[j]++;
} else {
lose[j]++;
}
}
}
こちらの方がすっきりしますね。
te.length についてちょっと言い訳。 以前、何重にも込み入ったループをメンテしていたときに IndexOutOfBoundsException に悩まされたので ループを配列に固定する意味でこのようにしました。 でも、ちゃんと変数の管理をすればいいことなんですよね。 そんな私は現在失業中…orz
質問です。例えばこの上でやっているじゃんけんであるとか、
何かしらの仕様があった時に、それを具体的にどういうクラス、
フィールド、メソッドにしていけばいいのかがいまいちピンときません。
品詞と動作で分けろ、とか言われますがどうも……(´Д`)
プレイヤークラス フィールド 手
じゃんけんクラス フィールド ぐーちょきぱー 動作 じゃんけんをする
判定クラス フィールド じゃんけんのルール 動作 判定をする
よくわからんorz
後、クラスなりにわける意味としては、例えばサブクラスでのフィールドを
private で記述する事によってメインから変更出来ない様にし、
結果、バグ取りが楽になる、とかそんな様な理解でもいいんでしょうか。
また、俗にサブルーチンと呼ばれる物は、
Javaのクラスをプログラム全体としてとらえた場合の
メソッドにあたる物、と言う考えですが、これも自信無しです。
>>195 を見たんですが、どうも理解出来ません……orz
public static void main(String[] args) { for (int i = 0; i < round; i++) { play(); } showTable(); showGraph(); }
間違って途中で送信したorz public class Janken { static int player = 5; static int round = 100; static int[] win = new int[player]; static int[] lose = new int[player]; public static void main(String[] args) { init(args); // コマンドラインの処理は省略 for (int i = 0; i < round; i++) { play(); } showTable(); showGraph(); }
public static void play() { int[] hand = new int[player]; int[] used = {0, 0, 0}; // 手が使われたかを表す{グー(0), チョキ(1), パー(2)} for (int i = 0; i < player; i++) { hand[i] = (int)(Math.random() * 3); used[hand[i]] = 1; } int kinds = used[0] + used[1] + used[2];//何種類使われた? if (kinds == 1) return;// みんな同じ手を出したので「あいこ」で終了 if (kinds == 3) return;// みんなばらばらの手を出したので「あいこ」で終了 // 「勝ち」の手(0: グー, 1: チョキ, 2: パー)を求める // (A) グーが出ていない -> チョキ(1)が勝ち,パーが負ける // (B) チョキが出ていない -> パー(2)が勝ち,グーが負ける // (C) パーが出ていない -> グー(0)が勝ち,チョキが負ける int winhand; if (used[0] == 0) { winhand = 1; } // (A) else if (used[1] == 0) { winhand = 2; } // (B) else if (used[2] == 0) { winhand = 0; } // (C) else { return ; } // 通ることはない // 勝ちをカウント for (int i = 0; i < player; i++) { if (hand[i] == winhand) win[i]++; else lose[i]++; } }
412 :
デフォルトの名無しさん :2005/05/20(金) 13:51:32
>>406 早速ありがとう。やっぱすっきりするね。
3箇所同じような処理があったのを一箇所にまとめたので
理解しやすくなったし、ソースも見やすくなった。
>>407 >以前、何重にも込み入ったループをメンテしていたときに
>IndexOutOfBoundsException に悩まされたので
>ループを配列に固定する意味でこのようにしました。
それ自体は、悪いことじゃないですが。
同じことを意味するのに、違う書き方で書くと混乱するっていうのと
te.lengthを見たときに、「えーっと、teっていうのは・・・、あ、playerの配列か」
っていうふうに考えなきゃいけなくなるのでその辺がだめでしたね。
逆に、配列を引数でもらって処理するようなメソッドなら
playerとかを意識する必要が無い閉じた世界なのでte.lengthでよかったと思います。
>そんな私は現在失業中…orz
あー、先生とおそろいだー・・・orz
>>408 まずは、トリップを付けるんだ。話はそれからだ。
>何かしらの仕様があった時に、それを具体的にどういうクラス、
>フィールド、メソッドにしていけばいいのかがいまいちピンときません。
クラスを作る理由には2種類あって、
ひとつは、拡張した変数を作る目的。ほかの言語で言ったら構造体みたいな感じ。
たとえば、ポーカーのプログラムでは、cardというクラスを作った。
これは、mark[52]、no[52]っていう変数をそれぞれ用意するよりも、
cardという枠を作って、その中にmarkやnoを定義することにより、
cardのmarkとかcardのnoというのが分かりやすくなるため。
管理もしやすくなる。
2個目の理由は、処理を分ける。
いわゆるサブルーチンの考え方だ。
メインとそこから呼ばれるメソッドを分けて作る。
そうしているうちに、メソッドの数が増えてくる。
そうしたら、メソッドのうち、同じような機能を持つ仲間を
別のクラスにしてやる。
たとえば、日付処理や年号処理のはいったカレンダークラスとか
そういうのを作ってやる。
まずメインの一部分をメソッドにすることによって、
メインがすっきりする。また、同じような処理を行う場合再利用ができる。
デバッグや変更などもメソッドを直すだけでいい。保守性があがる。
そういったメソッドが増えてきたら、クラスを作り外だしすることによって
クラスごとに保守、再利用するようにする。
つづき とまあ、こんなかんじ。 実際は、まず、プログラムを作ってみる。 で、メインから外に出せそうな部分を探す。 ・固まった処理のブロック(シャッフル、役判定、プリント処理など) ・いろんなばしょで何度も使う処理(カードを1枚引く、カードの内容を表示など) ・後で、ほかのプログラムでも使えそうな処理(日付処理、通信処理など) こんな感じの場所を、メソッドにする。 つぎに、メソッドを用途ごとに分類し、別のクラスにする たとえば、 ・日付処理クラス ・計算クラス ・通信クラス とかね。 フィールド変数は、その用途に合わせて、クラスに配分する。 定数も同様。 メインの定数が増えた場合は、定数専用のクラスを作ってもいい。
>>410-411 えーっと、このプログラム適当に作ってうごかないでしょ?
新ルール(あたりまえのことだけど)
・ソース発表する場合には、最低でも動かしてからコピペしてください。
(その際、見やすいようにインデント直さなくても良いです。書き込むと左寄せになりますが、eclipseにコピーしたら
フォーマットでなおせるので。全角スペース入れると逆に大変。)
とりあえず、分け方も微妙なので、先生だったらこうする・・・
みたいなのを書いてみるので、作ってみてください!
>>380-383 に
>>406 の修正をしたソースを元のプログラムとします。
(ついでに、ループのte.lengthとlessもかえる)
まず、playerの勝敗を表すクラスを作ります。
名前はplayerDataにしましょう。
win[],lose[]などは、プレイヤーの勝敗を表していますが、
別々の変数なので、一元に管理することにします。
ついでに、引き分けを表すdraw変数も作りましょう。
引き分けは確かにもとまりますが、それには試合数が必要になります。
試合数が分からなくても、成績が分かるようにしたほうがいいと思います。
試合数も含めてもいいのですが、今回は全員同じ数しか試合をしないので
入れるのはやめます。
次に、メインクラスを作りましょう。
フィールド変数は使いません。
>>410 のソースはroundなどをフィールド変数にしていますが
あまりよくないです。
基本的に、フィールド変数は使わない方が良いです。
値を保持することを目的としたクラス(playerDataとかcardとか)以外では
使わないよう心がけましょう。
で、メインクラスなのですが、思い切ってmainメソッドだけのクラスにします。
(本当はそこまでやる必要ないけど、まあ練習なので)
メインメソッドの処理はこんな感じ
STEP1
コマンドライン引数からplayerとroundを取得
STEP2
playerDataを作成し、初期化
STEP3
roundの数だけ、ゲームを繰り返す。
(gameクラスのplayメソッドをround回呼び出す)
STEP4
playerDataを表示する。
(printクラスのprintDataクラスを呼び出す)
つづく
えーっと、STEP1のコマンドライン引数のとこですが、 エラー処理とかまだならってないのでこんな感じで int player = Integer.parseInt(args[0]); int round = Integer.parseInt(args[1]); シンプルに2行でやりましょう。 てことで、STEP3 とSTEP4で呼び出すメソッドを作ります。 >(gameクラスのplayメソッドをround回呼び出す) gameクラスを作ります。ここは、gameをするクラスです。 playメソッドを作ります。 引数は、playerData[]です。もどり値も、playerData[]です。 playerData = game.play(playerData); で、つぎは、 >(printクラスのprintDataクラスを呼び出す) printクラスを作ります。ここは、表示関係のクラスです。 printDataメソッドを作ります。 引数は、playerData[]です。もどり値はありません。 こんな感じでどうでしょう。 作ってみてください。
ソースが出来上がったら、どうしてこういうふうに分けたのか?
とか、その辺の解説をしたいと思います。
実際ソース見たら、わかりやすいとおもうので。
みんな作ってみよう!
>>412 たしかに、誰が作ったかきになりますね。
>>408 なのかな?
でも、時間がだいぶずれてるし・・・。
とりあえず、
>>413 のいうとおりもちつけ
sage進行、質問とかはトリップ必須でおねがいします。
>>420 >408 ですが平日昼間は仕事です(´・ω・`)と言うわけで上にあったコードは知らないです。
で、それは置いといて、今、とりあえずじゃんけんのを考えつつ作ってます。
動かすだけならダラーっと書けば動きますが、それじゃJavaを使う意味が無い(と、思う)ので、
小さい物ならいらないかもしれないけど、練習の為に要求からオブジェクト指向的に設計して、
それから実際のコードを書いていってみようか、と思った訳です。
(スパゲティ書いてからリファクタリングしようとしたら出来ませんでしたorz)
クラス、というか、それぞれのオブジェクトをどこまで細分化するか、と言うので悩んでますが、
その辺は場数なのかなぁ、とか思いつつも、とりあえず逆の発想と言う事で、
無駄と言われるまで細分化して、それから合わせられる所は合わせてみようかと。
てなわけで今やっとこ起床して、今からまたじゃんけんをやっつけてきますヽ(`Д´)ノ
先生の説明は順序立ててあるのでわかりやすかったです。
悩んでたとことは別ですが、
>>417 の draw 変数部分の説明で目から鱗がぼろぼろと。
拡張しやすくするってこういう事か!!!1!!1!11みたいな(ノ∀`)
デキター! けどすごい長い。。。どうしよう。。。。。
トリップは自分の番号とトリップでお願い。
>>421 >>408 ですが平日昼間は仕事です(´・ω・`)と言うわけで上にあったコードは知らないです。
了解しました。
>クラス、というか、それぞれのオブジェクトをどこまで細分化するか、と言うので悩んでますが、
>その辺は場数なのかなぁ、とか思いつつも、とりあえず逆の発想と言う事で、
経験は確かにありますね。同じようなプログラムを組んだことがあれば、
どういう単位で分ければ良いのか(どういう単位で分けても意味が無いのか)とか、
こういう単位にわけると、こういう改造がしやすいとか、分かるようになるので。
>>422 >デキター!
>けどすごい長い。。。どうしよう。。。。。
完成おめでとう!早速アップしてください。
長くてもまあ良いですよ。
>>423 >トリップは自分の番号とトリップでお願い
それだ、ぜひそうしてください。っていうか、そういうルールにしましょう。
名前欄は、自分の番号+トリップで
以降、よろしくおねがいします。
うわー、先生間違い発見
>>397 >&&と&の違いですが、&&は右から見ていって条件になったら以降は判定しません。
右からじゃなくって、左からです。
ごめんなさい。
訂正後:
&&と&の違いですが、&&は左から見ていって条件になったら以降は判定しません。
まとめサイト、直して置いてください・・・orz
あと、
>>422 以外でも、できた人は、ソースをあげてみよう。
っていうか、○×ゲームも・・・
番号をつけるのは素で忘れてました(・∀・)
>>425 とりあえず長さを気にせずにうpです。うpしたら早く寝なくては
public class MultiJanken {
public static void main(String args[]) {
int player = 0;
int round = 0;
if (args.length != 2) { //引数が2つじゃ無い場合
System.out.println("引数は2個");
System.exit(1);
}
try { //変な値だと困るので
player = Integer.parseInt(args[0]);
round = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
System.out.println("引数は整数でひとつ");
System.exit(1);
}
if (player < 2) {
System.out.println("第一引数は人数なので2以上");
System.exit(1);
}
if (round < 1) {
System.out.println("第二引数は回数なので1以上");
System.exit(1);
}
Judgment jud = new Judgment(player, round); //審判を呼ぶ
}
}
class Judgment { private int plList[]; //手を入れるリスト Judgment(int players, int round) { //判定役の動き plList = new int[players]; judg(players, round); //じゃんけん開始} private void playGames(int players) { //プレイヤー(*n)の手を聞く Player player = new Player(); for (int i = 0; i < players; i++) {plList[i] = player.getHand(); //リストにする} } private void judg(int players, int round) { //勝ち負けの判定 Player player = new Player(); Graph graph = new Graph(players); int draw = 0; //あいこの数をカウント for (int i = 0; i < round; i++) { //ラウンド回数ゲームをする playGames(players); boolean hand[] = new boolean[3]; //= hand{false, false, false}; for (int j = 0; j < players; j++) { //プレイヤーの手を見る int plHand = plList[j]; if (plHand == 0) { hand[0] = true;} //0(ぐー)があれば(hand[0])をtrueに。 else if (plHand == 1) {hand[1] = true;} else if (plHand == 2) {hand[2] = true;} }
int handNum = 0; for (int k = 0; k < hand.length; k++) { //trueの数を出す if (hand[k]) {handNum++;} } if (handNum == 2) { //trueが2つなら(あいこじゃないなら) for (int l = 0; l < players; l++) { //それぞれの手を調べて if (hand[0] == true && hand[1] == true) { //ぐーちょきなら if (plList[l] == 0) { //ぐー(0)の人に graph.setPoint(l); //ポイントをあげる } } else if (hand[1] == true && hand[2] == true) { //ちょきぱーなら if (plList[l] == 1) { graph.setPoint(l); } } else if (hand[2] == true && hand[0] == true) { //ぐーぱーなら if (plList[l] == 2) { graph.setPoint(l); }}} } else { //trueが2つじゃなければあいこなので draw++; } } //for(round) graph.createGraph(players, round, draw); //グラフ係にグラフを作らせる}}
class Player { Player() {} public int getHand() { //privateなオブジェクトを返す為のgetter return selectHand();} private int selectHand() { //ぐーちょきぱー(0,1,2)の中から一つ選択して返す return ((int) (Math.random() * 3)); //0,1,2を返す; } }
class Graph { private int playersPoint[]; //プレイヤーごとの成績表 Graph(int players) {playersPoint = new int[players];} public void setPoint(int playerNo) {playersPoint[playerNo]++;} private int getPoint(int playerNo) {int point = playersPoint[playerNo]; return playersPoint[playerNo];} public void createGraph(int players, int round, int draw) { //グラフ作成 System.out.println("[result]\n" + players + "人で" + round + "回のじゃんけんの結果"); if (round != draw) { System.out.println("あいこは" + draw + "回ありました"); for (int i = 0; i < players; i++) { int points = getPoint(i); // printf("%5d",i); はダメな模様…… // sprintfも無さそうなのでとりあえずそのままiで。頑張れTab //Numberformat??? System.out.print("player\t" + i + "\tavg:" + ((double) points / round) + "\tpoint" + points + " "); if (points != 0) { for (int j = 0; j < points; j++) { //ポイント分グラフを書く System.out.print("*");} } else {System.out.print("0");} System.out.println();} } else {System.out.println("全部あいこでした");}}}
終了です。 改行が気持ち悪いかもしれないですが、行数減らすのに適当に削りました。 eclipseとかでフォーマットして下さい。 やばい1時すぎてるー寝ないとー おやすみなさい(´Д`)
>>414 >逆に、配列を引数でもらって処理するようなメソッドなら
>playerとかを意識する必要が無い閉じた世界なのでte.lengthでよかったと思います。
なるほど。これからはその指針で行きます。
>>369 ○×ゲームの方をつくってみました。これでいいのかな?
public class MaruBatsu {
static final String[] koma = { "・", "○", "×" };
int[][] map = new int[3][3];
void printMap() {
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(koma[map[i][j]]);
}
System.out.println();
}
}
public static void main(String[] args) {
MaruBatsu maruBatsu = new MaruBatsu();
maruBatsu.printMap();
}
}
>>428 うーんいまいちだなあ。ちゃんと
>>417 からの説明見てつくった?
特にいまいちな点としては
・Judgmentメソッドの中でじゃんけんをround分繰り返している
じゃんけんは、1ゲームで一つの機能なので、それだけで外に出すとすっきりする。
「複数回じゃんけんをする」を実行するのではなく、「じゃんけん」を複数回実行するようにすると
すっきりすると思う。
もしくは、
メインで「複数回じゃんけんをする」を実行する→その中で、「じゃんけん」を複数回実行する
こんな感じがいいとおもう。まあ、ここまで細かくする必要は無いかな。
・Judgmentメソッドの中で点数の集計、表示を行っている
複数の機能が入っているのですっきりしない。
このへん、どうわけたらいいかは、
>>417 からを参照
全体的にすっきりしてないですね。
>>417 からを読み返してみてください。
つづく
つづき ・playerクラスのgetHandの役割 これは、かなりだめです。 通常、getX()でXの値を取得、putX(x)でXに値を設定という決まりになっているのに これにのっとっていないことが一点。 (まあ、setHandが無いというのは別に良いですが) 一番悪いのが、getHandで得られる値が毎回ランダムで変わるというところです。 この仕様のため、getHandした値を呼び出し側で保持しておかないといけません。 実際、plList[]に保持して使っています。これでは、何のためのクラスか分かりません。 あと、ちょくせつselectHand()を呼ばない理由も分からないし・・・ っていうか、playerクラスじゃなくてただのサイコロクラスになっています。 あと、配列をリストという風にコメントしていますが リストというのはjavaでは配列とは別にあるので(List,ArrayList等) int[]とかは配列と呼ぶようにしてください。 つづく
と、いうわけで、先生これからつくってみるので参考にしてみてください。 結局、自宅のパソコンにもeclipseいれました。 ちょっとまってね。
えーっとできました。設定に手間取っちゃった。 10回くらいしかテストしてないけど、多分大丈夫でしょう・・・。 package jyanKen; public class JyanKen { public static void main(String args[]) { int player = Integer.parseInt(args[0]); int round = Integer.parseInt(args[1]); PlayerData[] playerData = new PlayerData[player]; for (int i = 0; i < player; ++i) { playerData[i] = new PlayerData(); } Game game = new Game(); for (int i = 0; i < round; ++i) { playerData = game.play(playerData); } Print print = new Print(); print.printData(playerData); } }
package jyanKen; public class Game { public PlayerData[] play(PlayerData[] argPlayerData) { int player = argPlayerData.length; int[] hand = new int[player]; for (int i = 0; i < player; ++i) { hand[i] = (int) (Math.random() * 3); } boolean[] isUse = new boolean[3]; for (int i = 0; i < player; ++i) { isUse[hand[i]] = true; } int handCount = 0; for(int i = 0; i < 3; ++i) { if (isUse[i]) { handCount++; } } int winHand; if (handCount == 2) { if (!isUse[0]) { winHand = 1; } else if (!isUse[1]) { winHand = 2; } else { winHand = 0; } } else { winHand = -1; // Draw }
for (int i = 0; i < player; ++i) { if (winHand == -1) { argPlayerData[i].setDraw(argPlayerData[i].getDraw() + 1); } else { if (hand[i] == winHand) { argPlayerData[i].setWin(argPlayerData[i].getWin() + 1); } else { argPlayerData[i].setLose(argPlayerData[i].getLose() + 1); } } } return argPlayerData; } }
package jyanKen; public class PlayerData { private int win; private int lose; private int draw; public int getWin() { return win; } public void setWin(int argWin) { this.win = argWin; } public int getLose() { return lose; } public void setLose(int argLose) { this.lose = argLose; } public int getDraw() { return draw; } public void setDraw(int argDraw) { this.draw = argDraw; } }
package jyanKen; public class Print { public void printData(PlayerData[] argPlayerData) { int player = argPlayerData.length; for (int i = 0; i < player; i++) { System.out.print("Player " + i); System.out.print(":[Win = " + argPlayerData[i].getWin()); System.out.print(":Lose = " + argPlayerData[i].getLose()); System.out.print(":Draw = " + argPlayerData[i].getDraw()); System.out.println("]"); } System.out.println(); for (int i = 0; i < player; i++) { System.out.print("player " + i + ":"); for (int j = 0; j < argPlayerData[i].getWin(); j++) { System.out.print("*"); } System.out.println(); } } }
こんな感じかな。 解説はまた今度。とりあえず、実行してみてください。 jyanKenというパッケージを作って、そのなかにクラスを作ってください。 うまくいくかな?
>>435 えーっと、だいたいOKだめなところは・・・
>static final String[] koma = { "・", "○", "×" };
定数は大文字で
KOMA
>int[][] map = new int[3][3];
クラス変数(グローバル変数)は使わない方向で
printMap は staticでいいんじゃないかな?
mainと同じクラスなんだし。
あと、printMapのループの添え字はx,yの方が分かりやすいと思います。
>>445 こんな感じでしょうか?
public class MaruBatsu {
static final String[] KOMA = { "・", "○", "×" };
static void printMap(int[][] map) {
for (int x = 0; x < map.length; x++) {
for (int y = 0; y < map[x].length; y++) {
System.out.print(KOMA[map[x][y]]);
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] map = new int[3][3];
printMap(map);
}
}
えーっと、まずはじゃんけんの解説
みんな、実行してみましたか?
>>439 >int player = Integer.parseInt(args[0]);
>int round = Integer.parseInt(args[1]);
>PlayerData[] playerData = new PlayerData[player];
mainで、人数,round,各プレイヤーのスコア(playerData)を定義しています、
以降、この3個はmainで管理していくことになります。
>for (int i = 0; i < round; ++i) {
>playerData = game.play(playerData);
>}
gamePlayを、roundの回数だけ繰り返します。
>print.printData(playerData);
playerDataの中身を表示します。
mainから呼ばれるメソッドは、playerDataを処理するだけで、
player,roundに関しては意識していないことに注目してください。
つづき >public class Game { >public PlayerData[] play(PlayerData[] argPlayerData) { playメソッドです。じゃんけんのゲームをして、 スコアをカウントし返却します。 playerDataを受け取る ↓ じゃんけんをして、playerDataを更新 ↓ playerDataを返却する こんな流れになっています。
つづき >public class PlayerData { >private int win; >private int lose; >private int draw; スコアを管理するplayerDataです。 各プレイヤーのスコアを管理します。 >public class Print { >public void printData(PlayerData[] argPlayerData) { printDataです。 このメソッドは playerDataを受け取る ↓ playerDataの内容を表示 という感じです。
mainでplayerDataを管理し、各メソッドは、playerDataを受け取って、 それを処理するって言う構造になっていることに注目してください。 各メソッドは、playerDataしか意識しなくてよく round、playerは意識していません。 このように、変数の適用範囲を絞ることによって メンテナンスしやすいようにしてます。
つぎに、playerDataについてみていきます。 >public class PlayerData { >private int win; >private int lose; >private int draw; 今まで、個別に管理していた win[] lose[] draw[] をplayerDataとしてまとめています。 各playerのwin 各playerのlose 各playerのdraw というのを、 各playerの{ win lose draw } にしたわけです。 こうしたことにより、 win[],lose[],draw[] では、各変数のつながりがぱっとみただけでは分かりませんでしたが 分かるようになりました。
さて、この考え方から行くと、 もう一箇所、○○の○○同士でまとめることができる 変数があります。それはどこでしょう? また、どうすればいいでしょうか? 考えてみてください。
>>445 それでいいと思います。
ばっちりですね。
説明追加 各メソッドのわけ方ですが、 メイン ゲームをプレイする スコアの表示 というように、機能ごとに分かれているのが分かると思います。 これにより、拡張性もあがっています。 たとえば、スコア表示を画像で行いたいと思えば、 スコアの表示のメソッドだけを変えればほかのメソッドに変更はいりません。 また、ゲームの内容をかえたければ、playメソッドの内容を変えれば ほかに影響が無いです。 部品が独立しているため、拡張性があがっていると思います。
先生お疲れ様です。 添削してもらった方も、お礼くらいは書いたらどうでしょう?
やっと手が空いた……けど電話鳴ってる……メールが、メールが、あああ(´Д`)
トリップこれだったっけかな……とりあえず >421 です。
ええと
>>417 の説明、今読みました(´Д`)
>「複数回じゃんけんをする」を実行するのではなく、「じゃんけん」を複数回実行する
これがよくわかんないのですよね。一緒じゃん!とか思ってしまいます。
>selectHand()を呼ばない理由〜ただのさいころクラス
この辺はなんていうか、よくわかんないのでとにかく分けてみよう、みたいな感じです。
セッターとか言うのを使うらしいぞ。ほほう、こんな感じかね、みたいな。
何にしても417を読んでみます。時間が出来たら(´Д`)
後、自分たまにしかこれないので >>455-
>>456 の様な流れになって
荒れるとアレなんで以降ROMにします。
色々ありがとうございました。影ながら応援しております(´・ω・`)ノ
>>455-456 えーっと、とりあえず無駄にスレを消費してもしょうがないので
基本的に先生に対するお礼書きこみはいらないです。
「ここが分かりやすかった」とか
「こうおもってたけど、説明で理解したとか」
そういうの書いてもらうと参考になるので、そういう意見はお願いします。
基本的に、何も書き込み無かったら分かったものとして進めてるので
これからもその流れで。あとで分からなかったら質問してください。
あ、もちろんこのスレだけのルールで
ほかのスレではお礼しないとだめだよ。
>>457 >ええと
>>417 の説明、今読みました(´Д`)
>>「複数回じゃんけんをする」を実行するのではなく、「じゃんけん」を複数回実行する
>これがよくわかんないのですよね。一緒じゃん!とか思ってしまいます。
拡張性の問題かな?機能を分けることによって、たとえばこんなケースに対応しやすいです。
・ゲームの内容をじゃんけんから、ポーカーに変える
→ポーカーを一回だけ行うメソッドを作成して、メインでそのメソッドを呼ぶように変えればOK
じゃんけんメソッドに変更はいらない。
・(ほかのメインプログラムで)じゃんけんを一回だけ行う
→じゃんけんメソッドを単体で呼ぶだけでOK
別の言い方にすると、
「じゃんけん」というのでひとつのゲームですよね?
たとえば、じゃんけんの三回勝負というのは、
「じゃんけんの三回勝負」というゲームをするのではなく、
「じゃんけん」というゲームを「三回勝負」で行うということになります。
なんで、ゲームである「じゃんけん」でひとつのメソッド
勝負方法である「三回勝負」でひとつのメソッドにします。
そうすることによって、すっきりしますし、ちょっとかえるだけで
「ポーカー」の「三回勝負」とか、
「じゃんけん」の「一回勝負」とかを作ることができます。
わかったかな?
>荒れるとアレなんで以降ROMにします。 >色々ありがとうございました。影ながら応援しております(´・ω・`)ノ 別にROMらなくても、また質問があったら書き込んでください。 先生も参考になるので。
あのーまた全然関係ない話ですが、J2SE付属のJREと IBMのJREは何か違うんでしょうか?
>>461 javaにバグがあるみたいで、eclipseとうまく連動しないようです・・・。
細かいことはよく分からないけど、eclipseインストールするときに
そんな記事を見つけたのでIBMのを使うようにこのスレではしてます。
eclipseのwikiに書いてあったと思うので、興味あったら調べてみてください。
(ついでに結果をおしえてくれるとうれしいw)
※注意※2005/01現在のSunJREにはバグがあり、 一部プラグインの読み込み*3や日本語化*4の際に不都合が生じます。 IBMJREを使用するかXMLパーサをXercesなどサードパーティのものに 入れ替えて下さい。 *3 例えばhyades同梱のlog4jプラグインに含まれるplugin.xmlがある条件で読み込めない。 *4 例えばJava開発環境オンラインマニュアルの「タスク」セクションが目次から消える。 と、言うことです。Java本国では英語なんで何ら問題はないような気がしますが やっぱ、日本語とか2バイトを扱うとこういうバグって多くなりますよね。
>>463 早速調べてくれたみたいでありがとうでした。
最近生徒が風邪引いて授業してない罠
465 :
デフォルトの名無しさん :2005/06/13(月) 11:08:17
sage忘れたorz
こんばんは。 最近メモリのことが気になってしょうがないんですが質問させてくださう。 例えばUserクラスと言うのでユーザー情報を保持してるとき、 User user = new User(unko,hogehoge);とかで新たに作りますよね。 (コンストラクタはIDとPASSだとします。) これでユーザー情報を元にいろいろ弄ってこのuserオブジェクトが いらなくなったとき、多分userオブジェクトはメモリ上にロードされてる と思ってるんですが、これを消す場合はどうすればいいんですか? ガーベッジが来るまで待つのですが?
>>468 即レスありです。
んー微妙に分からない。
userオブジェクトを明示的にゴミとさせて、Systemのgcを呼びたい・・・
それとも、明示的にuserオブジェクトをゴミとさせなくても、
勝手にgcがゴミと判断して消してくれるのかな
>>469 > userオブジェクトを明示的にゴミとさせて
user = null;
とすればGCの対象になるんじゃなかったかなぁ。
>>470 なるほど。dクスです。
最近思うんだけど、Javaで俺プログラム組んでるつもりなんだけど、
実際組んでないのと同じなんだよね
は?って思うかもしれないんだけど、俺はJavaが初言語なんだけど、
プログラムを組んでるようで組んでない。
つまり、俺は常にライブラリを使って組んだように見せかけてるだけで、
ライブラリから帰ってくる値をいじるだけしかしてない。
俺にとってこれはプログラムを組んでいるとは言えないと思う。
ライブラリはライブラリの中身を知ってる人が使うべきで
ライブラリの中身を全く知らない人間は使っても何ら成長もしてない。
と思ってる。
じゃあ何かクラス作れよって言われてもライブラリ使わなきゃ何も
できない俺がいる。
どうすればいいかな
>>471 > じゃあ何かクラス作れよって言われてもライブラリ使わなきゃ何も
> できない俺がいる。
Javaはあらゆるクラスがコアパッケージに含まれてるjava.lang.Objectを継承しているんだから
Javaで「ライブラリを使わずに」プログラムを組むことはできないんだけど。
多分、貴方には私の言いたいことが伝わってないんだと思う。
じゃあ、あなたにとって「Javaでプログラム組んでる人」はどんな人?
475 :
デフォルトの名無しさん :2005/06/25(土) 21:12:57
static void EOXception ・ ・ ・ すべての意味と使い方を理解していて、 すべて手入力で自力でプログラム組める人ってことでは?
インデント付けろや。 変換するプログラムくらい手元にあるっしょ?
ライブラリのソースを見なくてもライブラリが何をしているかと言うことを プログラマ自身知らなくても、ちょっとドキュメント覗いて、 それに書いてあるメゾッドを呼んで戻り値もらえば、済んでしまう。 これは、便利かも知れないけど、初めて言語触る人間にとっては 何ら勉強になってないかなって思う。そのライブラリの中身が 何となく分かってソースも書けそうな人ならライブラリを使用するのは 楽で便利であると言える。 私自身、java.lang.Objectのequals等がどういったことをしているとか分からない。 私にとって「Javaでプログラム組んでいる人」と言うのは大抵は、 なんちゃってプログラマであると思う。 「Javaでプログラムが組める人」と言うのは、自分がやりたい事柄を 実現するとき、ライブラリが無かったら、生々しくコードを書ける人かなって思ってます。 475さんの言うような感じです
>>477 の発言はオブジェクト指向の醍醐味だと思うんだけどなあ。
>>467 メモリの開放ですが、GCに任せます。自動的に開放されるのを待つわけです。
>>468 のいうとおり、自分でも呼べますが、そこまでする必要は無いでしょう。
なので、特に何も考えなくて良い・・・はずなのですが、
自動的に開放されない場合があるので、nullを指定して、明示的にGCの対象になるようにします。
終了処理のメソッドに、クラス変数をnullで初期化する処理を入れると良いでしょう。
>最近思うんだけど、Javaで俺プログラム組んでるつもりなんだけど、
>実際組んでないのと同じなんだよね
そうかなあ、そうじゃないと思うけどなあ。
javaはたまたま、ライブラリの中身が見れる状態にあるから
ライブラリ=誰かの作ったプログラム なので、自分は楽している
って考えちゃうのかもしれないけど。ほかの言語だってにたようなもんだよ。
javaのライブラリの変わりに、命令があるわけだけど、その命令の中で実際にどんな動作しているかなんて
普通は考えないよ。(まあ、わかるにこしたことは無いんだけど)
それに、ライブラリの中身なんていうのは、大して重要じゃない。
たとえば、rundomだったら、どういうアルゴリズムで乱数が生成されるかなんて
しらなくてもいい。問題は、その命令を必要に応じてうまく使いこなせるかだよ。
料理だったら、命令やライブラリはいわゆる調味料のようなもの。
でも、醤油がどうやってつくられるかとか、この香辛料はなんていう木の実でどうやって
加工するかとか、そんなの料理人はわからないでしょ?
大事なのは、その調味料がどんな味でどんなときに、どのくらい使えばいいのかを知っていること
そして、おいしい料理を作れることだと思う。
なんか、よくわからんけど、先生の意見はこんな感じ。 授業再開し始めたので、今週中には○×ゲームの回答を・・・ だせたらいいなあ。
>>479 プログラミングってそんなもんなんですか。
ただ、料理に例えてますけど、料理人なら
原料、ある程度の調味料の作成工程は知ってるものじゃないでしょうか。
それに、自分の欲しい調味料がないときは自作するのではないですか?
それはただの変人なんですかね。
それに私でも料理はできます。でも料理人ではないんです。
それでもおいしい料理はできます。
あーわかんなくなった。もうだめかもしれんね。
ちょっと消えます。
フルスクラッチでライブラリを書けない奴は勉強不足だが、 フルスクラッチでライブラリを書く奴は単なる馬鹿だ。
>>481 調味料の中身を知っていれば、知らないよりは良いし
何かの役に立つかもしれないけれど、
知らなくても使えるし、料理は作れるよね?
料理人の目的は、あくまでもおいしい料理を作ることだってことを
忘れてるんじゃないかな?
プログラムにしても、たとえばライブラリだと大きく分けて
数値演算系とハードウェア系とその他の便利な命令に分かれると思うんだけど、
たとえば数値計算で、乱数にしても、乱数を使う人が
均等でスピードの速い乱数の求め方とかを知ってる必要は無いんだよね。
ていうか、そういうアルゴリズムっていうのは何年もかけていろんな人が
研究して作った結果だしね。
ハードウェア系にしても、たとえば画面に点を書くにはハードウェアのVRAM領域の
ここにアクセスして・・・なんてことを知ってる必要は無いよね?
っていうか、そんな膨大なハードウェアの資料を調べたりそれを元に
各個人がそんな命令を作るのは不可能だし非常に生産性が悪い。
それよりも、もっと根本的なこと・・・それらを利用して目的のプログラムを作ることに
重点を置くといいと思います。
ただ、ライブラリの中身に興味を持つのはいいことだと思う。
とくに、javaの場合ライブラリが充実しているので、ほかの言語で似たような処理を行う
場合とか、参考になるかもしれないし。
もしかして、自分でもっと凄いアルゴリズムを発見して、それがライブラリに反映されるかも
しれないですしね!
まあ、ライブラリについては、「便利な世の中になってよかったなあ」程度の認識でよいのでは
ないでしょうか。先生はそう思いながらつかってます。
どうでもいいよ。
えーっと○×です。MaruBatuという名前のパッケージを作ってください。 まずは、点数を管理するクラスです。 package MaruBatu; public class Score { private int win; private int lose; private int drow; public int getWin() { return win; } public int getLose() { return lose; } public int getDrow() { return drow; } public void setWin(int argWin) { win = argWin; } public void setLose(int argLose) { lose = argLose; } public void setDrow(int argDrow) { drow = argDrow; } }
次が、座標を管理するメソッドです。 isUseには、その座標が有効かどうか(使用するかどうか)がはいります。 package MaruBatu; public class Zahyou { private int x; private int y; private boolean isUse; public int getX() { return x; } public int getY() { return y; } public boolean isUse() { return isUse; } public void setX(int argX) { x = argX; } public void setY(int argY) { y = argY; } public void setIsUse(boolean argIsUse) { isUse = argIsUse; } }
ここから先が、メインです。まずは、最初の部分 package MaruBatu; public class MaruBatu { public static final int ROUND = 10; public static String[] hako = { "・", "○", "×" };
メイン関数 public static void main(String[] args) { Score[] score = new Score[2]; for (int i = 0; i < 2; ++i) { score[i] = new Score(); } for (int i = 0; i < ROUND; ++i) { int winPlayer = playGame(); if (winPlayer == 1) { score[0].setWin(score[0].getWin() + 1); score[1].setLose(score[1].getLose() + 1); } else if (winPlayer == 2) { score[0].setLose(score[0].getLose() + 1); score[1].setWin(score[1].getWin() + 1); } else { score[0].setDrow(score[0].getDrow() + 1); score[1].setDrow(score[1].getDrow() + 1); } } System.out.println(); System.out.println("Player 1:" + score[0].getWin()); System.out.println("Player 2:" + score[1].getWin()); System.out.println("DrawGame:" + score[0].getDrow()); }
private static int playGame() { int winPlayer = 0; int[][] map = new int[3][3]; int player = 1; int teki = 2; while (winPlayer == 0) { map = putMap(map, player, teki); printMap(map); winPlayer = checkWin(map); if (player == 1) { player = 2; teki = 1; } else { player = 1; teki = 2; } } if (winPlayer == 3) { System.out.println("引き分け"); } else { System.out.println("PLAYER " + winPlayer + " の勝ち"); } return winPlayer; }
private static int[][] putMap(int[][] argMap, int argPlayer, int argTeki) { if (argPlayer == 1) { cpu2(argMap, argTeki, argPlayer); } else { cpu2(argMap, argTeki, argPlayer); } return argMap; }
private static int [][] cpu1(int [][] argMap, int argPlayer) { boolean isPut = false; while (!isPut) { int x = (int) (Math.random() * 3); int y = (int) (Math.random() * 3); if (argMap[x][y] == 0) { isPut = true; argMap[x][y] = argPlayer; } } return argMap; }
private static int [][] cpu2(int [][] argMap, int argTeki, int argPlayer) { boolean isPut = false; Zahyou zahyou; zahyou = checkReach(argMap, argPlayer); if (zahyou.isUse()) { argMap[zahyou.getX()][zahyou.getY()] = argPlayer; isPut = true; } if (isPut == false) { zahyou = checkReach(argMap, argTeki); if (zahyou.isUse()) { argMap[zahyou.getX()][zahyou.getY()] = argPlayer; isPut = true; } } if (isPut == false ) { if (argMap[1][1] == 0) { argMap[1][1] = argPlayer; isPut = true; } else { while (!isPut) { int x = (int) (Math.random() * 3); int y = (int) (Math.random() * 3); if (argMap[x][y] == 0) { argMap[x][y] = argPlayer; isPut = true; } } } } return argMap; }
private static int checkWin(int[][] argMap) { int winPlayer = 0; for (int i = 1; i < 3; ++i) { if ((argMap[0][0] == i && argMap[0][1] == i && argMap[0][2] == i) || (argMap[1][0] == i && argMap[1][1] == i && argMap[1][2] == i) || (argMap[2][0] == i && argMap[2][1] == i && argMap[2][2] == i) || (argMap[0][0] == i && argMap[1][0] == i && argMap[2][0] == i) || (argMap[0][1] == i && argMap[1][1] == i && argMap[2][1] == i) || (argMap[0][2] == i && argMap[1][2] == i && argMap[2][2] == i) || (argMap[0][0] == i && argMap[1][1] == i && argMap[2][2] == i) || (argMap[2][0] == i && argMap[1][1] == i && argMap[0][2] == i) ) { winPlayer = i; } } if (winPlayer == 0) { if (argMap[0][0] != 0 && argMap[0][1] != 0 && argMap[0][2] != 0 && argMap[1][0] != 0 && argMap[1][1] != 0 && argMap[1][2] != 0 && argMap[2][0] != 0 && argMap[2][1] != 0 && argMap[2][2] != 0 ) { winPlayer = 3; } } return winPlayer; }
リーチ状態を調べるメソッドです。長いので2分割 private static Zahyou checkReach(int[][] argMap, int argPlayer) { Zahyou zahyou = new Zahyou(); zahyou.setIsUse(false); if ((((argMap[0][1] == argPlayer && argMap[0][2] == argPlayer) || (argMap[1][0] == argPlayer && argMap[2][0] == argPlayer) || (argMap[1][1] == argPlayer && argMap[2][2] == argPlayer)) && argMap[0][0] == 0)) { zahyou.setX(0); zahyou.setY(0); zahyou.setIsUse(true); } else if ((((argMap[0][0] == argPlayer && argMap[0][2] == argPlayer) || (argMap[1][1] == argPlayer && argMap[2][1] == argPlayer)) && argMap[0][1] == 0)){ zahyou.setX(0); zahyou.setY(1); zahyou.setIsUse(true); } else if ((((argMap[0][0] == argPlayer && argMap[0][1] == argPlayer) || (argMap[2][0] == argPlayer && argMap[1][1] == argPlayer) || (argMap[1][2] == argPlayer && argMap[2][2] == argPlayer)) && argMap[0][2] == 0)) { zahyou.setX(0); zahyou.setY(2); zahyou.setIsUse(true); } else if ((((argMap[0][0] == argPlayer && argMap[2][0] == argPlayer) || (argMap[1][1] == argPlayer && argMap[1][2] == argPlayer)) && argMap[1][0] == 0)){ zahyou.setX(1); zahyou.setY(0); zahyou.setIsUse(true);
} else if ((((argMap[0][2] == argPlayer && argMap[2][2] == argPlayer) || (argMap[1][0] == argPlayer && argMap[1][1] == argPlayer)) && argMap[1][2] == 0)){ zahyou.setX(1); zahyou.setY(2); zahyou.setIsUse(true); } else if ((((argMap[0][0] == argPlayer && argMap[1][0] == argPlayer) || (argMap[0][2] == argPlayer && argMap[1][1] == argPlayer) || (argMap[2][1] == argPlayer && argMap[2][2] == argPlayer)) && argMap[2][0] == 0)){ zahyou.setX(2); zahyou.setY(0); zahyou.setIsUse(true); } else if ((((argMap[0][1] == argPlayer && argMap[1][1] == argPlayer) || (argMap[2][0] == argPlayer && argMap[2][2] == argPlayer)) && argMap[2][1] == 0)){ zahyou.setX(2); zahyou.setY(1); zahyou.setIsUse(true); } else if ((((argMap[0][0] == argPlayer && argMap[1][1] == argPlayer) || (argMap[2][0] == argPlayer && argMap[2][1] == argPlayer) || (argMap[0][2] == argPlayer && argMap[1][2] == argPlayer)) && argMap[2][2] == 0)){ zahyou.setX(2); zahyou.setY(2); zahyou.setIsUse(true); } return zahyou; }
最後は盤の表示 private static void printMap(int[][] argMap) { for (int i = 0;i < 3; ++i) { for (int j = 0;j < 3; ++j) { System.out.print(hako[argMap[i][j]]); } System.out.println(); } System.out.println(); } }
簡単に解説すると、思考ルーチンが2個あって(cpu1とcpu2) そいつらで戦わせてます。 cpu1は適当に置くだけ cpu2は、あがれたらそこにおく、リーチがあったらとめる、 真ん中が開いてたらおく、てきとうにおくというのを最初に書いたほうから 順番にやっていきます。 分からないことがあったらきいてください。
新しいことを覚えます、まずはswitchです。 switch(式) { case 条件1: 命令1; break; case 条件2: 命令2 case 条件3 命令3 default: 命令4 } 式の値が条件1なら、命令1を実行します。 条件2なら、命令2を・・・という感じです。それ以外ならdefaultを実行します 命令の実行はbreakが書かれるまで続きます。 なので、上記の例だと式の値が条件2の場合は、 命令2、命令3と実行した後にbreakでおわります。 defaultが無い場合は、条件に一致するのが無かったらなにもしません。
例: switch (x) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); case 3: System.out.println("3"); break; default: System.out.println("def"); break; } System.out.println("END");
次は、コンストラクタです。 クラスと同じ名前のメソッドをつくることが出来ます、 クラスが作成されるときに、よばれます。 例: public class Score { public String name; public Score() { name = "NO NAME"; } } 上記の場合 Score score = new Score(); と、メインクラスで呼んだときに、Score()が実行されます。
引数を使うことも出来ます。 public class Score { public String name; public Score(String argName) { name = argName; } } 上記の場合 Score score = new Score("なまえ"); と、メインクラスで呼ぶことになります。
次は、オーバーロードです。 同じ名前で、違う引数のメソッドを作ることが出来ます。 ただそれだけ。 例: public int add (int arg1, int arg2) { return arg1 + arg2; } public int add (int arg1, int arg2,int arg3) { return arg1 + arg2 + arg3; }
ちなみに、コンストラクタも、オーバーロードすることが出来ます。
それでは、新しいことを覚えます。今までうやむやにしていた参照です。 まずは、次を実行してみてください。どうなりますか? public class Main { public static void main(String[] args) { int x = 0; test(x); System.out.println(x); } public static void test(int argX) { argX = argX + 1; System.out.println(argX); } }
1 0 となったとおもいます。 では、つぎはどうでしょう? public class Main { public static void main(String[] args) { int[] x = new int[1]; x[0] = 0; test(x[0]); System.out.println(x[0]); } public static void test(int argX) { argX = argX + 1; System.out.println(argX); } }
それでは、本題、次を実行するとどうなるでしょう? public class Main { public static void main(String[] args) { int[] x = new int[1]; x[0] = 0; test(x); System.out.println(x[0]); } public static void test(int[] argX) { argX[0] = argX[0] + 1; System.out.println(argX[0]); } }
1 1 となったとおもいます。これはどうしてでしょうか?
と、いうわけで解説です。 int型は基本型、配列は、参照型なので、違いが出てくるのでした。 それでは、参照型とはなんでしょうか? その前に、基本型とは何かを説明します。
■基本型 intなどのプリミティブ型は、基本型になります。 宣言したときに、メモリ上に値を保持する場所を確保し、 値を直接保持します。 例(左の数字は行番号) 01 int x; 02 int y; 03 x=10; 04 y = x; 05 x = 5; 01 int xとやった時点で、メモリにxの場所が作られる メモリの001番地(xの場所):0 02 同様に、int yとやった時点で、メモリにyの場所が作られる メモリの001番地(xの場所):0 メモリの002番地(yの場所):0 03 xに10を代入すると、メモリにその値がかかれる メモリの001番地(xの場所):10 メモリの002番地(yの場所):0 04 yにxを代入すると、メモリにその値がかかれる メモリの001番地(xの場所):10 メモリの002番地(yの場所):10 05 xに5を代入すると、メモリにその値がかかれる メモリの001番地(xの場所):5 メモリの002番地(yの場所):10 ※yの値は変わらない
■参照型 objectや、配列は参照型になります。変数には、メモリのどこに実際の値が入っているかのメモがはいります。 実際の値は、newした時点で、メモリに場所が作られてそこにはいります。 代入した場合は参照の代入となり、メモリのどの場所かを示すメモがわたされます。 例 01 Score sc; 02 sc = new Score(); 03 sc.setWin(1); 04 Score sc2; 05 sc2 = sc; 01 scがメモリに作られる、メモの中身はnull メモリの001番地(scの場所):null 02 newされたので、メモリにScore()が新しく作られたあと、 scに、そのメモリ上の場所がメモされる メモリの001番地(scの場所):002番地 メモリの002番地(02で作られたScore()) 03 scのメモを見て、メモリ002番地につくられたScore()の中のsetWin()を実行する 04 sc2がメモリに作られる、メモの中身はnull メモリの001番地(scの場所):002番地 メモリの002番地(02で作られたScore()) メモリの003番地(sc2の場所):null 05 scのメモの内容がsc2に代入される メモリの001番地(scの場所):002番地 メモリの002番地(02で作られたScore()) メモリの003番地(sc2の場所):002番地 ※この状態で、sc.setWin(1); と sc2.setWin(1); は、同じ意味になる
配列の場合も、同じ感じで 10 int[] x; 20 x = new int[2]; 30 x[0] = 1; 40 int[] y; 50 y = x;
10 xがメモリに作られる メモリの001番地(x):null 20 newされたので、メモリにint[2]の場所が作られる xに、int[2]のメモリ上の場所のメモがかかれる メモリの001番地(x):002番地 メモリの002番地([0]):0 メモリの003番地([1]):0 30 xにメモってある002番地の[0]に、1が代入される メモリの001番地(x):002番地 メモリの002番地([0]):1 メモリの003番地([1]):0 40 yがメモリに作られる メモリの001番地(x):002番地 メモリの002番地([0]):1 メモリの003番地([1]):0 メモリの004番地(y):null 50 メモの内容が代入される メモリの001番地(x):002番地 メモリの002番地([0]):1 メモリの003番地([1]):0 メモリの004番地(y):002番地 ※この状態で、 x[0] = x[0] + 1; と y[0] = y[0] + 1; は、同じ意味
と、こんな感じになります。 参照は注意しないと、大変なことになります。 たとえば、引数の5倍をもどす関数を作る場合は public int gobai(int argX) { argx = argx * 5; return argX; } これでOKですが、 引数の配列の先頭の数字の5倍を戻す関数を 同じ感覚で作ってしまうと public int gobai(int[] argX) { argx[0] = argx[0] * 5; return argX[0]; } 引数に与えた配列の中身が変わってしまい、 大変なことになります。 (上記はあくまで例です、普通なら return argX[0] * 5; という関数を作れば良いので、何も問題ないです。)
引数と参照の関係ですが、 基本的には、「引数の値は変更されない」というのが、きれいな形です。 この辺のプログラムを作成するときの指針は難しいのですが、 実際それをするには、いちいち引数をコピーして退避したりなど 面倒なことも多いのも事実です。 このへんは、プログラムの作成時に決めておくといいと思います。 参照という概念をあたまにおいて、もう一度今まで作った プログラムを見てみると、結構適当だと思います。 (引数が変更されているのも多いですよね。) この辺を、どういうふうにすればきれいになるかを 考えてみてください。
いやぁ、久しぶりにここに来ました。トリップ上手く付いてるかな?
さっそくですが先生、
>>509-510 の解説はマズいですよ。
プログラミング言語の引数は「引数渡し」か「参照渡し」だけだと思うのですが。
要は、引数の実体が渡されるのか、引数がコピーされたものが渡されるのか、という…。
で、Java には「参照渡し」しか存在しない訳で。必ず引数はコピーされたものが渡る、って説明が良いのでは?
でないと、C で「構造体を引数にした時には、構造体がそのままコピーされたものが渡される」という事が説明できない…。
構造体は基本型じゃないし。
うーん、Java に限って話をすれば構わないのかもしれないけど…。Java はオブジェクトは全て参照で扱うし、難しいのかも知れませんが…。
JAVAはファイル名=クラス名なんでしょ? ひとつのファイルにたくさんのクラスがあるときは その中のどのクラスをファイル名にするんですか?
>516 [.java]ファイルのpublicなクラス名がファイル名です。 だから1つの[.java]ファイルにはpublicなクラスが1つしか作れず、それがファイル名になります。 コンパイル後の[.class]ファイルは作成したクラスだけ作られます。
>>517 すまん、微妙に違う。
Java では、1ソースファイルにいくつでも (これはものの謂い。言語仕様的上限はある) クラス定義が書ける。
コンパイルすると、定義したクラスの数だけクラスファイルができる。
ただし、public なクラスは 1ソースファイルに 1つだけしか定義できない。
そして、public なクラスを定義する場合は、public なクラスの名前とソースファイル名が一致しなければならない。
というのが正しい。
だから public でないクラス定義のみのソースファイルもコンパイル OK。
何故こんな言語仕様になっているのかについては、パッケージの概念について勉強されたし。
>>515 おひさしぶりです。
えーっと、ちょっとせつめいが足りなかったかな?いってることは同じだと思う。
基本型の場合、変数には実際の値が入る。
参照型の場合、変数にはメモ(アドレス、メモリ上の場所)が入る。
それをふまえて、
javaの代入
a = b
は、bの内容をaにコピーするということなので
基本形の場合、実際の値が入っているので
実際の値がコピーされる
参照系の場合、メモがはいっているので、
メモがコピーされる
ということです。代入自体は、「コピーされたものが渡る」という考え方なのですが、
変数の種類によって「実際の値」がコピーされるのか、メモがコピーされるのかの
違いが有り、メモがコピーされた場合、本体が増えるわけではないので、
注意してね・・・って言うことがいいたかったのですが・・・
どうでしょう。
>>516-518 このへんは
>>233-234 に書いてあるので参考にしてください。
最初は、1ファイルにpublicなクラスを1個書くというふうに、
おぼえてしまって差し支えないと思います。
お久しぶりです。 みんな、夏休みだしプログラム作ってる? 先生は、今日から旅に出ます。しばらく質問とか答えられないかもなので ゆるしてくれ!ちなみに、四国をお遍路さんでまわってくるお。 そいではー。
522 :
デフォルトの名無しさん :2005/08/25(木) 11:43:41
あげとこ
523 :
デフォルトの名無しさん :2005/09/13(火) 22:12:09
保守
524 :
デフォルトの名無しさん :2005/09/16(金) 03:22:30
age
んじゃオラ今日からはじめる打
526 :
デフォルトの名無しさん :2005/09/23(金) 23:38:01
コマンドライン引数 応用問題1 コマンドラインから数字と演算子を入力し計算結果を出力するプログラム を作成せよ (+とーのみにする)ただし、引数が不足している場合はエラーメッセージ を出力して処理を終了させる 実行例 java cale 10+2 これのソースわかる人いる?
528 :
デフォルトの名無しさん :2005/09/24(土) 16:29:54
>>526 ほれ、こんな感じか?
public class Sample1 {
static int calc = 0; static int curVal = 0; static int curOps = 0; // 0..nop 1..plus 2.. minus
public static void main(String[] args) {
if (args.length != 1) { System.err.println("Argument missmatch"); System.exit(1); }
boolean lastIsNumber = false;
for(int p=0; p< args[0].length(); p++) {
char ch = args[0].charAt(p);
if((ch >= '0') && (ch <= '9')) { if (!lastIsNumber) curVal = 0; curVal *= 10; curVal += (int)(ch - '0'); lastIsNumber = true; }
else if (ch == '+') { calcOps(); curOps = 1; lastIsNumber = false; }
else if (ch == '-') { calcOps(); curOps = 2; lastIsNumber = false; }
else { lastIsNumber = false; }
}
calcOps(); System.out.println(calc); System.exit(0);
}
private static void calcOps() {
if (curOps == 1) calc += curVal; else if (curOps == 2) calc -= curVal; else calc = curVal; curVal = 0;
}
}
cale だが?
530 :
528 :2005/09/24(土) 18:15:12
>>529 おおすまん、そこを見逃してた。Sample1をcaleに変えてくれ
eclipse上でソース入力して動かして結果でたからこれで完成と思ってたよ
久しぶりに入力してそのままエラー無しで動いたプログラムだったからちょっと興奮してた
531 :
デフォルトの名無しさん :2005/09/24(土) 23:40:41
一桁の乱数を作るにはどうしたらいいのでしょうか?
>531 Math.random()が0以上1未満の乱数を作るんだから、 ちょっと考えればわかるはず・・・
>わかるはず・・・ 10倍して小数点以下を切り捨てれば0〜9、ってなかなか思いつかないと思うけどな
>533 やっぱそうかな・・・ 書き込んだ後よく考えたら初心者にはわからないかもとちょっと思ったんだ。 >531ごめんよ(´・ω・`)
>>534 初心者というより数学的な勘って奴じゃないかと思う
先生質問です!! 何かの機能を実装するとき、staticにするか否かは どういう基準で判断すればいい? そのときの気分?
537 :
◆WtRerEDlHI :2005/09/29(木) 17:46:48
538 :
デフォルトの名無しさん :2005/09/29(木) 18:04:51
あと528のサンプルなんだけど、もうちょっとわかりやすくなると思う 具体的には calcOpsに引数と戻り値をついかすれば、static変数がいらなくなるし、すっきりする curValを初期化する場所が二カ所にあるcalcOpsにはいらないのでは? こんな感じでなおしてみたらどうでしょう
>537 お疲れさん。ブログ、さっと見た。 うまそうなもんばっか食ってんじゃないよw 羨ましいぞ畜生め。
540 :
デフォルトの名無しさん :2005/09/29(木) 18:29:07
>>528 static使ったのはわざとだったりするw
クラス化すんのめんどくさかった
curValを初期化するのが2回あるのはこのプログラムだと余計だね
calcOpsはリファクタリングして抜き出したけど、最初は一気に作ってて初期化されないと嫌だっただけ
すまん、初心者じゃない人間が作ってしまったw
541 :
デフォルトの名無しさん :2005/10/04(火) 23:04:52
なんとなく上げてみる
このスレ終わっちゃってるのかな 勉強したかったぜ
>>538 はこんな感じかな
public class TestMain {
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Argument missmatch");
System.exit(1);
}
int calc = 0;
int curOps = 0; // 0..nop 1..plus 2.. minus
int curVal = 0;
boolean lastIsNumber = false;
for (int p = 0; p < args[0].length(); p++) {
char ch = args[0].charAt(p);
if ((ch >= '0') && (ch <= '9')) {
if (!lastIsNumber) {
curVal = 0;
}
curVal *= 10;
curVal += (int) (ch - '0');
lastIsNumber = true;
} else if (ch == '+') { calc = calcOps(calc, curOps, curVal); curOps = 1; lastIsNumber = false; } else if (ch == '-') { calc = calcOps(calc, curOps, curVal); curOps = 2; lastIsNumber = false; } else { lastIsNumber = false; } } calc = calcOps(calc, curOps, curVal); System.out.println(calc); System.exit(0); } private static int calcOps(int argCalc, int argCurOps, int argCurVal) { if (argCurOps == 1) { argCalc += argCurVal; } else if (argCurOps == 2) { argCalc -= argCurVal; } else { argCalc = argCurVal; } return argCalc; } }
あー、クラス名なおしてなかった まあ、こんな感じにすれば、すっきりすると思う calcOpsが独立した関数として機能してるしね
547 :
デフォルトの名無しさん :2005/10/18(火) 10:31:49
i⌒ヽ i⌒ヽ (⌒ヽ _,,,ヽ `──、 _,,,ヽ `──、 \ \___ (______ 、一' (______ 、一' > ___) ___) | ___ ___) | / / ( ____ノ (___ ̄ヽ ( ____ノ | ( ヽ \__ __) | ヽ \__ ヽ ヽ____ \___) (___ノ \___) \____) ___ _| ̄|_ __ |__ | | ̄| |_ _| __| ̄|_|__| _ __| | | | |_ _| | __ _| | | | __| | | | |_ | | | |. | | |__ | | | | ._|. | ||_ \_. | | | | | | | ̄| |_ |/ \_|. | | _ __/ /. | | ノ \_____. | ヽ__ノ ノ |__/ |_| ヽ_ノ ̄ ̄\____| \_____/
なかなかために成った。
でももう
>>1 はこない悪寒がする。
549 :
851 :2005/11/04(金) 15:32:50
>>1 さま
おかげで,Java本1冊終えられました。
ありがとうございました.
551 :
デフォルトの名無しさん :2005/11/06(日) 14:45:56
もう家庭教師は首に成ったのか?
なんとなく読んだけど、自分が今まで学んできたことの復習になったよ ありがとう先生
>550 スレッド立てときながら いつのまにか傍観者の立場になってるし。。
554 :
デフォルトの名無しさん :2005/11/29(火) 12:24:13
あーごめんなさい 家庭教師はおわりました 旅から帰ってきました 働きました デスマーチ←いまここ スレはまあ、あれだ勉強したいひとのために残しておくので質問とかあったらどうぞー
555 :
デフォルトの名無しさん :2005/11/29(火) 19:14:56
デスマってJavaなデスマ?
vb.netなデスまでした ↓ とりあえず、契約切れたからおしまい ↓ 面接を受ける ↓ 一時面接合格 ↓ 来週二次面接←いまここ ていうか、あれだ、java勉強の話をしてくれよw
557 :
デフォルトの名無しさん :2006/01/08(日) 21:08:08
あげてみる。
100ぐらいまで読んだがためになるスレだな。
>>1 さん
自分は携帯向けjavaやりたいんですが、また講義できますか?
558 :
デフォルトの名無しさん :2006/01/10(火) 05:21:56
今日から東京! あたらしいプロジェクトです 質問かいてくれれば分かる範囲でこたえますよー
おらは今ポーカー作っとります。
561 :
デフォルトの名無しさん :2006/01/18(水) 08:34:15
お、みんな頑張ってるなあ 携帯からだからトリップなし 質問あったらお気軽にどうぞー
毎回新しいカードセットからカードを配るんじゃなくて、山や捨て場というようなものを使いたい場合、 こういったものはどうやって書けば良いんでしょうか。 ポーカーでも、他のゲームでも使えるようにしたいんですが。 山や捨て場は、例えばカードを操作するクラスみたいなのを作って、そこで保持させるよりも、 Pokerクラスが保持した方が良いですか? シャッフルするだとか、手札にカードを配るだとか、いろんなゲームで使う機能なので、 カードを操作するクラスみたいなのを作ろうかと思ったんだけど、 そこでカードを保持するのもどうなのかと思って。 あと、ランダムな要素を使うときにMathクラスのrandom()メソッドを使うのは分かるんですが、 java.util.RandomクラスのnextIntメソッドを使うと、整列したカードをシャッフルした後に 毎回同じような並びになってる気がしたんですが、このクラスのランダムってそういうものなのでしょうか。
トリップこれでいいかな?先生です。 >山や捨て場というようなものを使いたい場合、 いままでのサンプルで言ったら、山=デッキです。 いままでは、ゲーム開始時にシャッフルしていたのを、シャッフルしないようにすれば いいと思います。その場合、カードがなくなった場合の処理を入れる必要があるでしょう。 (ゲーム開始時に、カードが10枚以下なら新しいデッキでやるとか、枚数が0になったら新しいデッキにするとか) 捨て場は、捨て場を作ってカードを入れていけばいいと思います。 難しくはないと思う。 >山や捨て場は、例えばカードを操作するクラスみたいなのを作って、そこで保持させるよりも、 >Pokerクラスが保持した方が良いですか? デッキや捨て場は、独立しているのでそれぞれクラスを作って、 それをPOKERの中で使うといいかと思います。 俺だったら ゲームクラス(プレイヤー制御、勝敗管理とか) ポーカークラス(約の判定とか) デッキクラス(シャッフルとか、一枚引くとか) 捨て場クラス(何枚捨てられているか、最後に捨てられたのはなにかとか) カードクラス(マーク、数字) こんな感じかな。完成したら、ぜひupしてください。 >java.util.RandomクラスのnextIntメソッドを使うと、整列したカードをシャッフルした後に >毎回同じような並びになってる気がしたんですが、このクラスのランダムってそういうものなのでしょうか。 ソース希望、ならないと思うけどなあ
564 :
デフォルトの名無しさん :2006/04/12(水) 07:53:23
保守
基本的に擬似乱数はシードを適切に初期化しないと同じ結果が出るだろ
566 :
デフォルトの名無しさん :2006/04/15(土) 20:11:42
携帯だからトリップなし utilのはオブジェクトを作ったときの時間で作られるからその辺きにしなくていいはず なんでソース見たかったです
良スレ保守
先生まだいますか??
569 :
デフォルトの名無しさん :2006/07/03(月) 09:44:24
たまにのぞいてるから 質問あったらどぞー
クラスが持つプロパティやメソッドを表すのに 「.」ではなく、#で表現されているのもありますが、 どういう場合に#で表すのですか?
571 :
デフォルトの名無しさん :2006/07/04(火) 20:53:13
時給1000円でJava教えてくださるかたを募集します 場所 最寄駅 所沢(池袋・高田馬場から直通) よろしくおねがいします i−want−to−study−java@hotmail.co.jp
>>570 説明するときに、
staticの場合は.
staticじゃない場合は#
と書くことによって使い方を表します。
別の言い方で言うと、
インスタンスメソッドを表す記号です。
>>571 通信教育なら良いよwww
このスレでどうぞー
>>572 ご回答、どうもありがとうございます。
その意味を探せ出せなくて、つっかえて
いたところでした。
574 :
571 :2006/07/17(月) 21:37:52
>>572 レスありがとうございます (´∀` )
教える対象は超初心者です。
専門学校などでJavaを勉強されていて夏休みだけ教えたいという方も歓迎です
575 :
デフォルトの名無しさん :2006/07/17(月) 22:41:12
非常に情けない質問で恐縮なのですが j2se5.0の日本語のダウンロード画面が 白紙で何も表示されないで困っております。 解決法を教えていただけないでしょうか? よろしくお願いします
>>572 Googleで検索してキャッシュってとこ押したら表示できるよ!
>>575 ヒント:SunはアンチMS
ヒント:IEはMS製
579 :
デフォルトの名無しさん :2006/09/30(土) 21:59:01
(´・ω・`)
今日からはじめたお。とりあえず>10まですすんだお
581 :
デフォルトの名無しさん :2006/10/22(日) 00:09:45
質問あったらどぞー たまにみてますよー
講座もうやんないの? 903も発表されたことだし、iアプリも交えた講座をやってくれると嬉しい
583 :
デフォルトの名無しさん :2006/12/02(土) 22:33:02
iアプリかー 先生auなんだよー 携帯アプリは興味あるんで質問してくれたら答えるよー 先生てきにはwii買ったからブラウザゲーム作ってwiiで遊びたいなあ とか妄想
過疎ってるのにこうやって書き込むと即効でレス返す先生萌え
すまん。日付見てなかった。へそを曲げないでくれ>先生
586 :
デフォルトの名無しさん :2007/02/11(日) 11:22:56
たまに見てるよー 携帯からだからトリップなしなり
そして伝説へ・・・ じゃなくて、先生まだ見てたらファイル操作とかGUIとか教えてほしいな 講座的にはもう終わり?
588 :
デフォルトの名無しさん :2007/05/28(月) 18:30:14
期待あげ
589 :
デフォルトの名無しさん :2007/06/04(月) 02:45:10
お気に入りに保存。
590 :
デフォルトの名無しさん :2007/06/12(火) 23:33:57
保守
591 :
デフォルトの名無しさん :2007/07/12(木) 18:45:10
592 :
デフォルトの名無しさん :2007/08/20(月) 08:58:01
定期あげ
593 :
デフォルトの名無しさん :2007/08/20(月) 09:13:59
594 :
できるかな? :2007/12/06(木) 13:57:34
課題:じゃんけんゲームを作りなさい。 仕様:ユーザーとコンピュータで、じゃんけんを5回行い、ユーザー観点からの勝敗結果を出力する。 --------結果------- ○ × ○ × ○ あなたの勝ちです!。 本システムでは、1 = グー、2 = チョキ、3 = パーとする。 補足:キーボードの値を渡すには、System.inを使用。 コンピュータの手を決めるには、Ramdom.nextInt(int n) を使用。 どぞ☆
mpeg compass.jp 名古屋駅近辺でお話しましょう
596 :
デフォルトの名無しさん :2008/02/12(火) 21:34:30
ほしゅ
598 :
デフォルトの名無しさん :2008/03/09(日) 11:24:01
言いたいことが良く分からん
>>598 >>11 で合ってますよ
int型の変数xを定義してそれに0を代入するわけですから。
601 :
デフォルトの名無しさん :2008/03/09(日) 18:01:29
>>600 >>11 をコンパイルして実行しても
x:0になってx:5にはならないのだけど
何か勘違いしてる?
>>601 いや合ってる
恐らく先生の勘違いだろ
public class helloWorld {
public static void main(String[] args) {
// 変数の定義
int x;
// xに5を代入
x = 5;
// 文字を表示する
System.out.println("x:" + x);
}
}
だね
603 :
デフォルトの名無しさん :2008/03/09(日) 22:20:03
>>602 ありがとう
よかった、なんせ初心者だから
自分がとんちんかんな事やってるのかと
604 :
デフォルトの名無しさん :2008/04/09(水) 05:34:43
ほ
605 :
デフォルトの名無しさん :2008/04/20(日) 20:57:31
ほ
606 :
デフォルトの名無しさん :2008/04/25(金) 22:43:53
>>20 kyuryo の初期化は必要だと思うんだけど
607 :
デフォルトの名無しさん :2008/04/25(金) 23:47:06
よ〜くかんがえよ〜 初期化はだいじだよ〜
さすがにもう先生はいないかな〜
609 :
デフォルトの名無しさん :2008/06/03(火) 10:53:55
先生久しぶりにきました 確かに勘違いですね すみません
てst
611 :
デフォルトの名無しさん :2008/10/14(火) 00:34:24
オブジェクト化の概念を分かりやすく説明して頂けないでしょうか。 また、オブジェクト化=インスタンス化 ではないのでしょうか? 調べてみてもさまざまな見解があり、よく分からない状態です。 そのクラスで使用できる形にする //オブジェクト化 「呼び出すクラス」 変数a = new 呼び出すクラス(); 変数a.変数b(); のような形で、変数a型として変数bのメソッドを呼び出すことができるとは思うのですが、 この意味を説明しなさいといわれると、なんと説明してよいか言葉に詰まります。 オブジェクト化しないと、「呼び出すクラス」 は使えないと思って良いのですよね?
612 :
デフォルトの名無しさん :2008/10/14(火) 02:59:08
オブジェクト=G7 インスタンス=各国レベルの政策
613 :
◆WtRerEDlHI :2008/10/15(水) 01:45:00
先生です。トリップこれでいいんだっけ・・・
>>611 まず、オブジェクトといっても、文脈によって意味がいろいろあるので「クラス」ということで話を進めます。
まず、クラスを定義します。これは、設計図のようなもので実体はありません。
public class Test { ...(略)... }
実際に使用するときは、クラスを実体化します。
Test a = new Test();
いままで、設計図でしかなかった「Test」を実際に使える形「a」にします。
オブジェクト化っていってるのは、この部分だよね。
「a」は、「Test」っていう設計図をもとに作成した「実体」になります。
「a」は、実体なので、使うことができます。
>オブジェクト化しないと、「呼び出すクラス」 は使えないと思って良いのですよね?
クラスは「設計図」なので、「実体化」しないと使えない。と、最初は覚えるといいと思います。
たとえば、車だったら、「設計図」だけじゃ乗れないので、「実体化」して、はじめて乗れるようになります。
public class Car { ...(略)... }
という車クラスがあったとして、
Car a = new Car();
Car b = new Car();
:
というように、何台も車を作って、それぞれ乗ることができます。
※ちなみに、「設計図」の段階で、使用できるものもあります。staticと定数がそれにあたるんだけど、そのへんは
>>53 とかを読んでみてください。
先生お帰りw 待ってたよ
なるほど! クラス基準で考えた方が分かりやすいのですね。 ありがとうございました。
先生ほんとわかりやすいですね 説明が上手です うちのポリテクの講師と交代してほしいです
今日、このスレ見つけて色々ためになりました 先生質問です。自分、情報学科ですがプログラミングが全然できません… 例題の文章を打っているけど、学校の課題をやるときはいつもつまずき、友達のプログラムをコピーする毎日…… 解答みたら納得できますが、自分ではなかなか作成できません…… どうしたら上達しますか?
618 :
◆WtRerEDlHI :2008/10/21(火) 01:40:59
>>617 うーん、多分だけど、「分からない場所が分からない」のが問題じゃないかな。課題のときとか、どういう風にプログラム作ってる?
まずは、自分のできる範囲でプログラムを作ってみて、わからない場所を明確にしていけばいいと思う。
たとえば、サイコロプログラムを作るとしよう。
どうやってサイコロを振るかはわからなくても、とりあえず
こんな感じのプログラムは作れるよね。
public static void main(String[] args) {
System.out.println("さいころの目:1");
}
絶対に1しかでないプログラムだけど、ここまではできる。
そのあと、変数を使うことを思いつけば、
public static void main(String[] args) {
var x;
x = 1;
System.out.println("さいころの目:" + x);
}
こんな感じのプログラムは作れると思う。
619 :
◆WtRerEDlHI :2008/10/21(火) 01:44:35
ここまでできて、どうしてもサイコロの値を求める方法がわからなかったら、 友達に聞くなり、ネットで調べるなりすればいいと思う。 「途中までできたんだけどさあ、絶対1しか出ないんだよね。」 「1〜6までの数をもとめるのってどうやるの?」 みたいな感じで。 こうやって、わからない場所を明確にしていけば、質問もしやすいし、 友達のプログラムをただコピーするだけって感じにもならないと思う。 まずは、できる範囲から形にしていくといいんじゃないかな。 参考になったでしょうか?
620 :
デフォルトの名無しさん :2008/10/21(火) 20:47:22
先生 ()の中に()いれたりとか .〜〜().〜〜() って.が続くのがさっぱりわかりませぬ この複雑なやつの意味が理解できなくて サーブレットになると意味不明になります
>>620 分かりやすく言うと、東京都千代田区大手町を
東京都.千代田区.大手町
都道府県(13).市区郡(001).町村(0022)
みたいな。
括弧の中に括弧を入れるのがわからないというのは 1 / ((2 + 3) * 4) のような? ドットが続くのは例えば n = x.y().z(); の場合 a = x.y(); n = a.z(); ということ
623 :
デフォルトの名無しさん :2008/10/23(木) 01:39:50
>>621-622 なるほど〜
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
こういう( )を入れ子にするのの意味がわからないんです
意味がわからないままやってたんですけどサーブレットとかアプレットとか
やり出したらきつくなってきて
>>623 ただの入れ子じゃなくてnewの入れ子か。
それは僕も分からん。
625 :
◆WtRerEDlHI :2008/10/23(木) 03:25:26
>>623 InputStreamReader stream = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(stream);
これを1行に合体しただけだよ。
なんで、こういう書き方をするかというと
・すっきりまとまる
・streamは1回しか使わないので名前をつけたくない
という理由だと思います。
もう3年以上続いてるんですね このスレ
>>625 なるほど〜
いつもながらわかりやすいです
どうも
質問です Cをやったときはデバッグっていうの押すと.exeが作られるのでそれ動かせば自分の作ったプログラム動かせたのですが、 Javaってそういうのがないです。Javaはどうすれば普通にプログラムを実行できるのでしょうか?
>>628 jar
exewrap
JavaWebStart
あたりでぐぐってみる
・標準…照準の事。 ・レクティル…レティクルの事。何の疑問も持たずレクティルと呼ぶ。 ・弾ロス…被弾してもダメージを受けないチョンゲーの画期的なシステム 他のFPSをプレイすると、「弾ロスがない!ふしぎ!」とはしゃぐ。 ・ノーブ…noobの事。英語に縁の無い厨が誤解したまま定着した。 ・クープ…co-op(coop)の事。日本語表記にするのは難しいが、 あえて言うならコウォプ、総じてコープと呼ぶことが多い。クープと読むと別な意味になる。 ・クリアニング…クリアリングの事。そもそもクリアリングを知らないのが多数。 「クリアニングも知らないノーブが」と偉そうに語る。 ・ピン…Pingをピンと読むのが通だと思っているが、実際はピングとも言う。 「ピング?w、ピンだよwピンwww」と知ったかぶる。 ・対物ライフルで人を撃つのはハーグ陸戦協定違反!…そんな条文ありません。
java...
633 :
デフォルトの名無しさん :2009/02/16(月) 17:29:43
質問です。javaでポーカーのプログラムを組んでいるのですが、 CPUを4カードねらいにさせようとしているのですがどうも上手くいきません。 どんな風に手札を判定させればいいか皆様のお力添えお願いします
634 :
デフォルトの名無しさん :2009/02/27(金) 20:04:37
家庭教師ってバイトみたいに報酬ありなんですよね? 無料で教えてくれたりするのってないですかね?
>>634 自己投資と思えば100万でも安いでしょう、その技術で稼げるんだから
無料でなんて、甘すぎる
java検定2級とったけど全く意味がない
>>634 つ グーグル
金が無いなら時間を使えとはよく言ったもんだ
638 :
デフォルトの名無しさん :2009/06/01(月) 08:08:16
>>579 -
且且~
且且~
∧__∧ 且且~
(´・ω・) 且且~
`/ヽO=O且且~
/ ‖_‖且且~
し ̄◎ ̄◎ ̄◎
皆さん、お茶が入りましたよ…
java始めたいんだけどコンパイラソフトでお勧めのってある? Eclipseが有名って聞いたんだけど初心者にはお勧めじゃないみたいだし…
640 :
デフォルトの名無しさん :2009/08/12(水) 00:39:29
っと上げた方がよさそうだな…
641 :
デフォルトの名無しさん :2009/08/12(水) 00:49:12
ツールが初心者向けとかそうでないとかで悩む奴にプログラミング言語習得は無理だから諦めれ
642 :
デフォルトの名無しさん :2009/08/13(木) 00:00:05
netbeansおすすめ
自分の限界を安易に定めて、その中で出来ることを探したところで何も出来ない 何も見つからない 本当にやりたいことがあるなら、 そのために自分の能力を高める努力をするものだ そして努力は苦労ではない
>>644 努力以前に元からソフトウェアの開発に適正があったり興味があるひとは自分で自然と覚えていくし
最初は嫌いでも触れていくうちに好きになっていく人も覚えていく。俺もそうだった。
仕事にやりがいや興味を持ってやれる人間は伸びると思うよ。
まぁ、それと同時に働きやすい仕事環境も必要なんだけどね。
逆に嫌々でやってたり仕方なく仕事している人間は努力しないといけないから覚えることが苦労に感じるし、
苦労するのが嫌だから自分の限界を安易に定めてしまうみたい。
雇用能力開発機構(ポリテクとか)なら安く受けられるよ。 あとSunのe-ラーニングくらいか。 それ以外はしらね。
647 :
デフォルトの名無しさん :2010/09/17(金) 23:35:32
講座まだああ
648 :
デフォルトの名無しさん :2010/09/19(日) 14:33:16
いいなあここ。先生待ってます。
javaに興味あるやつはJavaを創った人々って本、絶対読んだ方が良いぞ!
650 :
デフォルトの名無しさん :2010/10/30(土) 14:11:00
651 :
デフォルトの名無しさん :2011/01/05(水) 10:22:26
過疎ってんな。。
axizやリナックスアカデミーの講座って職を得るために受ける価値ある?
653 :
デフォルトの名無しさん :2011/06/29(水) 15:30:09.56
Javaは最初のうちは分かるんだがそのうちなんだか段々と迷宮に・・・ ここは・・・どこ?って感じになってどこからやり直そうっていつも思う。
654 :
デフォルトの名無しさん :2011/07/02(土) 05:34:41.26
java勉強中の学生にとっては素晴らしすぎるスレ 本当にこういったスレの存在はありがたいです・・・ 引き続き頑張るとします!
2011年、Ruby,Perl,PHP,Pythonって並べたときにさ ここで、Ruby以外を選ぶ奴ってマジでなんなんだろうな お前らはほんとにゴミだな
656 :
デフォルトの名無しさん :2011/07/26(火) 15:06:52.29
なんか書き込めない・・・
最近javaやってるんだが、やらないか?
659 :
デフォルトの名無しさん :2012/05/16(水) 14:34:48.79
Javaなんて使っている人まだいるの?
そりゃいるだろ なぜか知らんが Android があれだけ人気あれば
661 :
デフォルトの名無しさん :
2012/05/17(木) 09:26:29.58 自分も現在Java勉強中の学生なのでこのスレはありがたいです! 勉強させていただきます!!