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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio Code

Visual Studio Codeとは、Microsoft社が開発したマルチプラットフォーム対応のテキストエディタです。Visual Studioファミリーの一員でもあります。拡張性とカスタマイズ性が高く、テキストエディタでありながら、IDEと遜色ない機能を備えることができます。

Q&A

解決済

2回答

608閲覧

2人対戦オセロのループの二回目が正常に動作しない

Ujiyasu

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio Code

Visual Studio Codeとは、Microsoft社が開発したマルチプラットフォーム対応のテキストエディタです。Visual Studioファミリーの一員でもあります。拡張性とカスタマイズ性が高く、テキストエディタでありながら、IDEと遜色ない機能を備えることができます。

0グッド

0クリップ

投稿2023/03/17 10:43

実現したいこと

  • 2人対戦オセロを完成させたい。

前提

C言語で二人対戦オセロを作っています。
main関数で手番の管理などの実装中に以下の問題が発生しました。

発生している問題・エラーメッセージ

main関数のループで白の手番のときproc==1のboard_surface()関数以降のプログラムが実行されません。

該当のソースコード

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <stdbool.h> 4 5const int BLACK = 1; 6const int WHITE = -1; 7const int EMPTY = 0; 8 9int board[8][8]={ 10 {0,0,0,0,0,0,0,0}, 11 {0,0,0,0,0,0,0,0}, 12 {0,0,0,0,0,0,0,0}, 13 {0,0,0,0,0,0,0,0}, 14 {0,0,0,0,0,0,0,0}, 15 {0,0,0,0,0,0,0,0}, 16 {0,0,0,0,0,0,0,0}, 17 {0,0,0,0,0,0,0,0} 18}; 19 20void board_init(){ 21 for(int y=0;y<8;y++){ 22 for(int x=0;x<8;x++){ 23 board[y][x]=EMPTY; 24 } 25 } 26 board[3][4]=BLACK; 27 board[4][3]=BLACK; 28 board[3][3]=WHITE; 29 board[4][4]=WHITE; 30} 31 32void board_surface(){ 33 printf(" "); 34 for(int xx=0;xx<8;xx++){ 35 printf(" %d ",xx); 36 } 37 printf("\n"); 38 for(int y=0;y<8;y++){ 39 printf("%d ",y); 40 for(int x=0;x<8;x++){ 41 if(board[y][x]==BLACK){ 42 printf(" ● "); 43 } 44 else if(board[y][x]==WHITE){ 45 printf(" ○ "); 46 } 47 else{ 48 printf(" - "); 49 } 50 } 51 printf("\n"); 52 } 53} 54 55bool can_return(int x,int y,int color){ 56 int total=0; 57 if(board[y][x]>0){ 58 return false; 59 } 60 for(int dx=-1;dx<2;dx++){ 61 for(int dy=-1;dy<2;dy++){ 62 int k=0; 63 int sx=x; 64 int sy=y; 65 if(total>0){ 66 return true; 67 } 68 while(true){ 69 sx+=dx; 70 sy+=dy; 71 if(sy<0 || sy>7 || sx<0 || sx>7){ 72 break; 73 } 74 75 if(board[sy][sx]==EMPTY){ 76 break; 77 } 78 79 if(board[sy][sx]==-color){ 80 k+=1; 81 } 82 83 if(board[sy][sx]==color){ 84 total+=k; 85 break; 86 } 87 } 88 } 89 } 90 if(total>0){ 91 return true; 92 } 93 return false; 94} 95 96void put_stone(int x,int y,int color){ 97 board[y][x]=color; 98 for(int dx=-1;dx<2;dx++){ 99 for(int dy=-1;dy<2;dy++){ 100 int k=0; 101 int sx=x; 102 int sy=y; 103 while(true){ 104 sx+=dx; 105 sy+=dy; 106 if(sx<0 || sx>7 || sy<0 || sy>7){ 107 break; 108 } 109 110 if(board[sy][sx]==EMPTY){ 111 break; 112 } 113 114 if(board[sy][sx]==-color){ 115 k+=1; 116 } 117 118 if(board[sy][sx]==color){ 119 for(int i=0;i<k;i++){ 120 sx-=dx; 121 sy-=dy; 122 board[sy][sx]=color; 123 } 124 break; 125 } 126 } 127 } 128 } 129} 130 131void put_input(int*px,int*py,int color){ 132 do{ 133 printf("横 縦の形で入力:"); 134 scanf("%d %d",px,py); 135 }while(can_return(*px,*py,color)==false); 136} 137 138void can_mark(int color){ 139 printf(" "); 140 for(int xx=0;xx<8;xx++){ 141 printf(" %d ",xx); 142 } 143 printf("\n"); 144 145 for(int y=0;y<8;y++){ 146 printf("%d ",y); 147 for(int x=0;x<8;x++){ 148 if(board[y][x]==BLACK){ 149 printf(" ○ "); 150 } 151 else if(board[y][x]==WHITE){ 152 printf(" ● "); 153 } 154 else if(can_return(x,y,color)==true){ 155 printf(" * "); 156 } 157 else{ 158 printf(" - "); 159 } 160 } 161 printf("\n"); 162 } 163} 164 165bool dis_pass(int color){ 166 int cn=0; 167 for(int x=0;x<8;x++){ 168 for(int y=0;y<8;y++){ 169 cn+=can_return(x,y,color); 170 } 171 } 172 if(cn!=0){ 173 return true; 174 } 175 else{ 176 return false; 177 } 178} 179 180int win_color(){ 181 int bn=0; 182 int wn=0; 183 for(int x=0;x<8;x++){ 184 for(int y=0;y<8;y++){ 185 if(board[y][x]==BLACK){ 186 bn++; 187 } 188 else if(board[y][x]==WHITE){ 189 wn++; 190 } 191 } 192 } 193 if(bn==wn){ 194 return 3; 195 } 196 else if(bn>wn){ 197 return BLACK; 198 } 199 else{ 200 return WHITE; 201 } 202} 203 204int main(void){ 205 int proc=0; 206 int turn=0; 207 int px,py; 208 int color[2]={BLACK,WHITE}; 209 while(true){ 210 switch(proc){ 211 case 0: 212 board_init(); 213 proc=1; 214 case 1: 215 can_mark(color[turn]); 216 put_input(&px,&py,color[turn]); 217 put_stone(px,py,color[turn]); 218 board_surface(); 219 proc=2; 220 case 2: 221 turn=1-turn; 222 if(dis_pass(color[turn])==false){ 223 turn=1-turn; 224 if(dis_pass(color[turn])==false){ 225 switch(win_color()){ 226 case 3: 227 printf("引き分け"); 228 proc=0; 229 case BLACK: 230 printf("黒の勝ち"); 231 proc=0; 232 case WHITE: 233 printf("白の勝ち"); 234 proc=0; 235 } 236 }else{ 237 proc=1; 238 } 239 }else{ 240 proc=1; 241 } 242 } 243 } 244 return 0; 245}

