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

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

ただいまの
回答率

90.61%

  • Java

    13505questions

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

JAVAの数あてゲームについて

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,999

Yoshinori

score 27

現在JAVAでランダムに重複しない4つの数字(a)を設定し、Scannerで数字を4つ打ち込んでaとすべて一致したらOKと表示するコードを書いています
そこまでは行けたのですがたとえば
aが1234でScannerで1524
と打ち込んだ時に一致している部分は○、間違えている部分は×と表示したいです
例)上記のだと1、4が一致しているので
  ○2、×2という風にしたいです

答えではなくヒントといいますか手引きをしてほしいです
よろしくお願いします


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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 4

0

一致した桁の数を保持する変数を用意し、
桁ごとに比較し一致したら変数に1を加え、
その結果をもとに表示すればいい。

4桁の乱数生成方法もちょっと気になるので私なりに書いてみます
for(int i = 0; i < 4; i++){
    check: while(true){
        int n = (int)(Math.random() * 9) + 1;
            for(int j = 0; j < i; j++){
                if(n == ans[j]) continue check;  //一致したら乱数生成に戻る
            }
        ans[i] = n;
        break;
    }
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

擬似的なコードで示します。

count_x = 0   //  不一致の数
count_o = 0   //  一致のかず
i = [0, 1, 2, 3] でループする。
  if num[i] == ans[i]
    count_o += 1  // 一致の数を +1 する
  else
    count_x += 1  // 不一致の数を +1 する


投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/06/07 10:44

    ありがとうございます
    教えていただいたように以下のように書いてみました。
    ですが実行すると
    aが1234で答えを1235とすると
    1つ間違い
    2つ間違い
    3つ間違い
    4つ間違い
    となってしまいます
    なぜ正解の部分が処理されないのでしょうか?
    if(num[1] == ans[0] && num[2] == ans[1] && num[3] == ans[2] && num[4] == ans[3]){
    System.out.println("OK");
    }else{
    for(int i = 0; i < 4; i++){
    if(num[i] == ans[i]){
    ans_ok += 1;
    System.out.println(ans_ok + "つ正解");
    }else{
    ans_bat += 1;
    System.out.println(ans_bat + "つ間違い");
    }
    }
    }

    キャンセル

  • 2015/06/07 10:56

    インデックスの付け方がずれているからです
    ans:[1,2,3,4]
    num:[1235,1,2,3,5]となっているので,
    1 == 1235 =false
    2 == 1 = false
    という比較になり,すべて間違い判定になるのです.
    比較する配列インデックスをnumの方だけ+1するか,
    そもそもnumの配列の入れ方がおかしいのでそれを修正するかですね

    キャンセル

  • 2015/06/07 11:02

    申し訳ございません
    JAVAを勉強してからまだ少ししかたっていませんのでもう少し噛み砕いて説明してほしいです・・・。

    キャンセル

  • 2015/06/07 11:28

    ans[0]:千の位,ans[1]:百の位・・・に対し,
    num[0]:解答した数字,num[1]:千の位,num[2]:百の位・・・
    あなたのコードではこうなっています.
    そしてans[i]==num[i]という比較は,
    ans[0]==num[0], ans[1]==num[1]・・・という比較になります

    キャンセル

  • 2015/06/07 11:32

    なので解決するには比較をans[i]==num[i+1]とするか,
    Scanner sc = new Scanner(System.in);
    int[] num = new int[4];
    int x = sc.nextInt();

    num[0] = x / 1000;
    t_much = x % 1000;
    num[1] = t_much / 100;
    t_much = t_much % 100;
    num[2] = t_much / 10;
    t_much = t_much % 10;
    num[3] = t_much;
    このように入力した数値を配列に入れずに,桁の数字を配列の0からスタートさせるかするべきですね.
    ちなみに整合性の問題から考えると後者が好ましいです.

    キャンセル

  • 2015/06/07 11:43

    なるほど!ありがとうございます!!
    よくわかりました!
    すみません最後の質問です
    正解するまで数字の入力を繰り返せるようにしたく、以下のようにdo~while文で囲んだのですがnumがエラーとなります。これはなぜなのでしょうか?
    do{
    Scanner sc = new Scanner(System.in);
    int[] num = new int[4];
    int x = sc.nextInt();
    int ans_ok = 0;
    int ans_bat = 0;

    num[0] = x / 1000;
    t_much = x % 1000;
    num[1] = t_much / 100;
    t_much = t_much % 100;
    num[2] = t_much / 10;
    t_much = t_much % 10;
    num[3] = t_much;
    if(num[0] == ans[0] && num[1] == ans[1] && num[2] == ans[2] && num[3] == ans[3]){
    System.out.println("OK");
    }else{
    for(int i = 0; i < 4; i++){
    if(num[i] == ans[i]){
    ans_ok += 1;
    System.out.println(ans_ok + "つ正解");
    }else{
    ans_bat += 1;
    System.out.println(ans_bat + "つ間違い");
    }
    }
    }
    }while(num[0] == ans[0] && num[1] == ans[1] && num[2] == ans[2] && num[3] == ans[3]);

    キャンセル

  • 2015/06/07 11:53

    numはdoブロックの中のローカル変数で,whileで継続条件をチェックする時点でブロックから抜けているためです.
    numをdoブロックの前で宣言するか,while(true)でループして正解した時にbreakで抜けるかする必要があります.
    それと正解数をカウントする以上,長ったらしい
    if(num[0] == ans[0] && num[1] == ans[1] && num[2] == ans[2] && num[3] == ans[3])
    というのを使わずに,ans_ok==4でチェックすればいいのでは?

    キャンセル

  • 2015/06/07 11:55 編集

    if(num[1] == ans[0] && num[2] == ans[1] && num[3] == ans[2] && num[4] == ans[3]) {
    System.out.println("OK");
    } else {
    for(int i = 0; i < 4; i++){
    if(num[i + 1] == ans[i]) {
    ans_ok += 1;
    }else{
    ans_bat += 1;
    }
    }
    System.out.println(ans_ok + "つ正解 " + ans_bat + "つ間違い");
    }
    とすれば良いと思います。

    > ... なぜ正解の部分が処理されないのでしょうか? ...
    そのような疑問をもったら、自分でプログラムの挙動をしらべて修正をすすめていくことが大事です。
    コードをよんだだけはわからなければ、デバッグでステップ実行するとか、print 文を埋め込んでみるとか。
    いまの場合だと、
      ...
      System.out,println( "i=" + i + ", num[i]=" + num[i] + ", ans[i] =" + ans[i])")
      if(num[i] == ans[i]){
      ...
    のような文を追加して実行してみると、num[i] == ans[i]) がいつも 成り立っていないことがわかると思います。
    (print 文は融通がきかないので、 debug での step 実行方法を習得した方がよいです。)

    キャンセル

0

こんにちは。

答えではなくヒントといいますか手引きをしてほしいです 

とのことなので、現状のコードの修正を最小限にする方針でいくとして
例えば、以下のようなメソッドを追加するというのはいかがでしょうか。
private static int countMatches(int[] a, int b[])
このメソッドは、整数の配列 a と配列 b を比較して、同じ位置に同じ
数がある要素の数を返します。たとえば
a が、{ 1, 2, 3, 4 } で、b が { 1, 5, 2, 4 } のときに

countMatches(a, b)

は、2 を返すようなものです。countMatchesメソッドをこのように作成して、
このメソッドの返す値を◯の数にするという方針です。

main の中に直接、countMatchesの中でやることを書かないで
メソッドとして切り分けてることで、どこで何をやるかを切り分
けます。

このようなcountMatchesを作成して、a として最初にランダムに
生成した値の配列を渡し、b としてScannerで取得した値の配列
を渡します。

ただ、もしこれでいくなら、現状、num を長さ5の配列にして
num[0]にユーザーが入力した値を入れ、num[1]からnum[4]で
1000の位から1の位までを入れていますが、これを改めて、
現状のnum[0]に変わる変数をひとつ追加して、(たとえば、inputValue とか。)
num[0]からnum[3]までに1000の位から1の位までを入れて

countMatches(ans, num)

として一致している数字の数を求めます。

countMatchesメソッドの詳細は、
答えではなくヒント
とのことなので書かないでおきます。

以上が「こうしてみては?」というひとつの考え方です。

以下は蛇足ですが、現状のソースをみて少し気になった部分です。

(1) クラス名が hitblow となっていますが、クラス名は先頭を
  大文字にするのが通例となっています。
  なので、Hitblow とかHitBlow とする方が良いかと思います。

(2)余りを入れておく変数が t_much となっていますが、
 割り算の余りは英語で

 remainder

 ですので、このまま変数名として使って、さきほど挙げた
 inputValue
 と併せて、

 int remainder = inputValue % 1000;
 
 とするのがよいと思います。
 少なくとも、 t_much という名前からは、これが
 割り算の余りであることが読み取れません。

 変数やメソッドなどの名前にこだわりを持つ習慣をつけると、
 今後プログラミングを続けていくときに、綺麗なコードを
 書くための良い下地になっていきます。

 ちなみに私は、この回答を書いているときに
 追加することを提案したメソッド名を
  countMatch
 にするのか、
  countMatches 
 にするのか、はたまた
  matchCount
 にするのかで、少し悩みました。

以上ご参考になれば幸いです。

追記(1)
(以下の懸案事項ですが、もし、すでに認識されている問題なら、すみません。)
現状のコードだと、ユーザーからの入力も4桁であることを前提にして
しまっているように思えますが、4桁よりも少ない桁の数(たとえば、
100とか)または大きい桁の数字(たとえば、9999999)を入力された場合に、
どのように対応するのかも、要検討かもしれませんね。

たとえば、ランダム生成したans が 1234 のときに、ユーザーからの入力が
134 だったとすると、

・両者をいわば"1234"と"134"という文字列と考えて、
 先頭からの同じ位置の数字が一致するものを数えたい。

  =>この例では、"1"だけが一致しているので、一致しているものの数は1

なのか

・ユーザーから入力された134は、整数の値の百三十四であるとして
 1234と134の各位の数字が一致しているものの数を数えたい。

  => この例では、十の位の3と、一の位の4が一致するので、
   一致しているものの数は2

なのかで、書くべきプログラムも変わってきます。


今回の数あてプログラムのようなものでも、考えるべきことは
たくさんありますね。がんばってください!


追記(2)

ランダム生成する数も、入力される数も4桁と決まっていて、
それら2つの4桁の数について、同じ位に同じ数字がいくつ
あるかを数えることが目的で、それを果たせればそれぞれの
位の数字を配列にする必要が特にないのであれば、
以下のメソッド

 int countMatchedDigits(int a, int b)

のようにシンプルに書けます。

public class Hitblow2 {

    // 2つの4桁の整数、a と bについて、同じ桁に同じ数が
    // いくつあるかを返す。
    private static int countMatchedDigits(int a, int b)
    {
        int count = 0;
        
        for ( int divisor = 1000; divisor >= 1; divisor /= 10 ) {
            if ( a / divisor == b / divisor) 
                count ++;
            a %= divisor;
            b %= divisor;
        }
        
        return count;
    }
    
    // 上記のメソッドのテスト
    public static void main(String[] args)
    {
        System.out.println(countMatchedDigits(1234, 1234));    // 4と表示される。
        System.out.println(countMatchedDigits(1234, 2345));    // 0と表示される。
        System.out.println(countMatchedDigits(1234, 9234));  // 3と表示される。
    }
    
}

以上、参考になれば幸いです。


追記(3)

もう1つ、
「4桁の数字が2つあったときに、同じ位の数字が一致しているかを判定する方法」
を思いついたので、挙げておきますね。

まず前提として、今回の場合、ランダム生成する4桁の数字は、各桁が
ans[i] = (int)(Math.random() * 9) + 1;  
という作成のされ方をするので、どの桁も1以上9以下ですので、
数字0を含まない4桁の整数として、aとbを検証の対象とします。

このとき、

(1) aとbを文字列として連結した文字列s を作成します。
  たとえば、
  a=1234, b=1784 なら、s="12341784" です。

(2)このように s を作ると、 a と b の千の位の数字が一致するか
  どうかを判定するには、文字列 s の一番左の数字と、左から
  5番目の数字が一致するかどうかを調べればよいことになります。

(3) 上記(2)を調べるには、文字列s が正規表現

^([1-9])[1-9]{3}\1[1-9]{3}$

にマッチするかどうかを調べればよいです。
この正規表現は、
「1以上9以下の数字だけで構成された、長さ8の文字列で、
 かつ、一番左の数字と左から5番目の数字が同じもの」
を表しています。

たとえば、
  • a=1234, b=1784 のときの s="12341784" はこの正規表現にマッチしますが、
  • a=5678, b=9876 のときの s="56789876" はこの正規表現にマッチしません。

(4) 同様に、aとbの百の位、十の位、一の位の数字が一致するかどうかを
判定するための、sに対する正規表現を、各々作ることができて、これら4つの
正規表現のうち、s にマッチするものの個数が、aとbとで数字が同じ桁の個数
になります。


正規表現の学習はこれからかもしれませんが、こんな感じにも
書けますということで、参考に留めて頂ければ幸いです。

 
 



 

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

 if(num[1] == ans[0] && num[2] == ans[1] && num[3] == ans[2] && num[4] == ans[3]){
            System.out.println("OK");
            }else{
            System.out.println("bat");
            }

ここをfor文にすると良いと思います。

for()
{
 if()
  ○++;
 else
  ×++;
}

このようにすると良いのではないでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • Java

    13505questions

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