• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:オセロを作成 助言お願いします・・・)

オセロ作成に関する助言をお願いします

N-Ishikawaの回答

回答No.1

そもそもおかしいところは1カ所ありますね。 bord[y][x]に1を設定した場合、その直後で必ず2にしています。 ---------------------------------------------------------------- //ひっくり返す// if(x>=0 && x<8 && y>=0 && y<8 && bord[y][x]==0){ if(bord[y][x] == 0){ bord[y][x]=1; } ← ここに elseがないのが問題 if(bord[y][x]==1) { bord[y][x]=2; } } ---------------------------------------------------------------- デバッグで値の変化ぐらいは確認しましょう..... あと、オセロのルールに則れば、 1.必ずひっくり返せる場所にしかおけない   →おけるかどうかの判定が必要。    入力エラーは入力直後に判定、間違っていても    おける以上、相手に権利を移させない。    ギブアップで-1,-1を入力すると手動で権利を移す 2.置いたらひっくり返す。   →ひっくり返せる方向は8方向    私ならどの方向にひっくり返せるかのチェック関数を作成。    1バイトフラグ(8bit)にて返す。(1.でも呼ぶ)    ひっくり返す際はフラグに従い、設置位置隣接位置から目的の    駒までひっくり返す。 ついでにいくつか気になった点を挙げておきます。 ・プログラムですが、X,Y座標入力において  以下の判定実行は scanf()の直後で実行すべきです。  ------------------------------------------  //エラー処理//  if(x<0 || x>=8 || y<0 || y>=8 )    :  ------------------------------------------    下記判定は上記判定の前段階で行っているのですが、  同一if文内の 判定順序は C言語の処理系によっては  後ろから....なんてことが多々あります。  bord[y][x]のように、配列にx,yを使用するのは必ず  値チェックを先に行いましょう。  (xに10000とか入力すると例外エラーの可能性が....)  ------------------------------------------  if(x>=0 && x<8 && y>=0 && y<8 && bord[y][x]==0){  ------------------------------------------  そもそも、scanf()直後にエラー処理を行っていれば、  「x>=0 && x<8 && y>=0 && y<8 &&」は不要ですよね。 ・入力に失敗しただけで相手に権利が移ってしまうのは厳しくないですか?  (そのように見えます。違っていたらすみません。) ・playerがカウントアップしていくのですが、うまく使えば終了条件に  使用できますよね。  今は駒を置くのに失敗してもカウントアップされてしまうようなので  64になっても必ず終了しているとは限りませんが、そこをうまく  調整すると終了条件に使用できるようになるかと思います。  (今は結局 CTRL+Cで終了させるように見えます.....)

kokakoara
質問者

補足

