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

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

ただいまの
回答率

90.81%

  • Java

    12556questions

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

出力が重複するバグの原因がわかりません。 java超入門

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 185

chicken-a_s.

score 25

おはようございます。

現在youtubeのjava超入門という動画をみて勉強しているのですが、出力が重複するバグが起こり、何度見直しても解消されません。

import java.util.*;
import java.io.*;

public class part18 {

        static String name = "ほげさん";
        static int lv = 30;
        static int hp = 30;
        static int gold = 10000;

        public static void main( String[] args ) throws IOException {

            joshou();     
            for( ; hp > 0; ){
                command();
            }            
        }

        static void joshou(){                    //序章を出力

            System.out.println( "魔王が世界を滅ぼそうとしています。" );
        }

        static void status(){                    //ステータスを出力

            System.out.println("--------------------------------------");
            System.out.println( name + "  Lv :" + lv + " HP :" + hp + "  Gold :"  + gold + "G" );
            System.out.println("--------------------------------------");
        }

        static void command() throws IOException {            //コマンドを表示

            status();

            System.out.println( " 1, 魔王を倒しに行く。" );
            System.out.println( " 2, 修行する。" );
            System.out.println( " 3, 宿屋に泊まる" );
            System.out.println("--------------------------------------");

            cmd();
        }

        static void cmd() throws IOException {                //コマンド処理設定

            int c = System.in.read();

            switch( c ) {

                case ( '1' ) :

                    if( lv < 40 ){
                            System.out.println( "魔王に敗れた。" );
                            gameover();
                        }else{
                            gameclear();
                        }

                        break;

                case ( '2' ) : 

                    Random rnd = new Random();
                    int monster = rnd.nextInt( 5 )+ 1;
                    int damage = rnd.nextInt( 5 );
                    int ex = rnd.nextInt( 5 );

                    System.out.println( "敵が " + monster + "匹 現れた。" );

                    hp -= damage;

                    if( hp < 0 ){
                        hp = 0;
                    }

                    if( hp > 0 ){
                        System.out.println( name + "は " + damage + " のダメージを受けた。" );
                        System.out.println( "敵を倒した。" + name + "は経験値を " + ex + " 獲得した。" );
                        lv += ex;
                    }else{
                        System.out.println( name + "は" + damage + "のダメージを受けた。" );
                        System.out.println( "HPが0になった。" );
                        gameover();    
                    }

                    System.out.println();          //改行
                    break;

                case ( '3' ) :

                    System.out.println( "HPが回復した。" );
                    hp = hp;

                    break;
            }
        }                

        static void gameover(){            //GAME OVER画面を出力

            System.out.println( "GAME OVER" );
        }

        static void gameclear(){            //GAME CLEAR画面を出力

            System.out.println( "魔王を倒した!" );
            System.out.println( "GAME CLEAR" );
        }
}

こちらのソースなのですが、出力が下記のように2度目の入力の時点でステータスとコマンド選択の出力が重複して表示されてしまいます。

魔王が世界を滅ぼそうとしています。
--------------------------------------
ほげさん  Lv :30 HP :30  Gold :10000G
--------------------------------------
 1, 魔王を倒しに行く。
 2, 修行する。
 3, 宿屋に泊まる
--------------------------------------
2
敵が 2匹現れた。
ほげさんは0のダメージを受けた。
敵を倒した。ほげさんは、0の経験値を手に入れた。

--------------------------------------
ほげさん  Lv :30 HP :30  Gold :10000G
--------------------------------------
 1, 魔王を倒しに行く。
 2, 修行する。
 3, 宿屋に泊まる
--------------------------------------
--------------------------------------
ほげさん  Lv :30 HP :30  Gold :10000G
--------------------------------------
 1, 魔王を倒しに行く。
 2, 修行する。
 3, 宿屋に泊まる
--------------------------------------

HPが0以上の場合、
ステータス表示
コマンド選択表示
入力受け取り
という流れをループさせたいのですが、分かる方がいましたら教えていただけると幸いでございます。

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • chicken-a_s.

    2018/06/12 09:08

    意図しない動きをバグと言わずなんと呼ぶべきなのかはわかりませんが。

    キャンセル

  • dit.

    2018/06/12 10:33

    私の「表現するべきではない」という言葉がいけませんでした。開発者の意図しない動作は確かにバグと呼べますね。バグという言葉に敏感になりすぎていたようです。(いつからか言われている「プログラムは思った通りに動かない、書いた通りに動く」という言葉を聞いてから、「仕様通りではないが記述どおりの動作」をなるべくバグと呼びたくなかったのですが、その考えを押し付けるような形になってしまいました。申し訳ないです。)

    キャンセル

  • chicken-a_s.

    2018/06/12 10:58

    とんでもないです。 元はと言えば私の勉強不足です。 私にとってはバグでも、開発者の力量によっては即座に解消でき、バグと認識しないのかもしれません。ご指摘ありがとうございます。 日本語は難しいですね。

    キャンセル

回答 2

checkベストアンサー

+1

System.in.read() で一文字づつ読み出してますが、2を読んだあと改行が読まれるので、2回繰り返してるように見えるのでしょう。
改行が入力されたときは無視する、とかする必要があります

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/12 08:50

    回答ありがとうございます。
    解決できました。

    キャンセル

+1

こんにちは

まず、ソースコードを見て気になったところを言いたいと思います。

1.Main関数にてfor( ; hp > 0; )とありますがなんとなく見づらいのでwhile(hp > 0)にしました。

2.関数command()の中にstatus()がありますが、Main関数にて

while(hp > 0){
     status();
     command();
}


としたとした方がいい気がします。

3.関数cmdのcase '3'のところにhp = hpにしていますが、これではhpは回復しません。
.static final int FIRST_HP = 30;などを宣言してhp = FIRST_HPにすべきです。
また、switch文なので一応defaultを書きましょう。

4.gameoverまたはgameclearしてもプルグラムが終了しないので
.static boolean gameover;
.static boolean gameclear;で判定するようにしました。

 これ以外で変更したところ

入力をScannerにしました。これで解決するはずです。

以上です。ソースコードを載せておきます。

import java.util.*;


public class part18 {

        static String name = "ほげさん";
        static int lv = 30;
        static final int FIRST_HP = 30;
        static int hp = 30;
        static int gold = 10000;
        static boolean gameover;
        static boolean gameclear;

        public static void main( String[] args ){

            joshou();  

            while(hp > 0){
                status();
                command();
                if(gameover || gameclear){
                    break;
                }
            }
        }

        static void joshou(){                    //序章を出力

            System.out.println( "魔王が世界を滅ぼそうとしています。" );
        }

        static void status(){                    //ステータスを出力

            System.out.println("--------------------------------------");
            System.out.println( name + "  Lv :" + lv + " HP :" + hp + "  Gold :"  + gold + "G" );
            System.out.println("--------------------------------------");
        }

        static void command(){            //コマンドを表示

            System.out.println( " 1, 魔王を倒しに行く。" );
            System.out.println( " 2, 修行する。" );
            System.out.println( " 3, 宿屋に泊まる" );
            System.out.println("--------------------------------------");

            if(hp < 0){
                hp = 0;
                System.out.println( "HPが"+ hp + "になった。" );
                gameover();
            }

            cmd();
        }

        static void cmd(){                //コマンド処理設定

            Scanner sc = new Scanner(System.in);
            int c = sc.nextInt();

            switch(c) {

                case 1 :

                    if( lv < 40 ){
                        System.out.println( "魔王に敗れた。" );
                        gameover();
                    }
                    else{
                        gameclear();
                    }

                        break;

                case 2 : 

                    Random rnd = new Random();
                    int monster = rnd.nextInt( 5 )  + 1;
                    int damage = rnd.nextInt( 5 );
                    int ex = rnd.nextInt( 5 );

                    System.out.println( "敵が " + monster + "匹現れた。" );

                    System.out.println( name + "は" + damage + "のダメージを受けた。" );
                    hp -= damage;

                    System.out.println( "敵を倒した。" + name + "は、" + ex + "の経験値を手に入れた。" );
                    lv += ex;

                    System.out.println();          //改行
                    break;

                case 3 :

                    System.out.println( "HPが回復した。" );
                    hp = hp;
                    break;
                default:
                    break;

            }
        }                

        static void gameover(){            //GAME OVER画面を出力

            System.out.println( "GAME OVER" );
            gameover = true;
        }

        static void gameclear(){            //GAME CLEAR画面を出力

            System.out.println( "魔王を倒した!" );
            System.out.println( "GAME CLEAR" );
            gameclear = true;
        }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/12 09:01

    回答ありがとうございます。
    自分で見ていても現状つっこみどころの多い処理ばかりで、Starsさんのご指摘も参考に動画を見ながら直していきます。
    ありがとうございます。

    キャンセル

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

  • ただいまの回答率 90.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    12556questions

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