おはようございます。
現在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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
System.in.read() で一文字づつ読み出してますが、2を読んだあと改行が読まれるので、2回繰り返してるように見えるのでしょう。
改行が入力されたときは無視する、とかする必要があります
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+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;
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
m.ts10806
2018/06/12 08:19
バグ、とは言いますが、プログラムは指示した通りにしか動かないのでご自身がそのように組んでしまっていることは認識しておいた方が今後のためになると思います。
Nerd_run.
2018/06/12 08:26
指示をミスしている箇所がわからないので質問しています。
dit.
2018/06/12 08:32
「希望通りに動かない」ことを「バグ」と表現するべきではない という指摘かと思います。
Nerd_run.
2018/06/12 08:48
ではなんと表現するべきなのでしょう?
m.ts10806
2018/06/12 08:50
デバッグ実行で確かめるくらいはできるようになりましょう。質問して回答待つより早いこともよくあります。
m.ts10806
2018/06/12 08:52
今回の場合は「出力が重複してしまう」だけで良いかと。いずれにしてもそのバグをおこしてしまってるのは自身に他ならないわけです。
Nerd_run.
2018/06/12 09:08
System.in.read();の機能をよくわからず使っていた為に起こり、気づけなかったので、そういうところを指摘しているのでしょうか?
Nerd_run.
2018/06/12 09:08
意図しない動きをバグと言わずなんと呼ぶべきなのかはわかりませんが。
dit.
2018/06/12 10:33
私の「表現するべきではない」という言葉がいけませんでした。開発者の意図しない動作は確かにバグと呼べますね。バグという言葉に敏感になりすぎていたようです。(いつからか言われている「プログラムは思った通りに動かない、書いた通りに動く」という言葉を聞いてから、「仕様通りではないが記述どおりの動作」をなるべくバグと呼びたくなかったのですが、その考えを押し付けるような形になってしまいました。申し訳ないです。)
Nerd_run.
2018/06/12 10:58
とんでもないです。 元はと言えば私の勉強不足です。 私にとってはバグでも、開発者の力量によっては即座に解消でき、バグと認識しないのかもしれません。ご指摘ありがとうございます。 日本語は難しいですね。