| 著作一覧 |
LinuxだとJNI_GetDefaultJavaVMInitArgs がSEGVと書いていたが、JNI_GetDefaultVMInitArgsに与える引数を間違えていた。
JDK1_1InitArgsを使っていたが、実際には、JavaVMInitArgsを使用する。
Solarisで、-Xusealtsigsを与えるためにいろいろ調べたら、結局、JavaVMInitARgsのJavaVMOption *optionsメンバに設定するらしいとわかったからだ。
で、JavaVMInitArgsを利用するように修正したら、Linuxでも通るようになった。では、JDK1_1InitArgsってのは一体どこで使えるんだろう?
追記:寝ぼけてるようだ。1_1なんだからJDK1.1用で、Java2(1.2)以降は、JavaVMInitArgsになったということだろう(データメンバが少ないので逆に考えてしまったらしいが、万能のoptionsメンバが追加されてるわけだし)。
なんか、最近やたらめったら「アドレス変更しました(音符マーク)」というサブジェクトのspamが来る。とにかく来る。連続5個くらい来たりする。
という状況の中で、「サイト移転のお知らせ」というのが来たので、即効削除しようとしてふと一瞬出た文面がそれまでと調子が違うので、あわてて手を止めた。Fe2+さんからのRuby256倍勝手に正誤表の移転のお知らせだった。危なかった。
で、思い出したが、ここまでspamがガンガン来ると、もう、「常識ではsubjectはASCIIで書くべきですな」とは言えないし(「アドレス変更しました」はとりあえず置いておいて)、用件だけ手短にってのもあまりうまくなさそうだな。
import java.io.*;
public class Gcp {
private static final String te[] = {"グー", "チョキ", "パー"};
private int win;
private int loose;
private int fair;
private BufferedReader reader;
private final Result[][] state;
public Gcp () throws IOException {
reader = new BufferedReader(new InputStreamReader(System.in));
state = new Result[3][3];
state[0][0] = state[1][1] = state[2][2] = new Fair();
state[0][1] = state[1][2] = state[2][0] = new Win();
state[0][2] = state[1][0] = state[2][1] = new Loose();
}
private abstract class Result {
void execute(int you, int com) {
System.out.print(" コンピュータ:" + te[com] +
",プレイヤー:" + te[you] + ":");
}
}
private class Win extends Result {
void execute(int you, int com) {
super.execute(you, com);
System.out.println("あなたの勝ちです!");
win++;
}
}
private class Loose extends Result {
void execute(int you, int com) {
super.execute(you, com);
System.out.println("あなたの負けです!");
loose++;
}
}
private class Fair extends Result {
void execute(int you, int com) {
super.execute(you, com);
System.out.println("引き分けです!");
fair++;
}
}
public void execute(int count) {
win = loose = fair = 0;
for (int i = 0; i < count; i++) {
int you = read();
int com = (int)(Math.random() * 2 + 1);
state[you][com].execute(you, com);
}
System.out.println("プレイヤーの勝敗数:" + win + "勝" +
loose + "負" + fair + "引き分け");
}
private int read() {
for (;;) {
System.out.print("あなたの手(0:グー、1:チョキ、2:パー)");
String s;
try {
s = reader.readLine();
} catch (IOException e) {
continue;
}
if (s.length() > 0) {
if (s.equals("q")) { // バックドア
System.exit(1);
}
try {
int n = Integer.parseInt(s);
if (n >= 0 && n <= 2) return n;
} catch (NumberFormatException e) {
}
}
}
}
public static void main(String[] args) throws Exception {
Gcp gcp = new Gcp();
gcp.execute(5);
}
}
添削結果:
public class K {
public static void main(String[] args) {
double k = 0.9999999999999999;
System.out.println("result=" + ((int)(k * 3))); // -> 2
double j = 0.99999999999999999;
System.out.println("result=" + ((int)(j * 3))); // -> 3
}
}
となるけど、代入時点で既にjは1.0になっているのか。
ジェズイットを見習え |
looseじゃなくてloseですよ
「グー、チョキ、パーをオブジェクト化してStrategyを適用してください。」は難しすぎですか?
難しいかどうかはわかりませんが、勝ち負け判定してカウントすることがプログラムの目的となっています。グーチョキパーは、勝敗に比べると着目価値がありません。
Strategy you = te.lookup(read());<br>ちょっと考えたけど<br>Strategy com = te.lookup(rand...);<br>Result.Display(you.battle_with(com));<br>かな? というか、グーチョキパーそれぞれをストラテジにするって変な気がするな(必ず対で出てくるし)。<br>取り得る状態が決定している場合は、ステートを使うべきだと思うが、逆にどう、ストラテジパターンを適用するのかちょっと知りたいところ。
勝ち負け判定の処理が複雑な気がしたので、オブジェクト化したグーチョキパーに任せれば、重要なカウント処理も単純になるかな?と思いました。
カウントは、勝ちオブジェクト、引き分けオブジェクト、負けオブジェクトの属性だし、勝ち負け判定はチャートのルックアップだからこれ以上単純化は不可能だと思いますが。<br>#3人じゃんけんならチャートが3次元になる。
ステートとストラテジーの違いは状態を多様化するのか処理を多様化するのかの違いで、インターフェースを多様化するという意味では同じパターンで、名前が違うだけですよね(この理解が間違っているかも知れませんが)。<br><br>グーチョキパーは勝ち負け判定を多様化するのが目的なのでストラテジーの方を使いました。<br><br>実装としてはTeをスーパクラスにGoo,Choki,Paaを定義<br>result = myTe.judge(yourTe);<br>のような感じだと思います。
まともなコードを書けばコメントは不要というのには大賛成です。まともなコードを書いていればコメントはコードに書いてあることを日本語化するだけの役割しか持たなくなるはずですので。
名前が違うだけと言われるとすごく抵抗を感じるけど、確かに見てくれはほとんど同じですね(実際、どっちか微妙なものもあるし)。<br>状態遷移テーブルのルックアップや、State next = currentState.next(newInput);のように比較的機械的に取得可能なのがステートで、Strategy stg = createStragety(newInput);のように、取得に独自の判定が必要なのがストラテジかな、とか漠然に感じています。
漠然「と」感じているのに、決定したときは明確な意志があるのはなぜだろう? 後、閉じている(ステート)、開いている(ストラテジ)なんだけど、意味わからないな、これでは。
そういわれれば、ステートは静的なストラテジは動的なイメージがあるかも知れません。
で、思ったんですが、グーチョキパーはエンティティとして考えて(ストラテジとして考えるには同時に2つ実体化されるのがどうしても気になる)、ここからストラテジを引っ張ってくる(この場合は勝負オブジェクトがステートじゃなくてストラテジ)というのはどうでしょう?<br>Te yours = Gcp.getTe(read());<br>Te comps = Gcp.getTe(Math.rand()...); // Teは勝敗判定を持つ<br>Strategy result = yours.battle(comps); // Strategyの実体は上のステート<br>result.show(); // 上のexecute/judge
しかし、好き嫌いでいくと、あまり好きではないな(状態遷移表引っ張るのが好きだからってのはあるかも)
ステートかストラテジかはおいておいて、僕が意図したコードはそんな感じです。考え方も実装もこちらの方が簡単かな?と。
あれ?嫌いなんですね。こういうコード。僕は自分がアホなので、アホでも解るコードが好きらしいです(考えることが少なくてすみますし)。
「// InputStreamReaderクラスのインスタンスを生成する。」こういうコメント嫌い。
(int)(Math.random() * 2 + 1); わははチョキさえ出してれば負けないぞ!
あ、10に書いてありましたね。すんません。
違いますよ。るいもさんの書き込みを見て書き足したんです。「確かにその通り」の部分がリンクになってます。