Gobang ai: The idea and implementation of the minimax search and α-β pruning algorithm (qt and c++) (4) Simple implementation of the calculation kill module

1. What is count as killing? Why is it counted as a kill?

Counting to kill is just to kill chess .

I used Gobang ai to play with others for a while and found that looking at the 6-level depth using the game tree (simulating ai to take 4 steps and the simulating human to take 3 steps) is actually not enough, because the real master can see far more than the 6th floor. . After the master makes a plan, at the beginning, he takes the position that seems " not so important ", and then he can form a double-live 3 or live 4 kill game to defeat ai. The ai that I realized is actually very short-sighted, that is, I can only see the benefits within the 6th floor, but cannot see the larger, overall benefits.

Here I refer to the article of this big man, which is very good, but I can't understand it very well, and I can only write it based on my own understanding: the fifth article of Gobang AI Algorithm-Counting Kill .

How to make the computer "planning" like this? A simple idea is to kill. It’s easy to think that counting a kill is just a kill game. It’s easy to think that counting a kill is also a minimax search . It’s just that you don’t need to consider the 10 nodes (previously implemented). You only need to consider the kill node of the white (ai) (to form a new). If the black is even 5, live 4, punch 4, live 3), black only considers the best node, then the number of branches b is greatly reduced, and the search depth can reach more than 16 layers (many of them cannot be searched for 16 layers, because there is no such More kill nodes), before reaching the search depth, as long as one node white wins, it will be successful even if it is killed. This is the count kill module that I simply implemented.

The kill calculation function I implemented is relatively simple, but it has further improved the chess power.

Second, the concrete realization

First, calculate the kill. If the kill is successful, use the kill point. If it is unsuccessful, use the point found in the original 6-level minimax search .

The first is to find the kill point for White.

QList<QPoint> chessAi::seek_kill_points(int (*board)[15]){
    
    //找白棋的连5,活4,冲4,活3的杀棋位置
    QList<QPoint> pointList;

    POINTS P=seekPoints(board);//一般来说,能冲4或者活3的必在评分前20的点内

    int sameBoard[15][15];
    copyBoard(board,sameBoard);

    for(int i=0;i<20;++i){
    
    
        sameBoard[P.pos[i].x()][P.pos[i].y()]=C_WHITE;//模拟落子
        if(evaluate(sameBoard).STAT[WIN]>0){
    
    //产生连5
            pointList.append(P.pos[i]);
        }else if(evaluate(sameBoard).STAT[FLEX4]>evaluate(board).STAT[FLEX4]){
    
    //产生新活4
            pointList.append(P.pos[i]);
        }else if(evaluate(sameBoard).STAT[BLOCK4]>evaluate(board).STAT[BLOCK4]){
    
    //产生新冲4
            pointList.append(P.pos[i]);
        }else if(evaluate(sameBoard).STAT[FLEX3]>evaluate(board).STAT[FLEX3]){
    
    //产生新活3
            pointList.append(P.pos[i]);
        }
        sameBoard[P.pos[i].x()][P.pos[i].y()]=C_NONE;//还原落子
    }
    return pointList;
}

Simple calculation to kill the module :

struct EVALUATION{
    
    
    int score;
    gameResult result;
    int STAT[8];//储存部分棋形的个数,下标WIN=1为白连5,LOSE=2为黑连5,FLEX4=3为白活4,BLOCK4=5为白冲4,FLEX3=7为白活3
};
struct POINTS{
    
    //最佳落子位置,[0]分数最高,[19]分数最低
    QPoint pos[20];
    int score[20];//此处落子的局势分数
};
struct DECISION{
    
    
    QPoint pos;//位置
    int eval;//对分数的评估
};

DECISION decision;

bool chessAi::analyse_kill(int (*board)[15], int depth){
    
    
    EVALUATION EVAL=evaluate(board);
    if(depth==0||EVAL.result!=R_DRAW){
    
    
        if(depth==0){
    
    //若抵达最深层,走一步对白棋的最好位置,若白棋还没赢则返回false
            POINTS P;
            P=seekPoints(board);            
            board[P.pos[0].x()][P.pos[0].y()]=C_WHITE;

            gameResult result=evaluate(board).result;
            if(result==R_WHITE)return true;
            else return false;
        }else if(EVAL.result==R_WHITE)return true;//找到白棋杀棋
        else return false;//白棋输
    }else if(depth%2==0){
    
    //max层,我方(白)决策
        QList<QPoint> pointList=seek_kill_points(board);//产生杀棋点

        if(pointList.length()==0)return false;//没有杀棋点
        for(auto i:pointList){
    
     
            int sameBoard[15][15];
            copyBoard(board,sameBoard);

            sameBoard[i.x()][i.y()]=C_WHITE;//模拟己方落子
            if(analyse_kill(sameBoard,depth-1)){
    
    
                if(depth==16){
    
    //开始层,需决定落子,结果存于decision中
                    decision.pos.setX(i.x());
                    decision.pos.setY(i.y());
                    decision.eval=INT_MAX;//杀棋评分没有作用
                }
                return true;
            }
        }
        return false;
    }else{
    
    //min层,敌方(黑)决策,只下对自己最好的棋
        int rBoard[15][15];
        reverseBoard(board,rBoard);
        POINTS P=seekPoints(rBoard);//找对于黑子的最佳位置,需要将棋盘不同颜色反转,因为seekPoint是求白色方的最佳位置

        int sameBoard[15][15];
        copyBoard(board,sameBoard);

        sameBoard[P.pos[0].x()][P.pos[0].y()]=C_BLACK;//模拟敌方落子:只走最好的一步
        //无需剪枝
        return analyse_kill(sameBoard,depth-1);
    }
}

//调用
if(!ai.analyse_kill(ai.chesses,16)){
    
    
     qDebug()<<"没找到杀棋";
     ai.analyse(ai.chesses,6,-INT_MAX,INT_MAX);
}else{
    
    
     qDebug()<<"找到了杀棋";
}

end

Simply writing a count-killing module still improves some of the chess skills.

The knowledge of chess game is still worth studying. When I was looking for information on Zhiwang.com, I found out that I can use Gomoku ai as my master's thesis. After reading it, I felt that. . Domestic paper review is indeed more watery. The real masters are on GitHub!

Guess you like

Origin blog.csdn.net/livingsu/article/details/104655537