簡易五子棋評估函數


void CFiveChessDlg::ComputerDown()
{
    int mode = 0, cur = 0, curX = 0, curY = 0, sum1 = 0, sum2 = 0;
    int x = 0, y = 0, cx = 0, cy = 0, cPrior = 0, prior = 0, flgL = 0, flgR = 0;

    for (x = 0; x < 15; x++)
    {
        for (y = 0; y < 15; y++)
        {    // 掃描全部空白點
            if (chessData[x][y] == 0)
            {
                prior = 0;
                for (mode = 1; mode < 5; mode++)    // 模式1為 — 向判斷,模式2為 | 向判斷
                {                            // 模式3為 \ 向判斷,模式4為 / 向判斷
                    sum1 = sum2 = 0;
                    flgL = flgR = 0;
                    curX = x;
                    curY = y; //改變模式后重置變量
                    for (cur = -4; cur <= 4; cur++)
                    {
                        if (mode == 1) //向→檢查
                        {
                            curX = x + cur;
                            if (curX < 0) continue; //左越界繼續
                            if (curX > 14) break;   //右越界停止
                        }
                        if (mode == 2) //向↓檢查
                        {
                            curY = y + cur;
                            if (curY < 0) continue; //上越界繼續
                            if (curY > 14) break;   //下越界停止
                        }
                        if (mode == 3) //向↘檢查
                        {
                            curX = x + cur;
                            curY = y + cur;
                            if (curX < 0 || curY < 0) continue; // 左或上越界繼續
                            if (curX > 14 || curY > 14) break;  // 右或下越界停止
                        }
                        if (mode == 4) //向↗檢查
                        {
                            curX = x + cur;
                            curY = y - cur;
                            if (curX < 0 || curY>14) continue; // 左或下越界繼續
                            if (curX > 14 || curY < 0) break;  // 右或上越界停止
                        }

                        // 初始化棋子標志,用於判斷反色
                        if (cur < 0 && flgL == 0 && chessData[curX][curY] != 0)
                            flgL = chessData[curX][curY];

                        if (cur > 0 && flgR == 0 && chessData[curX][curY] != 0)
                            flgR = chessData[curX][curY];

                        if (cur < 0 && chessData[curX][curY] == (-flgL))
                        {
                            sum1 = -1;        // 左側搜索到反色,相當於被堵住的棋
                            flgL = -flgL;    // 同時標記也取反
                        }

                        if (cur < 0 && chessData[curX][curY] == flgL)
                        {
                            sum1++; // 左側搜索到同色
                        }

                        if (cur == -1 && sum1 > 0 && chessData[curX][curY] == 0)
                        {
                            sum1--; // 左一位搜索到空棋
                        }
                        if (cur == 1 && sum2 > 0 && chessData[curX][curY] == 0)
                        {
                            sum2--; // 右一位搜索到空棋
                        }

                        if (cur > 0 && flgL == flgR) // 如果左邊的棋子和右邊的同色
                        {
                            sum2 += sum1; // 用sum2代替sum1繼續搜索
                            sum1 = 0;     // sum1置0以防重復相加和影響后面的cPrior
                        }

                        if (cur > 0 && chessData[curX][curY] == (-flgR))
                        {
                            sum2--; // 右邊出現反色則,相當於被堵住的棋
                            break;   // 不需要繼續搜索了
                        }

                        if (cur > 0 && chessData[curX][curY] == flgR)
                        {
                            sum2++;// 右側搜索到同色
                        }

                    }
                    // 長連相對短連擁有絕對的優勢
                    if (sum1 == 1) prior = prior + 1;
                    if (sum1 == 2) prior = prior + 10 - 2 * flgL; // 數目相同白棋優先
                    if (sum1 == 3) prior = prior + 100 - 20 * flgL;
                    if (sum1 == 4) prior = prior + 1000 - 200 * flgL;
                    if (sum2 == 1) prior = prior + 1;
                    if (sum2 == 2) prior = prior + 10 - 2 * flgR;
                    if (sum2 == 3) prior = prior + 100 - 20 * flgR;
                    if (sum2 == 4) prior = prior + 1000 - 200 * flgR;
                }

                if (prior > cPrior)
                {
                    cPrior = prior;
                    cx = x;
                    cy = y;
                }

                if (prior == cPrior && rand() < RAND_MAX / 5)
                {    // 除第一個棋外很少有優先級相等的點
                    cPrior = prior;
                    cx = x;
                    cy = y;
                }
            }
        }
    }

    PutDown(cx, cy); // 在得到的點下棋
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM