• 締切済み

プログラミングによるオセロゲームの作成について

今オセロゲームをCで作成中なので、先ほども質問したのですが、 http://hp.vector.co.jp/authors/VA015468/platina/algo/2_2.html のサイトのminiMax法の実装法ですと最終的な戻り値は評価値ですよね? 一番いい評価値の場所にコマを置くためには結局そのx.y座標が必要だと思うのですが、どこからそのx.y座標を最終的に得るのでしょうか? ご教授願います

みんなの回答

回答No.5

 突如として割り込んでしまいすみません。  疑問点があるのであれば書籍を参考にするのはいかがでしょう? >リバーシのアルゴリズム C++&Java対応―「探索アルゴリズム」「評価関数」の設計と実装 (I・O BOOKS) [単行本] >http://www.amazon.co.jp/%E3%83%AA%E3%83%90%E3%83%BC%E3%82%B7%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0-C-Java%E5%AF%BE%E5%BF%9C%E2%80%95%E3%80%8C%E6%8E%A2%E7%B4%A2%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%80%8D%E3%80%8C%E8%A9%95%E4%BE%A1%E9%96%A2%E6%95%B0%E3%80%8D%E3%81%AE%E8%A8%AD%E8%A8%88%E3%81%A8%E5%AE%9F%E8%A3%85-I%E3%83%BBO-BOOKS/dp/4875934289/ref=sr_1_1?ie=UTF8&qid=1392115035&sr=8-1&keywords=%E3%83%AA%E3%83%90%E3%83%BC%E3%82%B7%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9  第3章に探索アルゴリズムとして、ここの部分でMinimaxアルゴリズムをはじめとして複数が紹介がされています。  第4章が評価関数を扱っています。  リバーシの開発を行うのであれば必読と思います。  立ち読みで内容を確認してみてください。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

構造体を使って、bestの値だけでなく、その座標も返せばいいのでは。 途中の計算では、評価点だけを見ればいいです。

tomatokechappa
質問者

補足

回答ありがとうございます。 構造体はわかるのですが、関数の中でどのように実装すればよいかわかりません。 よろしければお教えいただけないでしょうか

回答No.3

Cじゃないんですが、このページか Scheme言語(Lisp言語)によるミニマックス法の解説: http://www.geocities.jp/m_hiroi/func/abcscm43.html あるいはこのページ Python言語によるミニマックス法の解説: http://www.geocities.jp/m_hiroi/light/pyalgo24.html が参考になるんじゃないでしょうか。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

best を更新するときに「どこに置いたのか」を覚えておく.

tomatokechappa
質問者

補足

回答ありがとうございます。 bestを更新するときにどこに置いたのかを覚えておくために、仮にxとy座標を覚える変数にそれを代入して、再帰関数で最終的に一番浅い階層の親の座標をコマとして置きたいのですが、どのようにすればいいかわかりません。 下のようにmini_max_x,mini_max_yを関数外で宣言して記憶するようにしたのですが、これでは一番下の階層の子節点の座標が表示されてしまいます。 しかしうまくいくような実装法が考えられませんでしたので、よろしければどのようにすればよいかお教えください。 ________if(turn == 先手 && best < val){ __________best= val; __________mini_max_x = j; __________mini_max_y = i; ________} ________if(turn == 後手 && best <-val){ __________best= -val; __________mini_max_x = j; __________mini_max_y = i; ________}

  • ok-kaneto
  • ベストアンサー率39% (1798/4531)
回答No.1

一般的には「おける場所すべてに総当たり方式でおいてみる」でしょうね。 評価関数の戻り値に評価値、引数に置く場所の座標を与えます。 で、すべての組み合わせの座標を試してみて最大の効果を得られる場所の座標を記録しておきます。

tomatokechappa
質問者

補足

