ページ 11

5目並べを作っております

Posted: 2010年4月21日(水) 08:20
by アルル
DXライブラリで5目並べを作っており判定以外の実装は出来ました。
しかし判定について検討がつかなく質問させて頂きました。

Mapという二次元配列に白なら1、黒なら2というように入っております。
この値を見てどっちが勝ったかのWinF(int型)判定をしたいです。
動作は特に問題ないようなのですがソースはこんな感じで大丈夫なのでしょうか?
汚いソースで申し訳ないのですがアドバイスを頂けないでしょうか?
一部抜粋

#define        CEL_W    18
#define        CEL_H    18
int Map[CEL_H][CEL_W];

    bool Check = false;
    for(int i=0; i<CEL_H; i++){
        for(int j=0; j<CEL_W; j++){
            for(int Num=1; Num<PlayCount+1; Num++){

                // 横
                if(j < CEL_W-3){
                    if(Map[j] == Num && Map[j+1] == Num && Map[j+2] == Num && Map[j+3] == Num ) Check = true;
                }
                
                // 縦
                if(i < CEL_H-3){
                    if(Map[j] == Num && Map[i+1][j] == Num && Map[i+2][j] == Num && Map[i+3][j] == Num ) Check = true;
                }
                
                // 斜め右下
                if(i < CEL_H-3 && j < CEL_W-3){
                    if(Map[j] == Num && Map[i+1][j+1] == Num && Map[i+2][j+2] == Num && Map[i+3][j+3] == Num ) Check = true;
                }

                // 斜め右上
                if(i > 3 && j < CEL_W-3){
                    if(Map[j] == Num && Map[i-1][j+1] == Num && Map[i-2][j+2] == Num && Map[i-3][j+3] == Num ) Check = true;
                }

                if(Check){
                    WinF = Num;
                }
                Check = false;
            }
        }
    }

Re:5目並べを作っております

Posted: 2010年4月21日(水) 09:07
by たいちう
判定部分は関数の形にして貼り付けた方が、読む人に判りやすいです。
プログラムの構造上もその方が良いと思いますが、そうなってませんか?

ぱっと見て気付くのは、この判定が4目の連続しか見ていないことです。
4目並べなのですか?それともリーチの判定?

その他、細かい点で気付いたこともありますが、
手始めに判定関数のテスト用のデータを用意して試してみるべきでしょう。

Re:5目並べを作っております

Posted: 2010年4月22日(木) 07:55
by アルル
すみません(汗)
添付したのはリーチの判定でした><
良くわかりましたね・・・。

又、PG上では関数になっております。
テストデータを用意して試してみたのですが問題はないのですが
配列なので領域を壊していたら怖いので質問させて頂きました。

又、ソースを作っていて気になったのですがオセロ等は置いてあるところと
隣接していないとおけないですよね?
あの判定ってどうやって行っているのでしょうか?
bool checkF = false;
    for(int i=0; i<CEL_H; i++){
        for(int j=0; j<CEL_W; j++){
            if(Map[j] != 0) checkF = true;
        }
    }
    // 置いてあるかどうか
    if(checkF == false){
        if(Cy == CEL_H-1 && Map[Cy][Cx] == 0){
            Map[Cy][Cx] = PlayNum;
        }
    }else{
        if(Cy > 0 && Cy < CEL_H-1 && Cx > 0 && Cx < CEL_W-1){
            if(Map[Cy+1][Cx] != 0 || Map[Cy-1][Cx] != 0 || Map[Cy][Cx-1] != 0 || Map[Cy][Cx+1] != 0){
                if(Map[Cy][Cx] == 0) Map[Cy][Cx] = PlayNum;
            }
        }else if(Cx == 0){
            
        }        
    }


自分なりに実装しようと思ったのですがよく理解できませんでした。
宜しければサンプルとなるソースを書いては頂けないでしょうか?
丸投げとなってしまい申し訳ないと思っているのですが
一度、配列を使ったPGで人が作った綺麗な判定のソースをみてみたいんです・・・。

今後の為にもお力添えを願えないでしょうか?

Re:5目並べを作っております

Posted: 2010年4月22日(木) 09:11
by たいちう
> 添付したのはリーチの判定でした><

リーチの判定だとしても不完全だと思います。
(4, 1)に相手の石が置いてなければ、
{ (1, 1), (2, 1), (3, 1), (5, 1) } の並びはリーチとすべきでしょう。

逆に、(1, 1)と(6, 1)に相手の石が置いてあるならば、
{ (2, 1), (3, 1), (4, 1), (5, 1) } の並びはリーチではありません。


> 又、ソースを作っていて気になったのですがオセロ等は置いてあるところと
> 隣接していないとおけないですよね?
>
> 自分なりに実装しようと思ったのですがよく理解できませんでした。
> 宜しければサンプルとなるソースを書いては頂けないでしょうか?

意図が判りません。5目並べに隣接の判定は必須ではないですよね?
単にお手本として似たようなゲームのソースコードが欲しい、
というだけでしたら、書籍と(半分ネタとして)動画を紹介します。

『リバーシのアルゴリズム C++&Java対応―「探索アルゴリズム」「評価関数」の設計と実装』
http://www.amazon.co.jp/dp/4875934289

【プログラミング】オセロを1 時間で作ってみた【実況解説】
[nico]http://www.nicovideo.jp/watch/sm8391299[/nico]