こんなに詳細に回答してくれるかたがいるとは思いませんでした。 ありがとうございます。 >必ずひっくり返せる場所にしかおけない >→おけるかどうかの判定が必要 これはクリアしました。 >入力エラーは入力直後に判定、間違っていても >おける以上、相手に権利を移させない。 >ギブアップで-1,-1を入力すると手動で権利を移す これもクリアしました。 >1バイトフラグ(8bit)にて返す。(1.でも呼ぶ) >ひっくり返す際はフラグに従い、設置位置隣接位置から目的の >駒までひっくり返す。 お手上げです。 >そもそもおかしいところは1カ所ありますね。 >bord[y][x]に1を設定した場合、その直後で必ず2にしています。 >-------------------------------------------------------------- >//ひっくり返す// >if(x>=0 && x<8 && y>=0 && y<8 && bord[y][x]==0){ >if(bord[y][x] == 0){ >bord[y][x]=1; >} ← ここに elseがないのが問題 >if(bord[y][x]==1) >{ >bord[y][x]=2; >} >} >-------------------------------------------------------------- >デバッグで値の変化ぐらいは確認しましょう..... この一番肝心なところがわかりません。。。 ------------------------------------------------------------ //ひっくり返す if(x>=0 && x<8 && y>=0 && y<8 && bord[y][x]==0){ if(bord[y][x] == 1){ bord[y][x]=2; }else{ if(bord[y][x]==0) bord[y][x]=1; } printf("\n"); printf("石が置かれました。\n"); player++; } ------------------------------------------------------------ こんな感じになったんですけどやはりずっと同じ石しか置けません。 終了条件ですかそれはできそうですね。 --------------------------以下すべてのソース------------------- #include<stdio.h> int bord[8][8]; int x,y; int i,j,l,a; int player; int main (void) { //ボードの初期化// for(i=0;i<8;i++){ for(j=0;j<8;j++){ bord[i][j]=0; } } bord[3][3]=1; bord[4][4]=1; bord[3][4]=2; bord[4][3]=2; //bordの表示// player=0; for(;;){ //何度も表示 printf("01234567\n"); for(i=0;i<8;i++){ for(j=0;j<8;j++){ if(bord[i][j] == 0){ printf("*"); } else if(bord[i][j] == 1){ printf("●"); } else{ printf("○"); } } printf("\n"); } //黒か白か判定// if(player%2==0){ bord[i][j]=1; printf("黒の番です。\n"); printf("y座標を入力してください。(縦軸)"); scanf_s("%d", &y); printf("x座標を入力してください。(横軸)"); scanf_s("%d", &x); } if(player%2==1){ bord[i][j]=0; printf("白の番です。\n"); printf("y座標とx座標どちらも100と入力すると相手のターンにします。\n"); printf("y座標を入力してください。(縦軸)"); scanf_s("%d", &y); printf("x座標を入力してください。(横軸)"); scanf_s("%d", &x); } //ひっくりかえす// //石を置く権利を相手に移す if(x==100 && y==100){ printf("\n"); printf("石を置く権利を相手に渡します。\n"); player++; continue; } //エラー処理(入力された数字が許容範囲外) if(x<0 || x>=8 || y<0 || y>=8 ) { printf("許容範囲外です。\n"); printf("もう一度入力してください。\n"); } //エラー処理(同じところには置けない) if(bord[y][x]!=0) { printf("\n"); printf("置かれてるよ!\n"); } //ひっくり返す if(x>=0 && x<8 && y>=0 && y<8 && bord[y][x]==0){ if(bord[y][x] == 1){ bord[y][x]=2; }else{ if(bord[y][x]==0) bord[y][x]=1; } printf("\n"); printf("石が置かれました。\n"); player++; } } //無限loop終了地点 return 0; } ---------------------------------ソース終了---------------------

