前提・実現したいこと
c言語でオセロを作成中の初心者です。ひととおり全体的な枠組みは完成したのですが、うまく挙動しません。
オセロで相手のコマをひっくり返すところがうまくいってないとは思うのですが、どこを改善すればよいのかわからないので教えてほしいです。
発生している問題・エラーメッセージ
put_checkという関数の部分がおかしいのだと思いますが、自分ではどこをかえたらいいのかわからないので教えてほしいです。よろしくお願いします。 所々いらないことを書いている部分もあるとは思うのですが、とりあえずひととり動くものを作りたいです。 ↓実行結果 自分のコマ(このコードではw固定)を置く位置を入力したあと、きちんと置かれず、謎の数字が一番上に追加されます。 12345678 1........ 2........ 3........ 4...wb... 5...bw... 6........ 7........ 8........ 0 あなたのターンです。 縦方向3 横方向5 1234119678 1........ 2........ 3........ 4...wb... 5...bw... 6........ 7........ 8........
該当のソースコード
C
1#include<stdio.h> 2#include<stdlib.h> 3#include<time.h> 4#define WHITE 1 5#define BLACK 2 6char board[9][9]; 7int turn;//自分のターン 8int sentaku; 9int i_put,j_put; 10int bamen_sentaku=1; 11//char o,a;//oは敵,aは自分 12void shokika(){ 13 board[0][0]=' '; 14 for(int a=1;a<9;a++){ 15 board[0][a]=a; 16 board[a][0]=a; 17 } 18 for(int i=1;i<9;i++){ 19 for(int j=1;j<9;j++){ 20 board[i][j]='.'; 21 } 22 23 } 24 board[4][4]=board[5][5]='w';//一旦wは自分,bが敵だとする 25 board[4][5]=board[5][4]='b'; 26} 27 28void display(){ 29 30 for(int i=0;i<9;i++){ 31 for(int j=0;j<9;j++){ 32 if(j==0&&i==0){ 33 printf("%c",board[i][j]); 34 }else if(j==0||i==0){//盤面の数字の部分はint型 35 printf("%d",board[i][j]); 36 }else{ 37 printf("%c",board[i][j]); 38 } 39 } 40 printf("\n"); 41 } 42 43} 44void shouhai(){ 45 int w_number=0; 46 int b_number=0; 47 int sum=0; 48 for(int i=1;i<9;i++){ 49 for(int j=1;j<9;j++){ 50 if(board[i][j]=='w'){ 51 ++w_number; 52 }else if(board[i][j]=='b'){ 53 ++b_number; 54 } 55 } 56 } 57 if(sum==64){ 58 printf("白%d枚、黒%d枚\n",w_number,b_number); 59 if(w_number==b_number){ 60 printf("引き分けです\n"); 61 }else if(w_number<b_number){ 62 printf("あなたの勝利です\n"); 63 }else{ 64 printf("あなたの敗北です\n"); 65 } 66 } 67} 68 69int num_kaeseru(int x,int y,int iro){//そこに打つといくつ返せるか 70 if(board[y][x]!='.'){ 71 return -1; 72 } 73 char my_iro; 74 char aite_iro; 75 if(iro==1){//自分の色がwなら 76 my_iro ='w'; 77 aite_iro ='b'; 78 }else{ 79 aite_iro = 'w'; 80 my_iro = 'b'; 81 } 82 int total=0; 83 for(int dy=-1;dy<=1;dy++){ 84 for(int dx=-1;dx<=1;dx++){ 85 int sx,sy; 86 int k=0;//めくる枚数 87 sx = x; 88 sy = y; 89 while(1){ 90 sx += dx; 91 sy += dy; 92 if(sx<=0 || sy<=0 || sx>8 || sy>8){//盤面を超えたら 93 break; 94 } 95 if(board[sy][sx]=='.'){ 96 break; 97 } 98 if(board[sy][sx]==aite_iro){ 99 k += 1; 100 } 101 if(board[sy][sx]==my_iro){ 102 total += k; 103 break; 104 } 105 } 106 } 107 } 108 return total; 109} 110 111void put_check(int x,int y,int iro){//iroは自分の色 112char my_iro; 113char aite_iro; 114if(iro==1){ 115 my_iro ='w'; 116 aite_iro ='b'; 117}else{ 118 my_iro ='b'; 119 aite_iro ='w'; 120} 121 for(int dy=-1;dy<=1;dy++){ 122 for(int dx=-1;dx<=1;dx++){ 123 int sx,sy; 124 int k=0;//めくる枚数 125 sx = x; 126 sy = y; 127 while(1){ 128 sx += dx; 129 sy += dy; 130 if(sx<=0 || sy<=0 || sx>8 || sy>8){//盤面を超えたら 131 break; 132 } 133 if(board[sy][sx]=='.'){ 134 break; 135 } 136 if(board[sy][sx]==aite_iro){ 137 k += 1; 138 } 139 if(board[sy][sx]==my_iro){ 140 for(int i=0;i<k;i++){//めくる作業 141 sx -= dx; 142 sy -= sy; 143 board[sy][sx]=my_iro; 144 } 145 break; 146 } 147 } 148 } 149 } 150} 151 152void put(){ 153 while(1){ 154 printf("あなたのターンです。\n"); 155 printf("縦方向"); scanf("%d",&j_put); 156 printf("横方向"); scanf("%d",&i_put); 157 if(num_kaeseru(i_put,j_put,WHITE)>0){ 158 break; 159 } 160 } 161 put_check(i_put,j_put,WHITE); 162} 163 164int uteru_masu(int iro){ 165 for(int y=1;y<=8;y++){ 166 for(int x=1;x<=8;x++){ 167 if (num_kaeseru(x,y,iro)>0){ 168 return 1;//1=打てるマスあり 169 } 170 } 171 } 172 return 2;//打てるマスなし 173} 174 175void computer_1(){ 176 int c_x,c_y;//コンピュータが置く位置 177 srand((unsigned int)time(NULL)); 178 while(1){ 179 c_x = rand()%8+1; 180 c_y = rand()%8+1; 181 if(num_kaeseru(c_x,c_y,BLACK)>0){ 182 break; 183 } 184 } 185 put_check(c_x,c_y,2); 186} 187void menu(){ 188 while(1){ 189 if(bamen_sentaku==1){ 190 printf("/////////////////オセロ/////////////////\n"); 191 //printf("ゲームモードを選択してください//なお2Pゲームしか実装されていない模様\n"); 192 //printf("1Pゲーム ---1\n2Pゲーム ---2\n --->"); scanf("%d",&sentaku); 193 shokika(); 194 display(); 195 printf("%d\n",num_kaeseru(5,1,1)); 196 bamen_sentaku=2; 197 }else if(bamen_sentaku==2){ 198 put(); 199 display(); 200 bamen_sentaku=3; 201 }else if(bamen_sentaku==3){ 202 computer_1(); 203 display(); 204 bamen_sentaku=4; 205 }else if(bamen_sentaku==4){ 206 if(uteru_masu(WHITE)==2 && uteru_masu(BLACK)==2){ 207 printf("試合終了です"); 208 bamen_sentaku=5; 209 }else if(uteru_masu(WHITE)==2 && uteru_masu(BLACK)==1){ 210 printf("あなたは打てないのでパスです\n"); 211 bamen_sentaku=3; 212 }else if(uteru_masu(WHITE)==1 && uteru_masu(BLACK)==2){ 213 printf("コンピュータが打てるコマがないのでパス。\n"); 214 }else{ 215 bamen_sentaku=2; 216 } 217 }else if(bamen_sentaku==5){ 218 shouhai(); 219 break; 220 } 221 } 222} 223 224int main(){ 225 menu(); 226 return 0; 227}
試したこと
このコードを実行したところ、コマを置く位置を指定したときに、カードがうまくいかず、おかしな挙動をします。pythonゲームアルゴリズム入門という書籍を参考しつつ、c言語で作ってみようとしているのですが、うまく行かないので、改善点を教えてほしいです。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
漠然と「うまく挙動しません」「おかしな挙動をします」というのではなく、
・こういう動作を期待して
・こういうプログラムを組んだ(この部分はありますが)ら
・期待と違う、こういうことが起こった
という「観察できる事実」を具体的に書いてください。そうでないと、回答者はあなたのプログラムを全部チェックしなければならなくなります。
computer_1();
は
computer_LV1();
の間違いでしょうか。提示されたソースをコンパイルすると、
computer_1でエラーになります。
全然ご質問に関係無く「どうでもいい」と言われそうですが、変数名や関数名に英語とローマ字日本語を混在させないで頂きたいです。
tatsu99様
コードを修正いたしました。
jimbe様
基本的にはpythonのゲームプログラミングの本の関数の名前をそのままつかっています。
混在しないほうがいいのは、そのとおりだと思うのであとで改善したいと思います。
thkana様
実行結果を載せました。
> 本の関数の名前をそのままつかっています
駄文に返信ありがとうございます、了解です。
python では有りなのでしょうけれど、なんともまぁ。
回答2件
あなたの回答
tips
プレビュー