回答ありがとうございます。質問の仕方が悪かったので訂正します。 今ネットを参考にしつつ自分で作った関数があるのですが、下のようなもので オセロ盤をxxx[SIZE][SIZE];でSIZE 8と定義してあります。 allDireCheckでは、渡された座標がおくことができるなら置き1を返すという処理をするものです。 この関数内でx,y座標を記憶し最終的に返すとなるとどこにどのように書けばよいかわかりません。 おおまかに教えてくださるとうれしいです。 int Minimax(手番 turn, 先読みの深さ depth){ __int val,best; __/* 葉の場合、評価値を返す */ __if(depth == 0) return eval(); __best = -1000000; __for(int i = 0 ; i < SIZE ; i++) { ____for(int j = 0 ; j < SIZE ; j++) { ______if( allDireCheck(turn,j,i) ){ ________val = Minimax(次の turn, depth-1); ________if(turn == 先手 && best < val) best= val; ________if(turn == 後手 && best <-val) best=-val; ________盤面を1手戻す; ______} __return best; }

関連するQ&A

  • プログラミングによるオセロゲーム作成について

    今オセロゲームをCで作っているのですが、AIを作るところで行き詰ってしまいました。 とりあえずminiMax法で作ろうとしており参考にしているサイトのURLは http://hp.vector.co.jp/authors/VA015468/platina/algo/2_2.html です。 このサイトの for(最初の子節点の手; 未評価の子節点がある; 次の子節点に移る) という部分を見る限り先に子節点がいくつあるのか調べておく必要があると思うのですが、 調べる上で次の子節点を調べるときにその前に調べた子節点以外から探す方法が よくわからないのですが、どのような実装を行えばいいでしょうか。 おおまかな説明、流れをご教授お願いします。

  • 今DirectXでゲームを作っているのですが、どうしても実装できないこ

    今DirectXでゲームを作っているのですが、どうしても実装できないことがあります。 マウスカーソルの近くにある物体をスピードを落としながら話していくという仕様なのですが、ベクトルを使っての実装ができません。どうかわかる方がいましたら回答お願いします。 pV1.x;//マウスカーソルのx座標 pV1.y;//マウスカーソルのy座標 pV2.x;//物体のx座標 pV2.y;//物体のy座標 pOut1.x;//物体のx座標からマウスカーソルのx座標を引いた値 pOut1.y;//物体のy座標からマウスカーソルのy座標を引いた値 D3DXVec2Subtract(&pOut1,&pV2,&pV1);//pV2ベクトルからpV1ベクトルを引いてpOut1に格納する float VecLength=D3DXVec2Length(&pOut1);//pOut1ベクトルの大きさをVecLengthに格納する vecPosition.x=/*ここがわかりません*/ vecPosition.y=/*ここがわかりません*/

  • オセロを作成 助言お願いします・・・

    C言語を初めてもうすぐ1ヶ月ぐらいたつんですけど今ある知識の そうまとめとしてオセロを作成しています。 同じオセロでもソースを2つ作ろうと考えています。 まずは関数を使わないで作るオセロ もうひとつは関数を使うオセロです。 関数を使わないほうのオセロで困っています。今1ターンごとに白い 石を置いたり黒い石を置いたりするばしょをつくっていて 変数を1週ごとに1ずつ増やしていき奇数なら黒い石偶数なら白い石 みたいにしようと考え次のようなソースコードを書きました。 ----------------------ソースコード-------------------------- #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++){ //繰り返す(1) for(j=0;j<8;j++){ //繰り返す(2) if(bord[i][j] == 0){ //bord[i][j]は初期化により0なので printf("*"); } else if(bord[i][j] == 1){ printf("●"); } else{ printf("○"); } } printf("\n"); } if(player%2==0){ bord[i][j]=1; } else if(player%2==1){ bord[i][j]==0; } printf("y座標を入力してください。(縦軸)"); scanf_s("%d", &y); printf("x座標を入力してください。(横軸)"); scanf_s("%d", &x); //ひっくりかえす //エラー処理// 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] == 0){ bord[y][x]=1; } if(bord[y][x]==1) { bord[y][x]=2; } } //エラー処理// if(x<0 || x>=8 || y<0 || y>=8 ) { printf("許容範囲外です。\n"); } player++; } //無限loop終了地点 return 0; } -------------------------ソース終了-------------------------- 汚いソースで申し訳ありません。これを実行すると いつでも白の石しか置けないのです・・・ なのでヒントでもいいのでどうすればいいのか教えてください!  あともしよければはさまれたら石の色を変える部分も教えてくださると助かります。 ちなみに偶数かどうかの判定の部分は 「if(player%2==0){ bord[i][j]=1; } else if(player%2==1){ bord[i][j]==0; } 」 というところです。 ※質問などありましたらどうぞいってください。 ご回答お待ちしております。

  • MiniMax法のコードが分からない

       こんにちは。 前回では、MiniMax法がよくわからないと説明をしたのすが、Cのコード自体がよく分からない のでまた質問させていただきました。 自分は今、オセロゲームを制作しています。 http://hp.vector.co.jp/authors/VA015468/platina/algo/2_2.html このサイトにあるコードなのですが int mm_max(int t) /* 自局面の節点 tは葉局面までの手数 */ { int max = -N; /* Nは十分大きな値 */ int v; if(t == 0) return (現在の局面の評価値); for(最初の子節点の手; 未評価の子節点がある; 次の子節点に移る){ 局面に子節点の手を打つ; v = mm_min(t-1, alpha, beta); 局面を元に戻す; if(v > max) max = v; } return max; } mm_min(int t) /* 自局面の節点 tは葉局面までの手数 */ { int min = -N; /* Nは十分大きな値 */ int v; if(t == 0) return (現在の局面の評価値); for(最初の子節点の手; 未評価の子節点がある; 次の子節点に移る){ 局面に子節点の手を打つ; v = mm_max(t-1); 局面を元に戻す; if(v < min) min = v; } return min; } return (現在の局面の評価値); とあるのですが現在の局面の評価値というのは一体どういうものなんでしょうか? 最初の子節点の手; 未評価の子節点がある; 次の子節点に移る とありますが、 まず一手置いた場所を保存しておき、未評価の子節点を探すみたいですが、どのようになるのかうまく想像できません。   局面に子節点の手を打つ; というのは子節点というものにすでに置く座標の値があるんでしょうか?   局面を元にもどす。 というのはどういう意味でしょうか? すこしづつ子節点を戻していくということなんでしょうか?   よろしくお願いします。

  • Jupiter 5

    表題のWinマシン用ソフトと 同じ様な機能を持つソフト、 Mac用で知りません? http://hp.vector.co.jp/authors/VA015579/jp5.htm

    • 締切済み
    • Mac
  • 便利に使っていたIDSoftという会社のソフトが全て公開が停止されまし

    便利に使っていたIDSoftという会社のソフトが全て公開が停止されました。 何があったのか、ご存じの方は教えてください。 http://hp.vector.co.jp/authors/VA037304/

  • この古いゲームソフトがインストールできません

    この古いゲームソフトがインストールできません http://hp.vector.co.jp/authors/VA001954/mysoft.html のかなインベーダーの方が、Windows2000マシンに、インストールできません。必要なファイルが見つかりませんと出ます。漢字の方はなんとかできたのですが・・ vbrjp200.dllが必要とのことで、ウェブからダウンロードして、システムフォルダに入れようとしたのですが、新しいバージョンがすでにあるとのことなので、上書きはやめました。 どうしたらよいでしょうか?

  • プログラミングC言語

    プログラミングC言語の問題で、 「ベクトルの内積を用いて、2つのベクトルの成す角度を求めるプログラムを作成せよ。」 という問題をやっていて、以下の画像のような答えになるのですが、上手くいきません。 どのようにすればいいのでしょうか? 作ったソースコード #include<stdio.h> #include<math.h> double naiseki(int *vecterA, int *vecterB) { double rad, deg; rad = acos( (vecterA[0]*vecterB[0] + vecterA[1]*vecterB[1]) / ( sqrt((double)(vecterA[0]*vecterA[0] + vecterA[1]*vecterA[1])) * sqrt((double)(vecterB[0]*vecterB[0] + vecterB[1]*vecterB[1])) ) ); deg = rad/3.141592*180; return deg; } int main(void) { double va[2]; double vb[2]; printf("v1_x:"); scanf("%lf", &va[0]); printf("v1_y:"); scanf("%lf", &va[1]); printf("v2_x:"); scanf("%lf", &vb[0]); printf("v2_y:"); scanf("%lf", &vb[1]); puts("内積から求めたベクトルの角度は"); printf("%f",naiseki(va,vb)); puts("です。"); return(0); } 最後のnaiseki(va,vb)のところで互換性がありませんと でてしまいます。 double naiseki のソースコードはこのままでプログラムが 動くようにしてほしいです。 よろしくお願いします!

  • 「しぃ絵チャット」のHP設置方法

    「しぃ絵チャット」の下の「PaintChatApp for Win 」というのをDLしました。 HPにチャットのページを設置したいのですが、やり方が全然分かりません。 「しぃ絵チャット」をHPに設置する方法を教えて下さい。 http://hp.vector.co.jp/authors/VA016309/paintchat/download.html

  • EXCELを使ったスペルチェック

    言語はVB2005を使っています。 http://hp.vector.co.jp/authors/VA014465/lab/college/tool/vbstep05.html ここに載っているエクセルを使ったスペルチェックを作りたいと思っています。 もしこれのVB2005での作り方を知っている人やコードを持っている人、また作り方の載っているサイトがあったら教えてください! お願いします。

専門家に質問してみよう