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

このQ&Aのポイント
  • C++で作成したオセロのCPUの処理が40手目あたりから正常に動作しない問題が発生しています。
  • ReverseOthello関数の石を探して裏返す処理が正しく機能しないため、改善が必要です。
  • プログラミング経験が豊富な方にアドバイスをお願いします。
回答を見る
  • ベストアンサー

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; }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

最初のほうしか見ていませんが、検索結果sumの要素が28しかないのは何故ですか? 単純に考えて64だと思いますが(最初に4個駒を配置しているなら60でもよいですが)。もしもkが28を超えた場合はスタックを破壊するので何が起きても不思議ではありません。 またバグとは関係ありませんが、for文が嫌いですか? 個人的には固定ループならwhile文より見やすいと思います。

その他の回答 (1)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

コメントが全くないソースコードを読み取るのは、 正直なところ厳しいです。

関連するQ&A

  • プログラムの処理について

    主クラスから別のクラスに送るときに 値一個ずつ6回送って処理した値を返すのと 値二個ずつ3回送って処理した値を返すのと どちらが早いのですか? 例1) main(){ int i,ans = 0; int num1[] = new int[6]; for(i=0;i<6;i++){ num1[i] = i+1; ans += ***.keisan(num[i]); } } class ***{ static int keisan(int num){ int x; x = num * 2; return x; } } 例2) main(){ int i,j,ans = 0; ***[] dt = new ***[3]; for(i=0,j=1;i<3;i++){ *** dt[i] = new ***(); dt[i].num1 = dt[i].num2 = 0; dt[i].num1 = j++; dt[i].num2 = j++; ans += ***.keisan(dt[i].num1,dt[i].num2); } } class ***{ public int num1; public int num2; static int keisan(int num1,int num2){ int x; x = (num1 + num2) * 2; return x; } } 上記の構文みたいな感じの状況です 構文が間違ってても気にしないでいただけるとありがたいです

    • ベストアンサー
    • Java
  • 配列に値が入らない【c言語】

    下のプログラムで配列(DivBdInfo[i].StgSizeAvg)に値が入らず困っています。 やっていることは平均を求めているだけです。 DivBdInfo[i].StgSizeAvgの変数iを3や5に変えるとこちらは値が入ります。 デバッグ時にSumとcntに値が入っているのは確認しました。 DIVBD_INFO DivBdInfo[DIVBOARD_NUM];はグローバルです。 回答よろしくお願いします。 #define DIVBOARD_NUM 9 typedef struct _DIVBD_INFO { double StrgSizeAvg; double LinkNumAvg; double GrpSizeAvg; }DIVBD_INFO; DIVBD_INFO DivBdInfo[DIVBOARD_NUM]; void StrgSizeAvg(STRING *stringlist) { int x,y,i,id; int rfx,rfy; int Sum; int cnt; for(i=0;i<DIVBOARD_NUM;i++) { GetDivideRfXY(i,&rfx,&rfy); for(i=0;i<movenum;i++){stringlist[i].chk=FALSE;} Sum= cnt= 0; for(y=0;y<DIVIDE_SIZE;y++) { for(x=0;x<DIVIDE_SIZE;x++) { if(gostridboard[rfy+y][rfx+x]>SPACE){ id= gostridboard[rfy+y][rfx+x]-1; if(stringlist[id].chk==FALSE){ Sum+= stringlist[id].size; stringlist[id].chk=TRUE; cnt++; } } } } DivBdInfo[i].StrgSizeAvg=(double)Sum/cnt; //DivBdInfo[5].StrgSizeAvg=Sum/cnt; } }

  • 合計値を求める関数

    #include<iostream> using namespace std; //sum関数の定義 int sum(int x, int y) { return x + y;  } int main() { int num1, num2, ans; cout << "1番目の整数を入力して下さい。\n"; cin >> num1; cout << "2番目の整数値を入力して下さい。\n"; cin >> num2; ans = sum(num1, num2); cout << "合計は" << ans << "です。\n"; return 0; }  ここのreturn x+y;の所の合計値を戻り値として返す処理の仕組みを解りやすく教えて欲しいです、戻り値はちょっと解りづらいです、よろしくお願いします。

  • C言語に関して

    C言語に関して 100までの自然数を文字列に変換したいのですが、以下のプログラムを実行すると、001,002,…010,…099,100のようになってしまいます。左詰めにしたいのですが、どこが間違っているかご教示下さい。 #include <stdio.h> #define N1 100 #define N2 5 int get_ketasuu(); void henkankun(); int main(void) { int i, dig, x; int num1 = N1; int num2 = N2; int buff1[N1], buff2[N1]; char buff3[N1][N2]; for (i = 0; i < N1; i++) { x = buff2[i] = buff1[i] = i + 1; dig = get_ketasuu(x); henkankun(&buff2[i], &buff3[i], dig); printf("%s\n", buff3[i]); } return 0; } int get_ketasuu(x) int x; { int dig; dig = 0; do { x /= 10; dig++; } while (x > 0); return dig; } void henkankun(x, y, dig) int *x; int dig; char (*y)[N2]; { int j, k; switch (dig) { case 1 : k = 1; case 2 : k = 10; case 3 : k = 100; } j = 0; do { (*y)[j] = (*x / k) + '0'; *x %= k; k /= 10; j++; } while (k > 0); (*y)[j] = '\0'; }

  • 解けません!

    http://www.pref.fukushima.jp/pc-concours/2008/03/pdf/2007honsen.pdf この問題03の宅配料金の問題が解けません!! 書かれている入力例と出力例はあっているのですが、 学校のジャッジシステムが受けつけてくれません。 どなたか僕のプログラムの不備を見つけて下さい。 お願いします。 #include <stdio.h> int ryoukin(int x, int y, int h, int w) { int i,t,c; i = x + y + h; if (i <= 60) t = 600; else if (i <= 80) t = 800; else if (i <= 100) t = 1000; else if (i <= 120) t = 1200; else if (i <= 140) t = 1400; else if (i <= 160) t = 1600; else t = 0; if (w <= 2) c = 600; else if (w <= 5) c = 800; else if (w <= 10) c = 1000; else if (w <= 15) c = 1200; else if (w <= 20) c = 1400; else if (w <= 25) c = 1600; else c = 0; if (t == 0) return 0; else if (c == 0) return 0; else if (t < c) return c; else return t; } int main(void) { int x,y,h,w,n,i,sum; sum = 0; while(n != 0){ scanf("%d",&n); if(n != 0){ for(i = 0; i < n; i++){ scanf("%d %d %d %d", &x, &y, &h, &w); sum = sum + ryoukin(x,y,h,w); } printf("%d\n",sum); sum = 0; } } return (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++

    ICPCの過去問です。 問題文:http://www.deqnotes.net/acmicpc/p0003/ja 過去問を解いたのですが実行が上手くいかずに困っています。 私の書いたソースコード: #include <iostream> #include <string> using namespace std; class Line{ public: char* Read(){ char number[1024];//数字を入れる配列 static char sentence[76];//できあがった文字列を入れる配列 char word;//現在の文字 int i=0;//カウンタ int s=0;//sentenceのカウンタ int y=0;//数字が何回連続したかを数える char one[5]={'.',',','!','?',' '}; char two[3]={'a','b','c'}; char three[3]={'d','e','f'}; char four[3]={'g','h','i'}; char five[3]={'j','k','l'}; char six[3]={'m','n','o'}; char seven[4]={'p','q','r','s'}; char eight[3]={'t','u','v'}; char nine[4]={'w','x','y','z'}; int c; while(c = getchar() != '\n'){//数を一文字ずつ配列にいれていく number[i] = c; i++; } for(int x=0;x<(i+1);x++){ if(number[x]=='0'){ if(word == 'N'){} else{sentence[s]=word;s++;y=0;word='N';} } else{ if(number[x]=='1'){ word=one[y]; y++; y=y%5;} else if(number[x]=='2'){ word=two[y]; y++; y=y%3;} else if(number[x]=='3'){ word=three[y]; y++; y=y%3; } else if(number[x]=='4'){ word=four[y]; y++; y=y%3; } else if(number[x]=='5'){ word=five[y]; y++; y=y%3; } else if(number[x]=='6'){ word=six[y]; y++; y=y%3; } else if(number[x]=='7'){ word=seven[y]; y++; y=y%4; } else if(number[x]=='8'){ word=eight[y]; y++; y=y%3; } else{ word=nine[y]; y++; y=y%4; } } } sentence[i]='N'; return sentence;//配列の先頭のポインタを返す } }; int main(){ int n;//行数 cin>>n; getchar();//改行をとる char *first[n]; int i; int x=0; char ch; char *Fir; for(i=0;i<n;i++){ Line line; first[i] = line.Read(); } for(int j=0;j<i;j++){ Fir = first[i]; while((ch = Fir[x]) != 'N'){ cout << ch ; x++; } cout << '\n'; } return 0; } 実行結果: 1 20 Segmentation fault となってしまいます。 coutやコメントアウトで動きを追ってみたところ、下から8行目くらいのwhile文がなければ、segumentation faultはおきませんでした。ポインタの扱いが間違っているのかなとは思うのですが、どこが悪いのか考えても分かりません。どなたか教えてください。

  • C言語での質問

    プログラミングの課題をやっているのですが、一部どうしてもわからないことがあるので質問させて下さい。 課題では100個の点のX座標、Y座標を0から5の間でランダムに設定し、ファイルに書き出すといった内容なのですが、この点を設定した時、任意の2点のX座標、Y座標の差が0.01以下になる場合は設定し直さないといけません。 これは後々の課題に関係してくるから、みたいなのですが。 そこで点の設定の関数として以下のようなプログラムを考えてみました。(ちなみに構造体pointを前に宣言してあり、p[].xは点のX座標、p[].yは点のY座標です。また、NUM=100と最初に宣言してあります。) void tensettei(point p[], int num){ int i, j, k; double sa; for(i=0; i < num; i++){ p[i].x = ((double) rand()) / ((double) RAND_MAX) * 5; p[i].y = ((double) rand()) / ((double) RAND_MAX) * 5; } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(p[j].x > p[k].x) sa = p[j].x - p[k].x; else sa = p[k].x - p[j].x; if(sa < 0.01) tensettei(p, NUM) } } for(j=0; j < (num - 1); j++){ for(k=j+1; k < num; k++){ if(mp[j].y > mp[k].y) sa = mp[j].y - mp[k].y; else sa = mp[k].y - mp[j].y; if(sa < 0.01) tensettei(p, NUM) } } } しかし、実行してもエラーが起こったのかすぐに終了してしまい、この後に点データを出力するプログラムを書いているのですが、ちゃんと出力されません。 いろいろプログラムを変えて試した結果、原因は「tensettei(p, NUM)」にあることはわかりました。 それさえ変えればすればうまく動作しましたので。 再帰と同じ感じでいけるかと思ったのですがどうやら駄目のようです。 そこで質問なのですが、ループの中である条件が起こったら最初からやり直し、てなプログラムはどんな風にすればいいのでしょうか?

  • インライン関数の使い道と理屈

    #include <iostream> using namespace std; //max関数の定義 inline int max(int x, int y){if(x>y) return x; else return y;} int main(){ int num1, num2, ans; cout << "1番目の整数を入力して下さい。\n"; cin >> num1; cout <<"2番目の整数を入力して下さい。\n"; cin >> num2; ans = max(num1, num2); cout << "最大値は" << ans << "です。\n"; return 0; } インライン関数の処理は呼び出し部分に埋め込まれるので、プログラムの処理速度が 向上することがありますとあるんですが、 どのような時にインライン関数は使用するのでしょうか? 理由もしくみもご教示お願いします。

  • Cのソースコードについて

    #include<stdio.h> int main(void) { long a[6000],sum[6000],max=0; int i,j=0,n,m; for (m = 0; m <= 6000; m++) sum[m] = 0; for (i = 0;; i++) { scanf_s("%ld", &a[i]); if (a[i] > 0) sum[j] += a[i]; else if (a[i] < 0) { j++; sum[j] = -1; j++; } else break; } for (n = 0; sum[n] == 0; n++) { if (max < sum[n]) max = sum[n]; } printf("%ld",max); while(1){} return 0; } こんなコードを書いたのですが 答えが常に0になってしまいます。 原因がはっきりしないので教えてください 使用言語はCです

専門家に質問してみよう