はりぼてリバーシの完成!

開発目標

このページの目標は、自由に思考ルーチンを改造してみることです。いくつかのアイデアを実装して、はりぼてリバーシの完成とします。

最後は数で勝負

今のところ、良い場所と悪い場所で点数を付けて盤を評価していますが、最終的には、そんなの関係ありません。数が多い方が勝ちです。まずは、それを実装します。

ReversiAI.java

//リバーシ思考ルーチン
//2011/09/25  by boco.hp3200.com
//--------------------------------------------------------------------------
package com.hp3200.boco.reversi;

public class ReversiAI {
    …略…
    
    //処 理:評価関数
    //引 数:myCoin……PLAYER or COM
    //戻り値:点数
    public int evaluationFunction(int myCoin) {
        int yourCoin = PLAYER;
        int i;
        int point = 0;
        int count = 0;
        
        //相手の石を設定
        if(myCoin==PLAYER) yourCoin = COM;
        
        //空白を数える
        for(i=11;i<=88;i++) {
            if(board[i]==BLANK) count ++;
        }
        //点数を計算
        if(count==0) {
            //最後は数で勝負
            for(i=11;i<=88;i++) {
                if(board[i]==myCoin) point ++;
                if(board[i]==yourCoin) point --;
            }
        } else {
            //有利な場所と不利な場所がある
            for(i=11;i<=88;i++) {
                if(board[i]==myCoin) point += POINT_MAP[i];
                if(board[i]==yourCoin) point -= POINT_MAP[i];
            }
        }

        //点数を返す
        return point;
    }

}

数を数えるだけなら読みを深くできる

最後は数を数えるだけなので、これならもっと深く読めるはず。そこで、8手くらい先から最後まで読みきることにします。

まずは、ReversiAIクラスに読みの深さを変更するためのメソッドを作ります。

ReversiAI.java

//リバーシ思考ルーチン
//2011/09/25  by boco.hp3200.com
//--------------------------------------------------------------------------
package com.hp3200.boco.reversi;

public class ReversiAI {
    …略…

    //処 理:読みの深さを決める
    //引 数:depth……読みの深さ
    //戻り値:なし
    public void setDepth(int depth) {
    	bestDepth = depth;
    }
    
}

そしてReversiViewクラスから、読みの深さをセットします。8手で最後まで読みきれる時は、読ますことにします。

ReversiView.java

package com.hp3200.boco.reversi;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;

class ReversiView extends View {
    …略…
    
    //描写処理
    @Override
    public void onDraw(Canvas c) {
        int count;
        …略…
        
        switch(page) {
        …略…
        case COM:
            count = 0;
            for(i=11;i<=88;i++) {
                if(board[i]==0) count ++;
            }
            if(count<=8) {
                ai.setDepth(8);
            } else {
                ai.setDepth(3);
            }
            ai.setBoard(board);
            ai.think(COM);
            place = ai.getPlace();
            //ページ移動
            page = REVERS;
            invalidate();
            break;
        …略…
        }
    }
    
    …略…
}

置ける場所は多い方が良い

「自分の置ける場所はできるだけ多く、相手の置ける場所はできるだけ少なく!」これを実装してみます。ここでは、置ける場所1つを10点くらいにしておきます。

ReversiAI.java

//リバーシ思考ルーチン
//2011/09/25  by boco.hp3200.com
//--------------------------------------------------------------------------
package com.hp3200.boco.reversi;

public class ReversiAI {
    …略…
    
    //処 理:評価関数
    //引 数:myCoin……PLAYER or COM
    //戻り値:点数
    public int evaluationFunction(int myCoin) {
        int yourCoin = PLAYER;
        int i;
        int point = 0;
        int count = 0;
        
        //相手の石を設定
        if(myCoin==PLAYER) yourCoin = COM;
        
        //空白を数える
        for(i=11;i<=88;i++) {
            if(board[i]==BLANK) count ++;
        }
        //点数を計算
        if(count==0) {
            //最後は数で勝負
            for(i=11;i<=88;i++) {
                if(board[i]==myCoin) point ++;
                if(board[i]==yourCoin) point --;
            }
        } else {
            //有利な場所と不利な場所がある
            for(i=11;i<=88;i++) {
                if(board[i]==myCoin) point += POINT_MAP[i];
                if(board[i]==yourCoin) point -= POINT_MAP[i];
            }
            //置ける場所は多い方が良い
            point += countPlace(myCoin)*10;
            point -= countPlace(yourCoin)*10;
        }

        //点数を返す
        return point;
    }

    //処 理:置ける場所を数える
    //引 数:myCoin……PLAYER or COM
    //戻り値:置ける場所数
    int countPlace(int myCoin) {
        int yourCoin = PLAYER;
        int i, j, p;
        int count = 0;
        boolean putting;

        //相手の石を設定
        if(myCoin==PLAYER) yourCoin = COM;

        //置ける場所を数える
        for(p=11;p<=88;p++) {
            putting = false;
            for(i=0;i<8;i++) {
                if(board[p+MOVE[i]]==yourCoin) {
                    for(j=2;j<8;j++) {
                        if(board[p+MOVE[i]*j]==myCoin) {
                            putting = true;
                            count ++;
                            break;
                        } else if(board[p+MOVE[i]*j]==yourCoin) {
                        } else {
                            break;
                        }
                    }
                    if(putting == true) break;
                }
            }
        }
        
        //置ける場所数を返す
        return count;
    }

}

開発結果

よし完成。Androidマーケットにアップしときます。誰かが、面白い改造をしてアップしてくれるのを待っています。