回答編集履歴

8

コード内コメントの誤字

2022/12/29 07:30

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -130,7 +130,7 @@
130
130
  //チェック
131
131
  for(int i = 0; i < n + n + 2; i++) {
132
132
  if(count[i] == n) {
133
- match_over = 1; //決着が着いた. ここで turn のループを break しなくても、 trun のループ条件に引っ掛かって終わってくれる.
133
+ match_over = 1; //決着が着いた. ここで turn のループを break しなくても、 turn のループ条件に引っ掛かって終わってくれる.
134
134
  break;
135
135
  }
136
136
  }

7

コードのフォーマットの修正

2022/12/16 03:01

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -73,7 +73,7 @@
73
73
  */
74
74
  char player = ' '; //元 kigou
75
75
  int match_over = 0; //決着が着く(どちらかが勝つ)と 1
76
- for(int turn = 0; turn < n*n && match_over == 0; turn++) { //turn は元 while_count. ターンが過ぎるか決着が着いたら終わる. [5.ターンを進める](turn++) を含む
76
+ for(int turn = 0; turn < n * n && match_over == 0; turn++) { //turn は元 while_count. ターンが過ぎるか決着が着いたら終わる. [5.ターンを進める](turn++) を含む
77
77
  printf("\n%d周目始まる\n", turn);
78
78
 
79
79
  //このターンのプレイヤー
@@ -108,7 +108,7 @@
108
108
  //[4.勝敗の判断] 縦横斜めが同じかどうかをループで判断。各カウントを一度に行う。
109
109
  int count[n + n + 2]; //[0~n-1]:水平, [n~n+n-1]:垂直, [n+n~n+n+1]:斜め
110
110
  //クリア
111
- for(int i = 0; i < n+n+2; i++) {
111
+ for(int i = 0; i < n + n + 2; i++) {
112
112
  count[i] = 0;
113
113
  }
114
114
  //カウント

6

関数引数も VLA 化

2022/12/15 05:31

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -38,11 +38,10 @@
38
38
  #include <stdio.h>
39
39
 
40
40
  //2箇所で表示するため、共通処理として関数化
41
- //board は 2 次元配列だが可変サイズのため 1 次元として扱う.
42
- void print_board(char *board, int n) {
41
+ void print_board(int n, char board[n][n]) {
43
- for(int y = 0, i = 0; y < n; y ++) {
42
+ for(int y = 0; y < n; y ++) {
44
- for(int x = 0; x < n; x++, i++) {
43
+ for(int x = 0; x < n; x++) {
45
- printf("%c", board[i]);
44
+ printf("%c", board[y][x]);
46
45
  }
47
46
  printf("\n");
48
47
  }
@@ -61,7 +60,7 @@
61
60
  board[i][j] = '_';
62
61
  }
63
62
  }
64
- print_board(board, n);
63
+ print_board(n, board);
65
64
 
66
65
  /*
67
66
  <del>while</del>forの中でやること
@@ -104,7 +103,7 @@
104
103
 
105
104
  //[3.◯xを記入して、ボードを表示]
106
105
  board[y][x] = player;
107
- print_board(board, n);
106
+ print_board(n, board);
108
107
 
109
108
  //[4.勝敗の判断] 縦横斜めが同じかどうかをループで判断。各カウントを一度に行う。
110
109
  int count[n + n + 2]; //[0~n-1]:水平, [n~n+n-1]:垂直, [n+n~n+n+1]:斜め

5

コード追加

2022/12/15 05:19

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -29,3 +29,120 @@
29
29
  }
30
30
  ```
31
31
  右上から左下になっていますか? 数えてますか?
32
+
33
+ ---
34
+ 大体整ったようですので、さらに纏めてみた感じのを提示させて頂きます。
35
+ 共通として表示部分だけを関数化していますが、他の部分は質問のコードに似せる感じにしています。
36
+ (Windows/Cygwin/Eclipse で確認しています)
37
+ ```c
38
+ #include <stdio.h>
39
+
40
+ //2箇所で表示するため、共通処理として関数化
41
+ //board は 2 次元配列だが可変サイズのため 1 次元として扱う.
42
+ void print_board(char *board, int n) {
43
+ for(int y = 0, i = 0; y < n; y ++) {
44
+ for(int x = 0; x < n; x++, i++) {
45
+ printf("%c", board[i]);
46
+ }
47
+ printf("\n");
48
+ }
49
+ printf("\n");
50
+ }
51
+
52
+ int main() {
53
+ int n;
54
+ printf("マスの数を入力してください:");
55
+ scanf("%d", &n);
56
+
57
+ //ボードを作る
58
+ char board[n][n];
59
+ for(int i = 0; i < n; i++) {
60
+ for(int j = 0; j < n; j++) {
61
+ board[i][j] = '_';
62
+ }
63
+ }
64
+ print_board(board, n);
65
+
66
+ /*
67
+ <del>while</del>forの中でやること
68
+ 1.◯を入力する(◯スタート。偶数回目であれば◯、奇数回目であればXを入力。1回目からスタート?それとも0回目?調べる)
69
+ 2.◯の場所が(A)範囲内で(B)空白なのかどうか確認
70
+ 3.◯を記入して、ボードを表示
71
+ 4.勝敗を判断
72
+ 5.ターンを進める
73
+ <del>6.1に戻る</de> ← ループの中でやることでは無いのでこれは不要, 逆にループをいつ終わるのかを書いておく必要がある
74
+ */
75
+ char player = ' '; //元 kigou
76
+ int match_over = 0; //決着が着く(どちらかが勝つ)と 1
77
+ for(int turn = 0; turn < n*n && match_over == 0; turn++) { //turn は元 while_count. ターンが過ぎるか決着が着いたら終わる. [5.ターンを進める](turn++) を含む
78
+ printf("\n%d周目始まる\n", turn);
79
+
80
+ //このターンのプレイヤー
81
+ if(turn % 2 == 0) {
82
+ player = 'O';
83
+ } else {
84
+ player = 'X';
85
+ }
86
+
87
+ //[1.入力する]+[2.入力チェック]
88
+ int x, y;
89
+ while(1) {
90
+ printf("x座標を0〜%dから入力してください:", n - 1);
91
+ scanf("%d", &x);
92
+ printf("y座標を0〜%dから入力してください:", n - 1);
93
+ scanf("%d", &y);
94
+
95
+ if(x < 0 || x > n - 1 || y < 0 || y > n - 1) {
96
+ printf("入力された値が不正です。\n");
97
+ } else if(board[y][x] != '_') {
98
+ printf("そのマスは埋まってます。\n");
99
+ } else {
100
+ printf("\n");
101
+ break; //エラーでは無い=正常な入力なら入力ループを抜ける
102
+ }
103
+ }
104
+
105
+ //[3.◯xを記入して、ボードを表示]
106
+ board[y][x] = player;
107
+ print_board(board, n);
108
+
109
+ //[4.勝敗の判断] 縦横斜めが同じかどうかをループで判断。各カウントを一度に行う。
110
+ int count[n + n + 2]; //[0~n-1]:水平, [n~n+n-1]:垂直, [n+n~n+n+1]:斜め
111
+ //クリア
112
+ for(int i = 0; i < n+n+2; i++) {
113
+ count[i] = 0;
114
+ }
115
+ //カウント
116
+ for(int y = 0; y < n; y++) {
117
+ for(int x = 0; x < n; x++) {
118
+ if(board[y][x] != player) {
119
+ continue; //条件に合わない場合に早々にスキップすることで、コードのインデントを深くしない(下の方で'}'が並ぶと分かり難くなる)
120
+ }
121
+ count[y]++; //水平
122
+ count[n + x]++; //垂直
123
+ if(x == y) { //斜め(\)
124
+ count[n + n]++;
125
+ }
126
+ if(n - 1 - x == y) { //斜め(/)
127
+ count[n + n + 1]++;
128
+ }
129
+ }
130
+ }
131
+ //チェック
132
+ for(int i = 0; i < n + n + 2; i++) {
133
+ if(count[i] == n) {
134
+ match_over = 1; //決着が着いた. ここで turn のループを break しなくても、 trun のループ条件に引っ掛かって終わってくれる.
135
+ break;
136
+ }
137
+ }
138
+ printf("\n%d周目終わり\n", turn);
139
+ }
140
+
141
+ if(match_over == 1) {
142
+ printf("%cの勝ちです!\n", player);
143
+ } else {
144
+ printf("引き分けです\n");
145
+ }
146
+ return 0;
147
+ }
148
+ ```

4

誤字

2022/12/14 16:37

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -28,4 +28,4 @@
28
28
  if(board[n - 1 - a][n - 1 - a] == kigou);
29
29
  }
30
30
  ```
31
- 上から下になっていますか? 数えてますか?
31
+ 上から下になっていますか? 数えてますか?

3

追加

2022/12/14 16:36

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -20,3 +20,12 @@
20
20
  break;
21
21
  }
22
22
  ```
23
+
24
+ ついでみたいになりますが
25
+ ```c
26
+ count = 0;
27
+ for (a = 0; a < n; a++){//右上から左下に向かってチェックする。countで数えてその回数とnが同じであれば勝ちになるはず。
28
+ if(board[n - 1 - a][n - 1 - a] == kigou);
29
+ }
30
+ ```
31
+ 左上から右下になっていますか? 数えてますか?

2

追加

2022/12/14 16:30

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -1,6 +1,9 @@
1
1
  例えば以下の判定部分を見てみましょう。
2
2
  最初の for には「横方向の行をn行分チェック」と書かれています。
3
3
  本当に n 行分チェックが実行されているでしょうか? count の変化と if による判定は妥当でしょうか?
4
+
5
+ プログラムが想定通りに動かない時、一番面倒なのが作った本人の思い込みです。考えた通りに動くように書いたはず・つもりですので、大量の「わ」の中に1つだけ「ね」があっても分からないみたいに(まぁ"ね"があると分かっているだけで難易度は相当下がりますが)、細かい所の違いが見えてきません。
6
+ 一旦頭をリセットして、他人の目・頭で知らないコードを解析するように少しずつ動作を調べていくことをやってみるのも必要になりまず。
4
7
 
5
8
  ```c
6
9
  int count = 0;

1

修正

2022/12/14 16:18

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -1,8 +1,10 @@
1
1
  例えば以下の判定部分を見てみましょう。
2
2
  最初の for には「横方向の行をn行分チェック」と書かれています。
3
- 本当に n 行分チェックが実行されているでしょうか?
3
+ 本当に n 行分チェックが実行されているでしょうか? count の変化と if による判定は妥当でしょうか?
4
4
 
5
5
  ```c
6
+ int count = 0;
7
+
6
8
  for(y = 0; y < n; y++){//横方向の行をn行分チェック。countで数えてその回数とnが同じであれば勝ちになるはず。
7
9
  for(x = 0; x < n; x++){
8
10
  if(board[y][x] == kigou){//あとでkigouに変える