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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

Q&A

1回答

2977閲覧

Java初心者:method移行時の処理について不明点

Takafumi-Seto

総合スコア8

Java

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

0グッド

0クリップ

投稿2015/11/15 06:07

###前提・実現したいこと
java初心者です。
練習としてカードゲームのハイアンドローのプログラムを組んでいるのですが下記のような状況になりモヤモヤしています。
全体的にかなり疎いコードでかつ、まだまだ未完成なので見づらい部分ばかりだとは思いますがどなたかご教授して頂けると幸いです。
下記問題以外にもハイアンドローを組む上でもっと効率的に組める方法やアイディア等気になる点が御座いましたら、是非とも伺いたいです。

###発生している問題・エラーメッセージ
問題自体は解決しています。
「proccess03」での「proccess04(bet,card,select);」を呼び出すポイントについて疑問があります。
問題発生当初「proccess04」の呼び出しをソースコード内に「// ※※問題発生箇所※※ //」とコメントしてある場所に書いていたのですが、その場合間違った入力がされて「proccess03」をやり直した数だけ(else分岐ルートを通った回数)、「proccess04」が繰り返されてしまいました。
その際に「int card」の乱数発生が毎回行われ違う数値になるのはもちろん、「String select」も間違った物を全種類引き継いだまま複数回繰り返されていて、単純にどうしてそのような処理になるのか分からず詰まっていました。
結果として、「proccess03」でif分岐ルートを通った際にif文の中で「proccess04」を呼び出しする事で上記の問題は起こらなくなったのですが、そもそもなぜ間違っていたのかが分からない為、当然、思い通りに動くようになった理由も分からない状態のままになっています。
かなり漠然とした質問になってしまっているのですが、理由を知りたくて質問させて頂きました。

###ソースコード

java

1public class highandlow{ 2 public static void main(String[] args){ 3 System.out.println("Welcome."); 4 System.out.println("Could you tell me your name?"); 5 String name = new java.util.Scanner(System.in).nextLine(); 6 proccess01(name); 7 // ここで名前と掛け金の入力 // 8 } 9 public static void proccess01(String name){ 10 System.out.println("Ok," + name + ".Bet please."); 11 int bet = new java.util.Scanner(System.in).nextInt(); 12 proccess02(bet); 13 // この掛け金を後にproccess05で使う為 // 14 // ここから下のmethodで全て引き継ぎ (もっとスマートに出来る?)// 15 } 16 public static void proccess02(int bet){ 17 System.out.println("Draw."); 18 int card = new java.util.Random().nextInt(13) + 1; 19 System.out.println("The card is " + card); 20 proccess03(bet,card); 21 // カードドロー + 表示 // 22 } 23 public static void proccess03(int bet,int card){ 24 System.out.println("High or Low?"); 25 String select = new java.util.Scanner(System.in).nextLine(); 26 if ("high".equals(select) || "High".equals(select) || "low".equals(select) || "Low".equals(select)){ 27 System.out.println("Ok..."); 28 proccess04(bet,card,select); 29 }else{ 30 System.out.println("Wrong selecet.Please call in \"high / High / low/ Low\""); 31 proccess03(bet,card); 32 } 33 // ※※問題発生箇所※※ // 34 // ハイアンドローの選択、誤った選択の場合繰り返し // 35 } 36 public static void proccess04(int bet,int card,String select){ 37 System.out.println("Card is " + card + ".And you selected" + select + "."); 38 int newcard = new java.util.Random().nextInt(13) + 1; 39 System.out.println("Next card is....." + newcard +"!!"); 40 proccess05(bet,card,newcard,select); 41 // カードとハイアンドローの確認、その後カードドロー // 42 } 43 public static void proccess05(int bet,int card,int newcard,String select){ 44 if (card < newcard && "high".equals(select) || "High".equals(select)){ 45 System.out.println("win with high"); 46 bet = bet * 2; 47 System.out.println("now,you got" + bet); 48 }if (card > newcard && "low".equals(select) || "Low".equals(select)){ 49 System.out.println("win with low"); 50 bet = bet * 2; 51 System.out.println("now,you got" + bet); 52 }else{ 53 System.out.println("lose"); 54 bet = bet * 0; 55 System.out.println("now,your bet is gone right now ^v^"); 56 } 57 // 複合結果からの勝敗、それに伴った掛け金の増減 // 58 // 負けた場合proccess01へ // 59 // 勝った場合proccess02へ // 60 // ここで設定する繰り返し処理が上手くいかず詰み // 61 // newcardの値をcardへ代入したいのですが // 62 // proccess02ではcardの乱数発生があり // 63 // どう互換性を保つか分からない // 64 } 65}

###宜しくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

process03の中でprocess03を呼び出す再帰になっているからです。
仮に最初のprocess03をa,その中でelseに入ったことにより呼んだprocess03をbとします。
このとき、bの処理が終わった後、aでbを呼んだ場所に戻るのです。
戻った後、aの処理が続行されます。すなわち、elseを抜けた後のprocess04が呼び出されることになります。
今、簡単のためにaとbの2段階で説明しましたが、いくつになってもこの原理は変わりません。
つまり、elseの中で再帰した回数だけ、elseを抜けた後の処理が実行されるので、問題の現象が発生します。

ハイ&ローのシステムですが、結局全部ひとつづきにしていて、メソッドに分割しているメリットが余りないように思います。メソッドに分割するなら、機能別に分けて、それぞれの機能をmainから呼び出す形のほうがわかりやすいかと思います。
つまり、

  • process01:名前の入力
  • process02:掛け金の入力
  • process03:ハイかローかの選択
  • process04:次のカードドロー
  • process05:判定と払い戻し

mainメソッドで名前や掛け金を管理して、それを各メソッドに渡す、という構造にしたほうがいいです。
また、入力した文字がhighかlowかを、大文字小文字を無視して判定したいのなら、equalsIgnoreCaseという便利なメソッドがありますのでご検討ください。

java

1if (card < newcard && "high".equals(select) || "High".equals(select))

ここは大問題です。論理演算子&&や||は、左から順に計算されます。
仮にcard < newcard か "high".equals(select)がfalseを返した場合、
card < newcard && "high".equals(select)全体としてfalseになります。
しかし、この後false || "High".equals(select)の評価になります。
ここで"High".equals(select)がtrueを返せば、このif文の中身はtrueとなります。
つまり、カードの如何にかかわらず、selectに"High"が入っていれば勝ちになるというコードになります。
下のif文も同じです。つまり**"High"か"Low"と入力すれば必勝になってしまいます**。

投稿2015/11/15 06:20

編集2015/11/15 07:55
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Takafumi-Seto

2015/11/17 01:12

aとbに例えた説明がすごく分かりやすかったです。 また、メソッドを活用出来ていない現状や演算子の使い方の指摘も助かりました。 参考にして根本から組み直しを頑張ってみます。 ありがとうございました。
swordone

2015/11/17 16:20

ちなみに、論理演算子(に限らずあらゆる演算)については括弧を使って演算の順番を変えることで、望む結果を得ることができます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問