試したこと

board_surface()関数の前にproc=2にすると、proc変数は2になりましたが相変わらずboard_surface()以降のプログラムが実行されません。

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

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

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

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

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

jimbe

2023/03/17 11:15 編集

「実行されない」というのはどうやって確認したのでしょうか。 最初の黒の番で縦2横3と入力すると白だった横4縦3と横3縦4が黒になって、黒だった横4縦4が白くなって、それだけで全然まともに動いていません。 board には BLACK(1), WHITE(-1) が入るのに can_return のしょっぱなで if(board[y][x]>0){ return false; } はダメなのでは。
Ujiyasu

2023/03/17 11:41

気づきませんでした。おかしいですね。 if(board[y][x]>0){ return false; } これ確認してみます
Ujiyasu

2023/03/18 11:48

if(board[y][x]!=0){ return false; } にしたら正常に動作しました。ありがとうございます
guest

回答2

0

解決されたようですので、こちらで弄って見たコードを載せておきます。
「置けるか」チェックをあちこちでされていたのを、 board に(石がまだ無い場合)8方向分のビット情報として保持するようにすることで、表示や置く処理でチェックを簡素化しています。
turn と color は同じ意味ですので turn に統一、チェック処理に合わせて 1=黒, 2=白です。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define SIZE 8 6 7#define BLACK 1 8#define WHITE 2 9#define nextTurn(turn) ((turn) ^ 3) 10#define toString(turn) ((turn)==BLACK ? "黒" : "白") 11 12int board[SIZE][SIZE]; //1以上=BLACK/WHITE, 0以下=フラグ群(ビットフィールド:あるターンにおいて8方向それぞれにひっくり返せる石があるか) 13#define inboard(y,x) (0<=(y) && (y)<SIZE && 0<=(x) && (x)<SIZE) 14#define isPlaced(square) ((square) > 0) 15#define canPlace(square) ((square) < 0) 16 17char *images[] = { "-","●","○","*" }; 18#define toImage(square) (images[(square)<0 ? 3 : (square)]) 19 20//8方向変化値 21typedef struct { 22 int y, x; 23} Delta; 24Delta d[] = { 25 {-1,-1},{-1,0},{-1,1}, 26 { 0,-1}, { 0,1}, 27 { 1,-1},{ 1,0},{ 1,1} 28}; 29int dlen = sizeof(d)/sizeof(d[0]); 30 31void init() { 32 memset(board, 0, sizeof(board)); 33 board[SIZE/2-1][SIZE/2] = BLACK; 34 board[SIZE/2] [SIZE/2-1] = BLACK; 35 board[SIZE/2-1][SIZE/2-1] = WHITE; 36 board[SIZE/2] [SIZE/2] = WHITE; 37} 38 39int checkLines(int y, int x, int turn) { 40 int flags = 0; //下位8ビットが8方向に対応 41 for(int i=0; i<dlen; i++) { 42 for(int sx=x+d[i].x, sy=y+d[i].y, c=0; inboard(sy,sx) && isPlaced(board[sy][sx]); sx+=d[i].x, sy+=d[i].y, c++) { 43 if(board[sy][sx] == turn) { 44 if(c > 0) flags |= 1<<i; //置けるならフラグセット 45 break; 46 } 47 } 48 } 49 board[y][x] = flags * -1; //0以下の数にして保存 50 return flags; 51} 52 53void changeLines(int y, int x, int turn) { 54 int flags = board[y][x] * -1; //0以上に戻す 55 board[y][x] = turn; 56 for(int i=0; i<dlen; i++) { 57 if(!(flags & (1<<i))) continue; //フラグが立っていない 58 for(int sx=x+d[i].x, sy=y+d[i].y; board[sy][sx]!=turn; sx+=d[i].x, sy+=d[i].y) { 59 board[sy][sx] = turn; 60 } 61 } 62} 63 64#define GAMEEND -1 65 66int check(int turn) { 67 int count = 0; //置ける個所数 68 int space = 0; //空き数 69 for(int y=0; y<SIZE; y++) { 70 for(int x=0; x<SIZE; x++) { 71 if(isPlaced(board[y][x])) continue; //石がある所はスキップ 72 space ++; 73 if(checkLines(y, x, turn) != 0) count++; 74 } 75 } 76 return space == 0 ? GAMEEND : count; 77} 78 79void print() { 80 printf(" "); 81 for(int x=0; x<SIZE; x++) printf(" %d ", x); 82 printf("\n"); 83 84 for(int y=0; y<SIZE; y++) { 85 printf("%d ", y); 86 for(int x=0; x<SIZE; x++) { 87 printf(" %s ", toImage(board[y][x])); 88 //if(board[y][x] > 0) printf(" %s ", images[board[y][x]]); 89 //else printf(" %02x ", board[y][x]*-1); 90 } 91 printf("\n"); 92 } 93} 94 95void input(int turn) { 96 int x, y; 97 do{ 98 printf("%sの番 \"横 縦\"の形で入力:", toString(turn)); fflush(stdout); 99 scanf("%d %d", &x, &y); 100 } while(!canPlace(board[y][x])); 101 102 changeLines(y, x, turn); 103} 104 105void judge() { 106 int bc=0, wc=0; 107 for(int y=0; y<SIZE; y++) { 108 for(int x=0; x<SIZE; x++) { 109 if(board[y][x] == BLACK) bc++; 110 else if(board[y][x] == WHITE) wc++; 111 } 112 } 113 printf("*** %s ***\n", bc>wc?"黒の勝ち":bc<wc?"白の勝ち":"引き分け"); 114} 115 116int main(void) { 117 while(1) { 118 printf("-------------------------\n"); 119 init(); 120 for(int turn=BLACK, skip=0, count; (count=check(turn))!=GAMEEND; turn=nextTurn(turn)) { 121 if(count == 0) { 122 printf("%s パス\n", toString(turn)); fflush(stdout); 123 if(++skip >= 2) break; //空きは有ってもどちらも置けない 124 continue; 125 } 126 skip = 0; 127 print(); 128 input(turn); 129 } 130 print(); 131 judge(); 132 } 133}

投稿2023/03/18 13:48

編集2023/03/19 09:43
jimbe

総合スコア12545

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

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

0

自己解決

jimbeさんの回答を元に解決できました

投稿2023/03/18 11:49

Ujiyasu

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問