zoukankan      html  css  js  c++  java
  • 简易五子棋评估函数

    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); // 在得到的点下棋
    }
    抓住青春的尾巴。。。
  • 相关阅读:
    [C/C++] 指针数组和数组指针
    [计算机网络] DNS劫持和DNS污染
    [计算机网络-数据链路层] CSMA、CSMA/CA、CSMA/CD详解
    [BinaryTree] 二叉树常考知识点
    NODE-windows 下安装nodejs及其配置环境
    MATLAB/Excel-如何将Excel数据导入MATLAB中
    Excel-怎样实现行列转置
    一篇文章学懂Shell脚本
    SQL-MySQL使用教程-对MySQL的初步尝试
    资源贴-在线编译环境推荐
  • 原文地址:https://www.cnblogs.com/xidian-mao/p/9336694.html
Copyright © 2011-2022 走看看