前提
NxNマスのマルバツゲームを作っています。
プレイヤー同士で対戦します。
実感としては90%ぐらいで来たと思います。
実現したいこと
詰まっている点は2つです。
- 判定方法のところのコードが間違っているのですが、それがなぜなのか全く分かりません。
- 勝負がついた時に、どのようにしてループを抜け出すのか(一応自分が終わって欲しいと思うところにbreakとは書いているのですが、下のパターン1、2の様に判定方法が間違っているせいなのかループから抜け出してくれません。)
発生している問題・エラーメッセージ
パターン1 OX_ XXO OXO x座標を0〜2から入力してください: //この様になっても終わらない。続いてしまう。さらに続けると OXO XXO OXO 引き分けです //となってしまう。 ____________________ パターン2.0 OXO XO_ OX_ //この様になっても終わらない パターン2.1 OXO XOX OXO Oの勝ちです! //パターン2.0をこの状態まで続けるとなぜか終わる。
該当のソースコード
C言語
1#include <stdio.h> 2 3int main() { 4 5 int n; 6 int while_count = 0;//全体をカウントする。これの偶奇でプレイヤー1、2を判断する。 7 printf("マスの数を入力してください:"); 8 scanf("%d", &n); 9 10 //ここからボードを作ってく 11 int x = n, y = n; 12 char board[y][x]; 13 int i, j; 14 15 for (i = 0; i < n ; i++){ 16 printf("\n"); 17 for(j = 0; j < n ; j++){ 18 printf("_ "); 19 board[i][j] = '_'; 20 } 21 } 22 printf("\n"); 23 24 /* 25 whileの中でやること 26 1.◯を入力する(◯スタート。偶数回目であれば◯、奇数回目であればXを入力。1回目からスタート?それとも0回目?調べる) 27 2.◯の場所が(A)範囲内で(B)空白なのかどうか確認 28 3.◯を記入して、ボードを表示 29 4.勝敗を判断 30 5.ターンを進める 31 6.1に戻る 32 */ 33 while(1){ 34 //1.入力する+2.入力チェック 35 do{ 36 printf("x座標を0〜%dから入力してください:", n - 1); 37 scanf("%d", &x); 38 printf("y座標を0〜%dから入力してください:", n - 1); 39 scanf("%d", &y); 40 41 if(x < 0 || x > n - 1 || y < 0 || y > n - 1){ 42 printf("入力された値が不正です。\n"); 43 }else if(board[y][x] != '_'){ 44 printf("そのマスは埋まってます。\n"); 45 } 46 }while((x < 0 || x > n - 1 || y < 0 || y > n - 1) || (board[y][x] != '_')); 47 48 //3.◯xを記入して、 49 if(while_count % 2 == 0){ 50 board[y][x] = 'O'; 51 }else{ 52 board[y][x] = 'X'; 53 } 54 55 //ボードを表示 56 for (i = 0; i < n ; i++){ 57 printf("\n"); 58 for(j = 0; j < n ; j++){ 59 printf("%c", board[i][j]); 60 } 61 } 62 printf("\n"); 63 64 //4勝敗の判断。縦横斜めが同じかどうかをループで判断引き分け(全マス埋まるも考える)。 65 char kigou; //if文を使って偶数回目であればkigou='O',奇数回目であればkigou='X'を代入 66 if(while_count % 2 == 0){ 67 kigou = 'O'; 68 }else{ 69 kigou = 'X'; 70 } 71 72 int count1 = 0; 73 for(y = 0; y < n; y++){//横方向の行をn行分チェック。countで数えてその回数とnが同じであれば勝ちになるはず。 74 count1 = 0; 75 for(x = 0; x < n; x++){ 76 if(board[y][x] == kigou){ 77 printf("count1 %d\n", count1); 78 count1++; 79 } 80 } 81 if(count1 == n){ 82 break; 83 } 84 } 85 if(count1 == n){ 86 printf("%cの勝ちです!\n", kigou); 87 break; 88 } 89 90 int count2 = 0; 91 for(x = 0; x < n; x++){//縦方向の行をn列分チェック。countで数えてその回数とnが同じであれば勝ちになるはず。 92 count2 = 0; 93 for(y = 0; y < n; y++){ 94 if(board[y][x] == kigou){ 95 printf("count2 %d\n", count2); 96 count2++; 97 } 98 } 99 if(count2 == n){ 100 break; 101 } 102 } 103 if(count2 == n){ 104 printf("%cの勝ちです!\n", kigou); 105 break; 106 } 107 108 109 int count3 = 0; 110 int a; 111 for(a = 0; a < n; a++){//左上から右下に向かってチェックする。countで数えてその回数とnが同じであれば勝ちになるはず。 112 if(board[a][a] == kigou){ 113 printf("count3 %d\n", count3); 114 count3++; 115 } 116 } 117 if(count3 == n){ 118 printf("%cの勝ちです!\n", kigou); 119 break; 120 } 121 122 int count4 = 0; 123 for (a = 0; a < n; a++){//右上から左下に向かってチェックする。countで数えてその回数とnが同じであれば勝ちになるはず。 124 if(board[n - 1 - a][a] == kigou){ 125 printf("count4 %d\n", count4); 126 count4++; 127 } 128 } 129 if(count4 == n){ 130 printf("%cの勝ちです!\n", kigou); 131 break; 132 } 133 134 if(while_count == n*n - 1){// 135 printf("引き分けです"); 136 break; 137 } 138 //5.ターンを進める 139 printf("\n%d周目終わり\n", while_count); 140 while_count++; 141 printf("\n%d周目始まる\n", while_count); 142 } 143 printf("\n"); 144 return 0; 145} 146 147
試したこと
判定方法に問題があると考えてので、76行目から125行目を変えたりして試しました。ただ自分が判定方法の何が問題なのか理解できていなかったため、何も分からなかったのが本音です。
判定方法の考え方としては、例えば76行目から86行目が横方向への判定方法なのですが、y=0(0行目)の時、二つ目のforでxを0からn-1(3x3のゲームであれば、nは2)まで動かし、if文の中でkigouが何度boardと同じなのかを数え、countの数とnが同じになれば”勝ち”となる様に考えました。
しかし実際には勝っていても終わらなかったり、引き分けと判定してしまうのです。
補足情報(FW/ツールのバージョンなど)
Macbook Air M1 2020 Ver 12.6
Xcode を使っています。
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー