Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

30

もっと賢く動かしたい

http://read.pudn.com/downloads78/sourcecode/java/296785/TCP_IP_JAVA_SRC/ch5/UmiServer.java__.htm
http://read.pudn.com/downloads78/sourcecode/java/296785/TCP_IP_JAVA_SRC/ch5/UmiClient.java__.htm

上記2つのファイルから成る、燃料を取得するゲームで
自動的に燃料を取得するrobt.javaを作りたく、以下のファイルを参考に、

http://read.pudn.com/downloads78/sourcecode/java/296785/TCP_IP_JAVA_SRC/ch5/Robot.java__.htm

以下のように書き換えました。

// 「海ゲーム」クライアントプログラムRobot.java
// このプログラムは,海ゲームのクライアントプログラムです
// 決められた手順で海ゲームをプレイします
// 使い方java Robot 接続先サーバアドレスゲーム参加者名
// 起動後,指定したサーバと接続し,自動的にゲームを行います
// 起動後,指定回数の繰り返しの後,logoutします
// このプログラムはlogoutコマンドがありません
// プログラムを途中で停止するには,以下の手順を踏んでください
// (1)コントロールC を入力してRobotプログラムを停止します
// (2)T1.javaプログラムなど,別のクライアントを使ってRobotと同じ名前でloginします
// (3)logoutします
// 別クライアントからのlogout作業を省略すると,サーバ上に情報が残ってしまいます

// ライブラリの利用
import java.net.*;// ネットワーク関連
import java.io.*;
import java.util.*;

// Robotクラス
public class Robot {
    // ロボットの動作タイミングを規定する変数sleeptime
    int sleeptime = 50 ;
    // ロボットがlogoutするまでの時間を規定する変数timeTolive
    int timeTolive = 50 ;
    // コンストラクタ
    public Robot (String[] args)
    {
        login(args[0],args[1]) ;
        try{
            for(;timeTolive > 0; -- timeTolive){
                System.out.println("あと" + timeTolive + "回") ;
                // 10 回に渡り,sleeptime*100ミリ秒おきにleftコマンドを送ります
                for(int i = 0;i < 10;++i){
                    Thread.sleep(sleeptime * 100) ;
                    out.println("left");
                    out.flush() ;
                }
                // 10 回に渡り,sleeptime秒おきにrightコマンドを送ります
                for(int i = 0;i < 10;++i){
                    Thread.sleep(sleeptime * 100) ;
                    out.println("right");
                    out.flush() ;
                }
                // upコマンドを1 回送ります
                out.println("up");
                out.flush() ;
            }
            // logout処理
            out.println("logout") ;
            out.flush() ;
            server.close() ;
        }catch(Exception e){
            e.printStackTrace();
            System.exit(1);
        }
    }

    // login関連のオブジェクト
    Socket server;// ゲームサーバとの接続ソケット
    int port = 10000;// 接続ポート
    BufferedReader in;// 入力ストリーム
    PrintWriter out;// 出力ストリーム
    String name;// ゲーム参加者の名前

    // loginメソッド
    // サーバへのlogin処理を行います
    void login(String host, String name){
        try {
            // サーバとの接続
            this.name = name;
            server = new Socket(host, port);
            in = new BufferedReader(new InputStreamReader(
              server.getInputStream()));
            out = new PrintWriter(server.getOutputStream());

            // loginコマンドの送付
            out.println("login " + name);
            out.flush();
        }catch(Exception e){
            e.printStackTrace();
            System.exit(1);
        }
    }
    
    void auto(){
        int ship_x = 0, ship_y = 0, ene_x = 0, ene_y = 0;
        try {
            String line = in.readLine();// サーバからの入力の読み込み

            //ship_infoから始まる船の情報の先頭行を探します
            while (!"ship_info".equalsIgnoreCase(line))
                line = in.readLine();

            // 船の情報ship_infoの表示
            // ship_infoはピリオドのみの行で終了です
            line = in.readLine();
            while (!".".equals(line)){
                StringTokenizer st = new StringTokenizer(line);

                // 船の位置座標を読み取ります
                int x = Integer.parseInt(st.nextToken()) ;
                int y = Integer.parseInt(st.nextToken()) ;
                ship_x = x;
                ship_y = y;

                // 次の1行を読み取ります
                line = in.readLine();
            }

            // energy_infoから始まる,燃料タンクの情報を待ち受けます
            while (!"energy_info".equalsIgnoreCase(line))
                line = in.readLine();

            // 燃料タンクの情報energy_infoの表示
            // energy_infoはピリオドのみの行で終了です
            line = in.readLine();
            while (!".".equals(line)){
                StringTokenizer st = new StringTokenizer(line);

                // 燃料タンクの位置座標を読み取ります
                int x = Integer.parseInt(st.nextToken()) ;
                int y = Integer.parseInt(st.nextToken()) ;
                ene_x = x;
                ene_y = y;

                // 次の1行を読み取ります
                line = in.readLine();
            }

            if (ship_x < ene_x) {
                out.println("right");
            } else if (ene_x < ship_x) {
                out.println("left");
            }
            
            if (ship_y < ene_y) {
                out.println("up");
            } else if (ene_y < ship_y) {
                out.println("down");
            }
            
        }catch (Exception e){
            e.printStackTrace();
            System.exit(1);
        }
    }

    // mainメソッド
    // Robotを起動します
    public static void main(String[] args){
        new Robot(args);
    }
}

左右には動くのですが、上下に動きません。
また、このif文の書き方はイマイチだなと思うのですが、どのように改善すればより良くなるでしょうか。

よろしくお願いいたします。

2

回答

8215

閲覧

2件の回答

評価

0

>左右には動くのですが、上下に動きません。
それはただのバグだろうから、調査してみることだ。

>このif文の書き方はイマイチだなと思う
まず処理の必要ないものを弾けばelseで良くなる。

状態に応じた0,1,2が作れれば表示文を配列から取れる。

オブジェクト指向でのポイントの一つに、条件分岐が継承で
隠れるように考えるというものがある。

状態を抽象クラスにしてその具象クラスで処理する、という
古典的な手を使ってもいい。
(デザインパターンでStateと呼ばれるようになったやつだ)

readLineしてwhileを回す部分も格納先が違うだけのようだ。
xとyを別に扱わないように考える。
「座標」というモノ(クラス)を見出せるようになろう。

こんなところでどうだ?

評価

310

これは、同●社大学の講義の課題ですね。

みなさん、教えては彼のためにならないので、
スルーしましょう。

なお、多くの学生さんがここにたどり着いていると思いますが、

このようなトピックが建てられていることは
講義担当の教授に報告させていただきますので、

このプログラムを参考に作成しても、良くて大幅な減点、最悪カンニングした、誰かのを写したと判断されるリスクがあることを忘れないでくださいね。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。