teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

追加

2018/06/24 17:38

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -84,4 +84,42 @@
84
84
  a[i] = a[j];
85
85
  a[j] = temp;
86
86
  }
87
+ ```
88
+
89
+ ### Hit,Blowの判定の改善
90
+ ```java
91
+ private boolean checkHitAndBlow(String[] cpuNumArray, String[] playerNumArray){
92
+
93
+ int hitCount = 0;
94
+ int blowCount = 0;
95
+
96
+ // 面倒なんで重複チェックはSetに任せた
97
+ boolean unique = new HashSet<String>(Arrays.asList(playerNumArray)).size() == MAX_LENGTH;
98
+
99
+ //数字のチェック
100
+ if (unique) {
101
+ for(int i = 0; i < MAX_LENGTH; i++){
102
+ for(int j = 0; j < MAX_LENGTH; j++){
103
+ if(playerNumArray[i].equals(cpuNumArray[j])){
104
+ if (i == j) hitCount++;
105
+ else blowCount++
106
+ break;
107
+ }
108
+
109
+ }
110
+ }
111
+ } else {
112
+ for (int i = 0; i < MAX_LENGTH; i++) {
113
+ if (playerNumArray[i].equals(cpuNumArray[j])
114
+ hitCount++;
115
+ }
116
+ }
117
+
118
+ System.out.println(hitCount + " Hit " + blowCount + "Blow");
119
+
120
+ if(hitCount == MAX_LENGTH){
121
+ return true;
122
+ }
123
+ return false;
124
+ }
87
125
  ```

3

追加

2018/06/24 17:38

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -8,7 +8,8 @@
8
8
  間違いでした。詳細は後述
9
9
 
10
10
  ### 追記に対して
11
+ ####cpuNumArrayメソッドについて
11
- まず、cpuNumArrayメソッドについて。(メソッド名は小文字始まりが慣例なので修正。ガタガタインデントも修正。)
12
+ メソッド名は小文字始まりが慣例なので修正。ガタガタインデントも修正。
12
13
 
13
14
  ```java
14
15
  private String[] cpuNumArray(){
@@ -43,8 +44,44 @@
43
44
  }
44
45
  ```
45
46
  ムダなループがあったりする以外はOKかと。
46
-
47
- つぎに、blowカウントについてはコメントの間違いでした。
47
+ ####hitカウント、blowカウントについて
48
+ 前の回答の間違いでした。
48
49
  「重複=0blow」ならば、きちんと重複をチェックする必要があります。
49
50
 
50
- 3Hitの理由は、1桁目をcpuの配列の0番目ではなく1番目に入れているから。
51
+ 3Hitの理由は上記コメントの通り、1桁目をcpuの配列の0番目ではなく1番目に入れているから。
52
+ 例えばコメントのように5697と表示されたときは、実は次のような流れになっています。
53
+ 0. 最初の3が配列の1番目に格納。CpuNumの中身は{null, "5", null, null}
54
+ 0. 次の6が配列の1番目に格納。CpuNumの中身は{null, "6", null, null}
55
+ 0. その後、9と7がそれぞれ2番目、3番目に格納され、CpuNumの中身は{null, "6", "9", "7"}
56
+ 0. 入力された5697に対しては、**blow判定が1ループでbreakしてしまうため、最初の5としか比較できない。**(ここは本当はifの中でbreakしてというつもりだった)
57
+ 5はCpuNumに入っていないため、blowは0になる。
58
+ 0. 最初の5にhit判定ができず(nullとの比較のため)、3hit止まり。blowは3回引かれ、‐3blowとなる。
59
+
60
+ ### LinkedList不要
61
+ フィッシャー・イェーツ法という、効率的なシャッフルアルゴリズムを利用すれば、LinkedListを作らなくても桁重複なしの乱数が作れます。
62
+ ```java
63
+ private String[] cpuNumArray() {
64
+ String[] cpuNum = new String[MAX_LENGTH];
65
+ int index = (int)(Math.random() * NUM_ARRAY.length);
66
+ switchElem(NUM_ARRAY, index, NUM_ARRAY.length - 1);
67
+ if (NUM_ARRAY[NUM_ARRAY.length - 1].equals("0")){
68
+ index = (int)(Math.random() * (NUM_ARRAY.length - 1));
69
+ switchElem(NUM_ARRAY, index, NUM_ARRAY.length - 1);
70
+ }
71
+ cpuNum[0] = NUM_ARRAY[NUM_ARRAY.length - 1];
72
+
73
+ for (int i = 1; i < MAX_LENGTH; i++) {
74
+ index = (int)(Math.random() * (NUM_ARRAY.length - i));
75
+ cpuNum[i] = NUM_ARRAY[index];
76
+ switchElem(NUM_ARRAY, index, NUM_ARRAY.length - 1 - i);
77
+ }
78
+ return cpuNum;
79
+ }
80
+
81
+ private void switchElem(String[] a, int i, int j) {
82
+ if (i == j) return;
83
+ String temp = a[i];
84
+ a[i] = a[j];
85
+ a[j] = temp;
86
+ }
87
+ ```

2

追加

2018/06/24 03:20

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -4,7 +4,8 @@
4
4
 
5
5
  > 入力値は重複させないようにすること。(0blowと表示)
6
6
 
7
- これも簡単。blowCountが増えた時点でbreakしてしまえばいい。
7
+ ~~これも簡単。blowCountが増えた時点でbreakしてしまえばいい。~~
8
+ 間違いでした。詳細は後述
8
9
 
9
10
  ### 追記に対して
10
11
  まず、cpuNumArrayメソッドについて。(メソッド名は小文字始まりが慣例なので修正。ガタガタインデントも修正。)
@@ -22,8 +23,13 @@
22
23
 
23
24
  //最初は1から9の乱数 floorも不要
24
25
  int num = (int)(Math.random() * 9) + 1;
26
+
27
+ //ここのインデックスは0。
28
+ //元のコードではループカウンタのiを使っており、
29
+ //1で初期化されていたため、0番目に何も入らなかった
30
+ //これが3hitの理由
25
31
  CpuNum[0] = tempList.remove(num);
26
- System.out.println(CpuNum[i]);
32
+ System.out.println(CpuNum[0]);
27
33
 
28
34
  for(int j = 1; j < 4; j++){
29
35
  int num2 = (int)(Math.random() * (10-j));
@@ -39,4 +45,6 @@
39
45
  ムダなループがあったりする以外はOKかと。
40
46
 
41
47
  つぎに、blowカウントについてはコメントの間違いでした。
42
- 「重複=0blow」ならば、きちんと重複をチェックする必要があります。
48
+ 「重複=0blow」ならば、きちんと重複をチェックする必要があります。
49
+
50
+ 3Hitの理由は、1桁目をcpuの配列の0番目ではなく1番目に入れているから。

1

追記

2018/06/20 17:19

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -4,4 +4,39 @@
4
4
 
5
5
  > 入力値は重複させないようにすること。(0blowと表示)
6
6
 
7
- これも簡単。blowCountが増えた時点でbreakしてしまえばいい。
7
+ これも簡単。blowCountが増えた時点でbreakしてしまえばいい。
8
+
9
+ ### 追記に対して
10
+ まず、cpuNumArrayメソッドについて。(メソッド名は小文字始まりが慣例なので修正。ガタガタインデントも修正。)
11
+
12
+ ```java
13
+ private String[] cpuNumArray(){
14
+
15
+ List<String> tempList = new
16
+ LinkedList<String>(Arrays.asList(NUM_ARRAY));
17
+
18
+ String[] CpuNum = new String[4];
19
+
20
+ //1回しかしないならループ不要。
21
+ //for(int i = 1; i < 2; i++){
22
+
23
+ //最初は1から9の乱数 floorも不要
24
+ int num = (int)(Math.random() * 9) + 1;
25
+ CpuNum[0] = tempList.remove(num);
26
+ System.out.println(CpuNum[i]);
27
+
28
+ for(int j = 1; j < 4; j++){
29
+ int num2 = (int)(Math.random() * (10-j));
30
+ CpuNum[j] = tempList.remove(num2);
31
+ System.out.println(CpuNum[j]);
32
+ }
33
+ //}
34
+
35
+ return CpuNum;
36
+
37
+ }
38
+ ```
39
+ ムダなループがあったりする以外はOKかと。
40
+
41
+ つぎに、blowカウントについてはコメントの間違いでした。
42
+ 「重複=0blow」ならば、きちんと重複をチェックする必要があります。