関連するQ&A

  • C++でオセロのCPUの処理を考えたのですが、40手目あたりからうまく

    C++でオセロのCPUの処理を考えたのですが、40手目あたりからうまくいきません。ReverseOthello関数の石を探して裏返す処理がおかしいと思われます。一番裏返せる石が多い位置を裏返すという処理をしています。プログラミング経験が豊富な方よろしくお願いします。 #include "stdafx.h" bool Othello(int (*pBoard)[8] ){ int i; int j; int ans; int k = 0; int num[3] = {0,0,0}; int sum[28][3]; i = 0; while(i < 28){ j = 0; while(j < 3){ sum[i][j] = 0; j++; } i++; } i = 0; while(i < 8){ j= 0; while(j < 8){ if(pBoard[i][j] == 0){ ans = SeachStone(i,j,pBoard); if(ans != 0){ sum[k][0] = i; sum[k][1] = j; sum[k][2] = ans; k++; } } j++; } i++; } i = 0; while(i < 28){ if(num[2] < sum[i][2]){ num[0] = sum[i][0]; num[1] = sum[i][1]; num[2] = sum[i][2]; } i++; } if(num[2] == 0){ return false; } ReverseStone(num[0],num[1],pBoard); return true; } void ReverseStone(int y1,int x1,int (*pBoard)[8]){ int cnt = 0; int y2; int x2; int i; int j; int k; if(y1 == 0){ i = 0; } else { i = y1-1; } while(i < y1 + 2){ if(x1 == 0){ j = 0; } else { j = x1-1; } while(j < x1 + 2){ y2 = i; x2 = j; cnt = 0; while(pBoard[y2][x2] == -1){ y2 = y2 + (i - y1); x2 = x2 + (j - x1); cnt++; } if(pBoard[y2][x2] == 1&& cnt != 0){ k = 0; while(k < cnt + 1){ y2 = y2 + (y1 - i); x2 = x2 + (x1 - j); pBoard[y2][x2] = 1; printf("%d\n",pBoard[y2][x2]); k++; } } j++; } i++; } } int SeachStone(int y1,int x1,int (*pBoard)[8]){ int cnt = 0; int sumCnt = 0; int y2; int x2; int i; int j; if(y1 == 0){ i = 0; } else { i = y1-1; } while(i < y1 + 2){ if(x1 == 0){ j = 0; } else { j = x1-1; } while(j < x1 + 2){ y2 = i; x2 = j; cnt = 0; while(pBoard[y2][x2] == -1){ y2 = y2 + (i - y1); x2 = x2 + (j - x1); cnt++; } if(pBoard[y2][x2] == 1&& cnt != 0){ sumCnt = sumCnt + cnt; } j++; } i++; } return sumCnt; }

  • C言語の問題がわからないです。

    C言語のプログラムで、列数を自分で決めて、 (例)3列         ●(この行を最後として)   □● ●□● 上記のプログラムを作りたいのですが、 上手くいきません。途中まで作ったのですが、なかなか思うようにいかないです。どうすれば上記のようになりますでしょうか? #include <stdio.h> void disp(int x, int y); main() { int i,n; printf("表示する列:"); scanf("%d",&n); disp(3,3); for(i=1;i<=n;i++){ if(i%2==0){ disp(n-i,4); disp(i,2); } else{ disp(n-i,4); disp(i,1); } disp(1,3); } } void disp(int x, int y) { int i; for(i=0;i<x;i++){ if(y==1){ printf("●"); } else if(y==2){ printf("□"); } else if(y==3){ printf("\n"); } else{ printf("\0"); } } }

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • C++でグラフをリスト構造で作る

    今、『グラフのデータを読み込んで、行列形式で配列に保存するプログラム』を作りました。下記に私の作ったそのプログラムがあります。しかしこの次にこれと同じことを「リスト構造」を使って作らないといけないのですがなかなかうまくいかないです。どのように作ればいいか分かる人がいたら教えてください! #include<stdio.h> #define hairetu 5 int main(void){ int x, y, i, j, a[hairetu][hairetu]; for(i=0; i<5; i++){ for(j=0; j<5; j++){ a[i][j]=0; } } printf("0以下の数を入れると終了します\n"); while(1){ printf("1~5の数のうち、2つ数字を入力しなさい\n"); scanf("%d%d", &x, &y); if(x<=0 || y<=0){ break; } else if(x>5 || y>5){ printf("エラー\n"); return 1; } a[x-1][y-1]=1; } for(i=0; i<5; i++){ printf("\n"); for(j=0; j<5; j++){ printf("%d", a[j][i]); } } printf("\n"); return 0; }

  • 迷路作成のプログラミング

    迷路作成のプログラミングをC++で作ったのですが、エラーが出ます。 どのように直せば良いか教えてください。 エラー内容は 'randoomize': 識別子が見つかりませんでした。 16 進型定数には、少なくとも 1 桁の 16 進数が必要です。 'kbhit': 識別子が見つかりませんでした 'getch': 識別子が見つかりませんでした です、、お願いします。 #include <stdio.h> #include <stdlib.h> #include <time.h> #define YOKO_MAX 200 #define ESC '\xlb' int n; int map[YOKO_MAX],count[YOKO_MAX]; int rr() { return rand() % 10>3; } void tate() { int i,j,k; printf("■"); for (i=0; i<n-1;i++) if(map[i]!=map[i+1] && rr()) { k=map[i+1]; count[k]=0; for(j=0; j<n; j++) if(map[j]==k) { map[j]=map[i]; count[map[i]]++; } printf(" "); } else printf("■"); printf("■\n"); } void last_tate() { int i,j,k; printf("■"); for (i=0; i<n-1;i++) { if(map[i]==map[i+1]) printf("■"); else { k=map[i+1]; for (j=0; j<n; j++) if (map[j]==k) map[j]=map[i]; printf(" ",map[i]); } } printf("■\n"); } void yoko() { int i,j; for (i=0; i<n; i++) if (count[i]>1 && rr()) { printf("■■"); for(i=0; i<n; i++) { if (count[j]==0) { count[j]=1; count[map[i]]--; map[i]=j;break; } } } else { printf("■"); } printf("■\n"); } void enter() { int i,k; k=rand() % n; for (i=0; i<n; i++) if(i==k) { printf("■"); } else { printf("■■"); } printf("■\n"); } void initialize() { int i; for (i=0; i<n; i++) { map[i]=i; count[i]=1; } randoomize(); } int main() { printf("無限に大きな迷路\n"); do { printf("\n迷路の横幅(2~200)?"); scanf("%d",&n); } while (n<2||n>=YOKO_MAX); printf("\n ESCキーを押すと止まる。\n"); initialize(); enter(); do { tate(); yoko(); } while (!kbhit()||getch()!=ESC); last_tate(); enter(); }

  • RPGゲームの簡単なプログラムを打ってみたんですがうまく表示されません

    RPGゲームの簡単な初歩的なサンプルプログラムを自分で打ってみたんですが、思った通りに表示されません。 以下のソースのどこかおかしいとこありますでしょうか。 #include<stdio.h> #include<windows.h> #define MAP_SIZE_Y 10 #define MAP_SIZE_X 10 int x = 4,y = 5; int j,i; int map[100][100] = { {1,1,1,1,1,1,1}, {1,0,0,3,0,0,1}, {1,0,0,0,0,0,1}, {1,0,2,0,2,0,1}, {1,0,0,0,0,0,1}, {1,1,1,1,1,1,1}, }; void DrawMap(){ for(j = 0; i < MAP_SIZE_Y; j++){ for(i = 0; i < MAP_SIZE_X; i++){ if(j == y && i == x){ printf("勇"); }else{ switch ( map[j][i]){ case 1: printf("■"); break; case 2: printf("兵"); break; case 3: printf("王"); break; default:printf(" "); break; } } } printf("\n"); } } void main(){ while(1) { system("cls"); DrawMap(); } }

  • 有限体GF(4)上の同次方程式で不定方程式

    連立方程式の解法ですが、手計算だとうまくいくのにプログラムにしようとするとうまくいきません。 さらに不定方程式なので解がないといわれてしまいます。誰かわかる方がいらしたらプログラムを 見て直していただきたいです。プログラムは以下の通り。 #define N 4 #define T 6 unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char ad[4][4]; /* 答えは 1,1,2 */ unsigned char s[3][3]={{1,3,1},{3,3,0},{1,0,3}}; /* 答えはzを不定として1と置き、x=z=1;y=0;になる筈だがならない */ //unsigned char s[][]={{2,2,2},{2,0,2},{2,2,2}} int add(int x,int y){ return ad[x][y]; } int mlt(int x, int y){ if(x==0||y==0) return 0; return ((x+y-2)%(N-1))+1; } int mltn(int n,int x){ int i,j; if(n==0) return 1; i=x; for(j=0;j<n-1;j++) i=mlt(i,x); return i; } int div(int x,int y){ if(x==0) return 0; return ((x-y+(N-1))%(N-1))+1; } void syn(){ int i,j,k,l,n; for(i=0;i<3;i++){ for(j=0;j<3;j++){ if(i==j){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } // exit(1); if(s[i][j]==0){ while(s[i][j]==0){ j++; } printf("i-j==%d\n",s[i+1][j]); if(s[i][j]!=0){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } }} // i++;j++; //exit(1); } } } } } for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%2d ",s[i][j]); printf("\n"); } } int main(){ int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++) ad[i][j]=fg[gf[i]^gf[j]]; } syn(); }

  • 奇数魔方陣

    下記のプログラム(奇数魔方陣) について最初のfor文からどのような処理が行われているかわかりません。 { int mahoujin[10][10],x,y,i,n = 7; x = n / 2 + 1; y = 1; mahoujin[x][y] = 1; for( i = 2; i <= n * n; i++ ){ if( i % n == 1 ){ y = y + 1; }else{ x = x + 1; y = y - 1; } if( x > n ) x = 1; if( y < 1 ) y = n; mahoujin[x][y] = i; } for( y = 1; y <= n; y++ ){ for( x = 1; x <= n; x++ ){ printf( "%3d ", mahoujin[x][y] ); } printf( "\n" ); } 特にわからないのがif文で分岐になるところどのようなことが行われているかがわからないです。どなたか教えて頂けるとうれしいです。

  • おかしいところ

    ソースのおかしいところ教えてください #include <stdio.h> #include <time.h> #include <stdlib.h> //繰り返し処理(結果のトータル表示なし) main () { int piayer, computer; int limit = 5; //繰り返し回数 int i; printf ("【%d回勝敗ジャンケンゲーム】\n", limit); srand(time(NULL)); for(i = 0; i < limit; i++) { printf("ジャンケンゲーム・・・(グ―:1 チョキ:2 パ―:3を入力) > "); piayer = 0; scanf("%d", &piayer); while (getchar() != '\n') { } computer = rand()%3 + 1; printf("コンピュータは"); if(computer == 1) {printf("グー"); } else if(computer == 2) { printf("チョキ");} else if(computer == 3) { printf("パー");} printf("! "); if(computer == player){ printf("あいこ\n"); } else if(player ==1 && computer ==2){ printf("プレイヤーの勝ち\n"); } else if(player ==2 && computer ==3){ printf("プレイヤーの勝ち\n"); } else if(player ==3 && computer ==1){ printf("プレイヤーの勝ち\n"); } else if(player ==2 && computer ==1){ printf("コンピュターの勝ち\n"); } else if(player ==3 && computer ==2){ printf("コンピュターの勝ち\n"); } else if(player ==1 && computer ==3){ printf("コンピュターの勝ち\n"); } else { printf("プレイヤーが不正な手を出した\n"); } return 0; }

  • N王妃システムの解のタイム計算

    先輩方にご協力をお願いしたく書き込みさせていただきます。 #include <stdio.h> #define FREE 0 #define BUSY 1 #define N 8 int q_pos[N+1]; int colum[N+1]; int r_up[2*N]; int r_dw[2*N]; void disp(void) { int y,x; static count = 0; printf("\n解 %d\n", ++count); for(y=1;y<=N; y++){ for(x=1;x<=N; x++){ if (q_pos[y] == x)printf("○"); else printf("×"); } printf("\n"); } } void eight_queens(int y) { int x; for (x=1; x<=N; x++){ if(colum[x]==FREE && r_up[y+x-1]==FREE && r_dw[y-x+N]==FREE){ q_pos[y]=x; if (y>=N) disp(); else{ colum[x]=BUSY; r_up[y+x-1]= r_dw[y-x+N]=BUSY; eight_queens(y+1); colum[x]=FREE; r_up[y+x-1]= r_dw[y-x+N]=FREE; } } } } int main(void) { int i; for(i=1;i<=N; i++) colum[i]=FREE; for(i=1;i<2*N;i++) r_up[i]= r_dw[i]=FREE; eight_queens(1); return 0; } こちらのプログラムに #include<stdio.h> #include<stdlib.h> #include<time.h> void sleep(clock_t wait); void main(void) { int i,j,n; time_t start,finish; double duration,v; printf("繰り返し回数は>"); scanf("%d",&n); time(&start); v=1.01; for(i=0; i<n; i++) { if(((i+1)% 10)==0) { fprintf(stdout,"."); fflush(stdout); } for(j=0; j<n; j++) { v *=1.0001; } } printf("\n"); time(&finish); duration=difftime(finish,start); printf("計算にかかった時間は約%6.2f 秒です \n", duration); } のプログラムを合体させ、1つのプログラムを完成させたいのですが、どのような配列にしたらいいのか教えて欲しいです>< アルゴリズムとしては、チェスのN王妃のプログラムから解を導きだすと同時に、そのプログラムを起動してから終わりまでのタイムを計算するプログラムを挿入すると言う内容です。 長くてすいません;;