예제 #1
0
        //到达末端结点则进行一次终盘模拟
        private void simulate(nodes node, int currentside, int firstplayer)
        {
            //叶子结点为最终节点
            if (checkboard(node.board) != -1)//即游戏已结束
            {
                if (checkboard(node.board) == 1)
                {
                    node.sim_Num++;
                    node.win_Num++;
                }
                else if (checkboard(node.board) == 0)
                {
                    node.sim_Num++;//模拟数+1
                }
                else
                {
                    node.sim_Num++;
                    node.win_Num += 0.5;
                }
            }
            else//游戏没结束则扩展节点
            {
                expand(node);//扩展末端节点,被扩展的子节点内只有Move
                int   temp   = rand.Next(node.child.Count);              //随机选择一个末端子节点
                simap board2 = node.child[temp].board.createDeepClone(); //复制末端子节点的地图

                while (checkboard(board2) == -1)                         //循环进行模拟直到终局
                {
                    doRandomMove(board2);
                }

                //更新末端节点胜利数与模拟数
                if (checkboard(board2) == 1) //终局模拟返回为胜
                {
                    node.win_Num++;          //末端子节点胜利数+1
                    node.sim_Num++;          //末端子节点模拟数+1
                }
                else if (checkboard(board2) == 0.5)
                {
                    node.win_Num += 0.5;
                    node.sim_Num++;
                }
                else
                {
                    node.sim_Num++;
                }
            }
        }
예제 #2
0
        private double cal_flipping(nodes node)
        {
            double point = 0;

            if ((node.board.currentside == 0) && (node.board.firstplayer == 0) || (node.board.currentside == 1) && (node.board.firstplayer == 1))//现在先手且先手为红或者现在后手且先手为蓝
            {
                point = (1) * (node.board.Prjiang * 20 + node.board.Prshi * node.board.Prxiang * 6 + node.board.Prche * 4 + node.board.Prma * 3 + node.board.Przu * 2 + node.board.Prpao * 6) + (-1)
                        * (node.board.Pbjiang * 20 + node.board.Pbshi * node.board.Pbxiang * 6 + node.board.Pbche * 4 + node.board.Pbma * 3 + node.board.Pbzu * 2 + node.board.Pbpao * 6);
            }
            else if ((node.board.currentside == 1) && (node.board.firstplayer == 0) || (node.board.currentside == 0) && (node.board.firstplayer == 1))//现在后手且先手为红或者现在先手且先手为蓝
            {
                point = (-1) * (node.board.Prjiang * 20 + node.board.Prshi * node.board.Prxiang * 6 + node.board.Prche * 4 + node.board.Prma * 3 + node.board.Przu * 2 + node.board.Prpao * 6) + (1)
                        * (node.board.Pbjiang * 20 + node.board.Pbshi * node.board.Pbxiang * 6 + node.board.Pbche * 4 + node.board.Pbma * 3 + node.board.Pbzu * 2 + node.board.Pbpao * 6);
            }
            return(point);
        }
예제 #3
0
        public nodes(nodes parent)//创造节点的方法
        {
            this.parent = parent;
            ucb         = 10;                 //初始化UCB值为10
            sim_Num     = 0;                  //初始化节点模拟数为零
            win_Num     = 0;                  //初始化结点胜利数为零
            child       = new List <nodes>(); //创造出子节点序列
            Move movtion = new CDC.Move();

            win_ratio          = 0;//胜率
            turn               = 0;
            visit              = 0;
            alpha              = -1000;
            beta               = 1000;
            remain_flip_number = 0;
            resign             = -1;
        }
예제 #4
0
        //得到最大UCB值节点,并通过常数控制保证没被模拟过的节点仍会被选择到
        private Move best_move(nodes rootnode)
        {
            double maxwin_ratio = -1;
            nodes  bestnode     = new nodes();

            rand = new Random();

            for (int i = 0; i < rootnode.child.Count; i++)
            {
                if (rootnode.child[i].win_ratio > maxwin_ratio)
                {
                    maxwin_ratio = rootnode.child[i].win_ratio;
                    max_child    = i;
                    bestnode     = rootnode.child[i];
                }
            }
            return(bestnode.movtion);
        }
예제 #5
0
        //到达末端结点则进行一次终盘模拟
        private void simulate(nodes node, int currentside, int firstplayer)
        {
            block[][] matrix = node.board;//末端节点的地图信息

            //叶子结点为最终节点
            if (checkboard(node.board, currentside, firstplayer) != -1)//即游戏已结束
            {
                if (checkboard(node.board, node.side, firstplayer) == 1)
                {
                    node.sim_Num++;
                    node.win_Num++;
                }
                else
                {
                    node.sim_Num++;//模拟数+1
                }
            }
            else//游戏没结束则扩展节点
            {
                expand(node);//扩展末端节点,被扩展的子节点内只有Move

                int       tempNodeNum = rand.Next(node.child.Count); //随机选择一个子节点
                int       nowside;
                block[][] board2 = node.child[tempNodeNum].board;    //创造末端子节点的地图

                //循环进行模拟直到终局
                for (int k = board2.getTurnCount(); k < board2.getTurnLimit() && checkboard(board2, 0) == -1; k++)
                {
                    doOneTurnMove(board2, nowside++ % 2);
                }

                //更新末端节点胜利数与模拟数
                if (checkboard(board2, node.side, firstplayer) == 1) //终局模拟返回为胜
                {
                    node.win_Num++;                                  //末端子节点胜利数+1
                    node.sim_Num++;                                  //末端子节点模拟数+1
                }
                else
                {
                    node.sim_Num++;
                }
            }
        }
예제 #6
0
        //得到最大UCB值节点,并通过常数控制保证没被模拟过的节点仍会被选择到
        private Move best_move(nodes rootnode)
        {
            int    temp;
            double maxucb   = -1;
            nodes  bestnode = new nodes();

            rand = new Random();

            for (int i = 0; i < rootnode.child.Count; i++)
            {
                if (rootnode.child[i].ucb > maxucb)
                {
                    maxucb    = rootnode.child[i].ucb;
                    max_child = i;
                    bestnode  = rootnode.child[max_child];
                }
            }
            if (maxucb == 10)
            {
                temp     = rand.Next(rootnode.child.Count);
                bestnode = rootnode.child[temp];
            }
            return(bestnode.movtion);
        }
예제 #7
0
        private bool deloop(nodes node, Map map)
        {
            bool value = false;
            int  n     = 0;

            if (map.Plyr_move.Count >= 6)
            {
                for (int i = map.Plyr_move.Count - 6; i < map.Plyr_move.Count - 1; i++)//重复度检查
                {
                    if (map.Plyr_move[i].movtion.froX == node.movtion.froX && map.Plyr_move[i].movtion.froY == node.movtion.froY &&
                        map.Plyr_move[i].movtion.desX == node.movtion.desX && map.Plyr_move[i].movtion.desY == node.movtion.desY)
                    {
                        n += 1;
                    }
                }
            }

            if (n >= 3)//多次重复
            {
                value = true;
                Console.WriteLine("Repeation Draw!!!!");
            }
            return(value);
        }
예제 #8
0
        private bool deloop(nodes node, Map map)
        {
            bool value = false;

            if (map.currentside == 0)//为先手方时调用先手方历史纪录
            {
                int n = 0;
                if (map.Plyr1move.Count <= 6)
                {
                    for (int i = 0; i < map.Plyr1move.Count - 1; i++)//重复度检查
                    {
                        if (map.Plyr1move[i].movtion.froX == node.movtion.froX && map.Plyr1move[i].movtion.froY == node.movtion.froY &&
                            map.Plyr1move[i].movtion.desX == node.movtion.desX && map.Plyr1move[i].movtion.desY == node.movtion.desY)
                        {
                            n += 1;
                        }
                    }
                }
                else
                {
                    for (int i = map.Plyr1move.Count - 6; i < map.Plyr1move.Count - 1; i++)//重复度检查
                    {
                        if (map.Plyr1move[i].movtion.froX == node.movtion.froX && map.Plyr1move[i].movtion.froY == node.movtion.froY &&
                            map.Plyr1move[i].movtion.desX == node.movtion.desX && map.Plyr1move[i].movtion.desY == node.movtion.desY)
                        {
                            n += 1;
                        }
                    }
                }

                if (n >= 3)//多次重复
                {
                    value = true;
                    Console.WriteLine("Found Repeat!");
                }
            }
            else if (map.currentside == 1)//为后手方时调用后手方历史纪录
            {
                int m = 0;
                if (map.Plyr2move.Count <= 6)
                {
                    for (int i = 0; i < map.Plyr2move.Count - 1; i++)//重复度检查
                    {
                        if (map.Plyr2move[i].movtion.froX == node.movtion.froX && map.Plyr2move[i].movtion.froY == node.movtion.froY &&
                            map.Plyr2move[i].movtion.desX == node.movtion.desX && map.Plyr2move[i].movtion.desY == node.movtion.desY)
                        {
                            m += 1;
                        }
                    }
                }
                else
                {
                    for (int i = map.Plyr2move.Count - 6; i < map.Plyr2move.Count - 1; i++)//重复度检查
                    {
                        if (map.Plyr2move[i].movtion.froX == node.movtion.froX && map.Plyr2move[i].movtion.froY == node.movtion.froY &&
                            map.Plyr2move[i].movtion.desX == node.movtion.desX && map.Plyr2move[i].movtion.desY == node.movtion.desY)
                        {
                            m += 1;
                        }
                    }
                }

                if (m >= 3)//多次重复
                {
                    value = true;
                    Console.WriteLine("Found Repeat!");
                }
            }
            return(value);
        }
예제 #9
0
        public nodes subAI_Evaluate(Map map)
        {
            simap map2 = new CDC.simap();

            map2 = map2.createDeepClone(map);            //复制一下地图
            List <Move> movtionlist = new List <Move>(); //移动指令表
            List <Move> fliplist    = new List <Move>(); //翻棋指令表
            List <Move> Alllist     = new List <Move>(); //翻棋指令表
            Move        bestmove    = new CDC.Move();    //最佳动作
            Move        bestflip    = new Move();        //最佳翻棋
            Move        startflip   = new Move();        //起始翻棋
            nodes       bestnode    = new nodes();

            if (map2.turncount == 1)                                                                    //一局开始
            {
                fliplist              = AI_tools.getallfliplist(map2);                                  //可翻行动列表
                startflip             = fliplist[rand.Next(fliplist.Count)];                            //起始翻
                map2.firstplayer      = map.Matrix[startflip.froX, startflip.froY].item.side;           //第一个棋子即为第一玩家的颜色
                map2.secondplayer     = (map.Matrix[startflip.froX, startflip.froY].item.side + 1) % 2; //第二玩家为另一颜色
                map2.currentside      = map2.firstplayer;
                bestnode.movtion.froX = startflip.froX;
                bestnode.movtion.froY = startflip.froY;
                bestnode.movtion.desX = startflip.desX;
                bestnode.movtion.desY = startflip.desY;
                return(bestnode);
            }
            else//非开局
            {
                int point;
                int Maxpoint = 0;
                movtionlist = AI_tools.getallmove(map2);            //获取所有可行指令
                foreach (Move movtion in movtionlist)               //遍历进攻选项
                {
                    point = AI_tools.point_Evaluate(map2, movtion); //计算进攻选项得点
                    if (point > Maxpoint)                           //判断得点最大
                    {
                        Maxpoint = point;
                        bestmove = movtion;
                        bestnode.movtion.froX = bestmove.froX;
                        bestnode.movtion.froY = bestmove.froY;
                        bestnode.movtion.desX = bestmove.desX;
                        bestnode.movtion.desY = bestmove.desY;
                        return(bestnode);
                    }
                }
                if (Maxpoint == 0)//为移动指令时
                {
                    if (movtionlist.Count != 0)
                    {
                        bestmove = getnear(map2, map2.currentside);
                    }
                    Alllist = AI_tools.getmovflip(map2);
                    if (Alllist.Count == 0)
                    {
                        checkboard(map2);
                    }
                    bestmove = Alllist[rand.Next(Alllist.Count)];//无有效步的时候生成随机步数
                }
            }
            bestnode.movtion.froX = bestmove.froX;
            bestnode.movtion.froY = bestmove.froY;
            bestnode.movtion.desX = bestmove.desX;
            bestnode.movtion.desY = bestmove.desY;
            return(bestnode);
        }
예제 #10
0
        private double score(nodes node)
        {
            List <Move> flippingList = new List <Move>();

            flippingList = AI_tools.getallfliplist(node.board);
            double point = 0;
            double score = 0;

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if ((node.board.Matrix[i, j].item.side == node.board.firstplayer && currentside == 0 && node.board.Matrix[i, j].flip == 1) ||
                        (node.board.Matrix[i, j].item.side == node.board.secondplayer && currentside == 1 && node.board.Matrix[i, j].flip == 1)) //针对根结点行动方的估值
                                                                                                                                                 //确保在相同手时使用最大值,对方手时使用最小值
                    {
                        switch (node.board.Matrix[i, j].item.type)
                        {
                        case chesstype.jiang:
                            point = 20;
                            break;

                        case chesstype.shi:
                            point = 10;
                            break;

                        case chesstype.xiang:
                            point = 6;
                            break;

                        case chesstype.che:
                            point = 4;
                            break;

                        case chesstype.ma:
                            point = 3;
                            break;

                        case chesstype.zu:
                            point = 2;
                            break;

                        case chesstype.pao:
                            point = 6;
                            break;

                        case chesstype.blank:    //移动
                            point = 0;
                            break;
                        }
                    }
                    if ((node.board.Matrix[i, j].item.side == node.board.firstplayer && currentside == 1 && node.board.Matrix[i, j].flip == 1) ||
                        (node.board.Matrix[i, j].item.side == node.board.secondplayer && currentside == 0 && node.board.Matrix[i, j].flip == 1))
                    {
                        switch (node.board.Matrix[i, j].item.type)
                        {
                        case chesstype.jiang:
                            point = -20;
                            break;

                        case chesstype.shi:
                            point = -10;
                            break;

                        case chesstype.xiang:
                            point = -6;
                            break;

                        case chesstype.che:
                            point = -4;
                            break;

                        case chesstype.ma:
                            point = -3;
                            break;

                        case chesstype.zu:
                            point = -2;
                            break;

                        case chesstype.pao:
                            point = -6;
                            break;

                        case chesstype.blank:    //移动
                            point = 0;
                            break;
                        }
                    }
                    if (node.board.Matrix[i, j].item.side == 2)
                    {
                        point = 0;
                    }

                    for (int b = 0; b < 4; b++)
                    {
                        for (int a = 0; a < 8; a++)
                        {
                            if (((Math.Abs(b - i) <= 1) && (Math.Abs(a - j) <= 1)) && node.board.Matrix[b, a].flip == 1 && node.board.Matrix[b, a].item.side != 2)
                            {
                                Move movtion  = new Move();
                                Move movtion2 = new Move();

                                movtion.froX = i;
                                movtion.froY = j;
                                movtion.desX = b;
                                movtion.desY = a;

                                if (GameController.checkmove(node.board, movtion) == true)
                                {
                                    point = point * 1.25;
                                }

                                movtion2.froX = b;
                                movtion2.froY = a;
                                movtion2.desX = i;
                                movtion2.desY = j;

                                if (GameController.checkmove(node.board, movtion2) == true)
                                {
                                    point = point * 0.75;
                                }
                            }
                        }
                    }
                    score += point;
                }
            }

            if (node.movtion.desX == -1 && node.movtion.desY == -1 && node.movtion.froX != -1 && node.movtion.froY != -1)//节点为翻棋面节点时
            {
                point = cal_flipping(node);
                for (int b = 0; b < 4; b++)
                {
                    for (int a = 0; a < 8; a++)
                    {
                        if (((Math.Abs(b - node.movtion.froX) <= 1) && (Math.Abs(a - node.movtion.froY) <= 1)) && node.board.Matrix[b, a].flip == 1 && node.board.Matrix[b, a].item.side != 2)
                        {
                            Move movtion  = new Move();
                            Move movtion2 = new Move();

                            movtion.froX = node.movtion.froX;
                            movtion.froY = node.movtion.froY;
                            movtion.desX = b;
                            movtion.desY = a;

                            if (GameController.checkmove(node.board, movtion) == true)
                            {
                                point = point * 1.25;
                            }

                            movtion2.froX = b;
                            movtion2.froY = a;
                            movtion2.desX = node.movtion.froX;
                            movtion2.desY = node.movtion.froY;

                            if (GameController.checkmove(node.board, movtion2) == true)
                            {
                                point = point * 0.75;
                            }
                        }
                    }
                }
                score += point;
            }
            return(score);
        }
예제 #11
0
        private nodes smartflipping(nodes rootnode, Map map)
        {
            int         flippedpiece = 0;
            double      temp_value   = 0;
            double      min_risk     = 100;
            int         mark         = 0;
            nodes       nodesmove    = new nodes();
            List <Move> flippingList = new List <Move>();

            flippingList = AI_tools.getallfliplist(rootnode.board);
            Map mapasses = new Map();

            mapasses = map.createDeepClone();

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (rootnode.board.Matrix[i, j].flip == 1)
                    {
                        flippedpiece += 1;
                    }
                }
            }
            //第一阶段,只要相邻格有敌方棋子则不翻
            for (int i = 0; i < flippingList.Count; i++)
            {
                for (int a = 0; a < 4; a++)
                {
                    for (int b = 0; b < 8; b++)
                    {
                        if ((((Math.Abs(a - flippingList[i].froX) == 0) && (Math.Abs(b - flippingList[i].froY) == 1)) || ((Math.Abs(a - flippingList[i].froX) == 1) && (Math.Abs(b - flippingList[i].froY) == 0))) && //与翻棋坐标相邻的
                            ((rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.firstplayer && rootnode.board.currentside == 1) ||
                             (rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.secondplayer && rootnode.board.currentside == 0)))                                     //周围的非己方棋子
                        {
                            mark++;
                        }
                    }
                }
                if (mark != 0)
                {
                    flippingList.Remove(flippingList[i]); //则去掉这样一个元素
                    mark = 0;                             //清除
                    continue;
                }
            }
            if (flippingList.Count != 0)//存在保守翻棋策略
            {
                nodesmove.remain_flip_number = flippingList.Count;
                nodesmove.movtion.froX       = flippingList[rand.Next(flippingList.Count)].froX;
                nodesmove.movtion.froY       = flippingList[rand.Next(flippingList.Count)].froY;
            }
            //第二阶段,不存在完全保守的策略时
            else if (flippingList.Count == 0)                           //不存在保守翻棋策略
            {
                flippingList = AI_tools.getallfliplist(rootnode.board); //重新刷进flippinglist
                mark         = 0;                                       //清除mark
                for (int i = 0; i < flippingList.Count; i++)
                {
                    for (int a = 0; a < 4; a++)
                    {
                        for (int b = 0; b < 8; b++)
                        {
                            if ((((Math.Abs(a - flippingList[i].froX) == 0) && (Math.Abs(b - flippingList[i].froY) == 1)) || ((Math.Abs(a - flippingList[i].froX) == 1) && (Math.Abs(b - flippingList[i].froY) == 0))) && //与翻棋坐标相邻的
                                ((rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.firstplayer && rootnode.board.currentside == 1) ||
                                 (rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.secondplayer && rootnode.board.currentside == 0)))                                     //周围的已经翻开的非己方棋子
                            {
                                temp_value = cal_risk(a, b, map);
                                if (temp_value == -1000)//绝对会被吃掉的情况
                                {
                                    mark++;
                                }
                                else
                                {
                                    flippingList[i].risk += cal_risk(a, b, map);
                                }
                            }
                        }
                    }
                    if (mark != 0)
                    {
                        flippingList.Remove(flippingList[i]); //则去掉这样一个元素
                        mark = 0;                             //清除
                        continue;
                    }
                }
                for (int i = 0; i < flippingList.Count; i++) //选择威胁值最小的翻棋步骤
                {
                    if (flippingList[i].risk <= min_risk)    //越高的正值
                    {
                        nodesmove.remain_flip_number = flippingList.Count;
                        nodesmove.movtion.froX       = flippingList[i].froX;
                        nodesmove.movtion.froY       = flippingList[i].froY;
                    }
                }
            }
            return(nodesmove);
        }
예제 #12
0
        public nodes alpha_Beta(Map map)
        {
            //start rootnode;
            nodes       rootnode   = new nodes();
            simap       board      = new simap();
            nodes       bestnode   = new nodes();
            List <Move> atkmovtion = new List <Move>();
            List <Move> allmovtion = new List <Move>();
            double      maxscore   = -1000;

            board          = board.createDeepClone(map);
            rootnode.board = board;
            rootnode.depth = 0;//根节点的深度为零
            currentside    = rootnode.board.currentside;

            atkmovtion = AI_tools.getallatk(board);
            allmovtion = AI_tools.getallmove(board);

            alphabeta(rootnode);
            Console.WriteLine("CUT:" + cut + "\r\n\r\n\r\n");

            foreach (nodes child in rootnode.child)
            {
                if (child.visit == 0)
                {
                    continue;
                }
                else if (maxscore <= child.beta)
                {
                    maxscore = child.beta;
                    bestnode = child;
                }
            }

            if (deloop(bestnode, map) == true)//6步里2步以上重复 且为bestnode  则跳出
            {
                rootnode.child.Remove(bestnode);

                if (map.unflipped > 0)
                {
                    bestnode = smartflipping(rootnode, map);
                }
                else if (map.unflipped == 0 && rootnode.child.Count != 0)
                {
                    foreach (nodes achild in rootnode.child)
                    {
                        if (maxscore <= achild.beta)
                        {
                            maxscore = achild.beta;
                            bestnode = achild;
                        }
                    }
                }
                else if (map.unflipped == 0 && rootnode.child.Count == 0)
                {
                    bestnode = subAI_Evaluate(map);
                }
            }

            if (bestnode.movtion.desX == -1 && bestnode.movtion.desY == -1)
            {
                bestnode = smartflipping(rootnode, map);
            }

            return(bestnode);
        }
예제 #13
0
        private double alphabeta(nodes node)
        {
            loop_number++;
            double rvalue = 0;

            if (node.depth < limitdepth && node.visit == 0)
            {
                atk_expand(node);
                if (node.depth != 0)
                {
                    if (node.depth % 2 == 0)//极大结点继承上界
                    {
                        node.beta = node.parent.beta;
                    }
                    else//极小结点继承下界
                    {
                        node.alpha = node.parent.alpha;
                    }
                }
            }
            if (node.depth == limitdepth || (node.visit == 1 && node.child.Count == 0) || (node.visit == -3))//最终结点
            {
                rvalue = score(node);
                if (node.depth % 2 == 0)//MAX
                {
                    node.alpha = rvalue;
                }
                else//MIN
                {
                    node.beta = rvalue;
                }

                if (node.depth != 0)
                {
                    nodes temp = node;
                    temp.child = null;
                    temp       = null;
                }
                return(rvalue);
            }

            if (node.depth % 2 == 0)// 极大节点
            {
                foreach (nodes child in node.child)
                {
                    double temp = alphabeta(child);
                    if (temp >= node.alpha)
                    {
                        node.alpha = temp;
                    }

                    if (node.beta <= node.alpha) // 该极大节点的值>=α>=β,该极大节点后面的搜索到的值肯定会大于β,因此不会被其上层的极小节点所选用了。对于根节点,β为正无穷
                    {
                        cut++;
                        break;
                    }
                }
                //子节点循环完毕
                rvalue = node.alpha;

                if (node.depth != 0)
                {
                    nodes temp = node;
                    temp.child = null;
                    temp       = null;
                }
            }
            else// 极小节点
            {
                foreach (nodes child in node.child) // 极大节点
                {
                    double temp = alphabeta(child);
                    if (temp <= node.beta)
                    {
                        node.beta = temp;
                    }

                    if (node.beta <= node.alpha) // 该极大节点的值<=β<=α,该极小节点后面的搜索到的值肯定会小于α,因此不会被其上层的极大节点所选用了。对于根节点,α为负无穷
                    {
                        cut++;
                        break;
                    }
                }
                rvalue = node.beta;

                if (node.depth != 0)
                {
                    nodes temp = node;
                    temp.child = null;
                    temp       = null;
                }
            }
            return(rvalue);
        }
예제 #14
0
        private void atkandmove(Map map, nodes node)
        {
            #region Branching Factor Part
            List <Move> flipList = new List <Move>();
            List <Move> movelist = new List <Move>();
            simap       map2     = new CDC.simap();
            map2 = map2.createDeepClone(vmap);
            int branchingF   = 0;
            int flipList_num = 0;
            int e_flip       = AI_tools.getallfliplist(map2).Count;

            if ((map.currentside == 0 && map.firstplayer == 0) || (map.currentside == 1 && map.firstplayer == 1))//Red
            {
                e_flip = (e_flip - map.unflipp_blue);
            }
            else if ((map.currentside == 0 && map.firstplayer == 1) || (map.currentside == 1 && map.firstplayer == 0))//Blue
            {
                e_flip = (e_flip - map.unflipp_red);
            }
            flipList_num = e_flip;//从缩减后改为毫无缩减的状况

            movelist   = AI_tools.getallmove(map2);
            flipList   = AI_tools.getallfliplist(map2);
            branchingF = movelist.Count + flipList.Count;
            allB.Add(branchingF);
            #endregion

            Move use = new CDC.Move();
            use.froX = node.movtion.froX;
            use.froY = node.movtion.froY;
            use.desX = node.movtion.desX;
            use.desY = node.movtion.desY;                                             //避免将原数据消除

            if (use.desX == -1 && use.desY == -1 && use.froX != -1 && use.froY != -1) //AI给出的行动为翻棋
            {
                flipchess(map, use.froX, use.froY);
            }
            if (use.froX != -1 && use.froY != -1 && use.desX != -1 && use.desY != -1)//都选定的情况
            {
                if (GameController.checkmove(map, use) == true)
                {
                    setmove(map, use);
                }
                else
                {
                    use.froX = -1;
                    use.froY = -1;
                    use.desX = -1;
                    use.desY = -1;
                }
            }
            if (map.currentside == 0)
            {
                label1.Text = "Current Player: First Player";
            }
            if (map.currentside == 1)
            {
                label1.Text = "Current Player: Second Player";
            }

            if ((vmap.currentside + 1) % 2 == 0) //已经实行的那一步的实施方(因为再flpchess和setmove中改变了currentside的值)属于先手或者后手
            {
                vmap.Plyr1move.Add(node);        //movtion存入先手List
                vmap.Plyr_move.Add(node);
            }
            else if (((vmap.currentside + 1) % 2 == 1))
            {
                vmap.Plyr2move.Add(node);//movtion存入后手List
                vmap.Plyr_move.Add(node);
            }

            double displayturn = map.turncount - 1;
            use.froX = -1;
            use.froY = -1;
            use.desX = -1;
            use.desY = -1;
        }
예제 #15
0
        private int checkboard(nodes node, Map map)
        {
            int flag      = 0;//0为游戏未结束, 1为游戏结束
            int redCount  = 0;
            int blueCount = 0;

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (map.Matrix[i, j].item.side == 0) //为红方
                    {
                        redCount++;                      //红加1
                    }
                    if (map.Matrix[i, j].item.side == 1) //为蓝方
                    {
                        blueCount++;                     //蓝加1
                    }
                }
            }
            if (node.resign == 1)
            {
                if ((map.currentside == 0 && map.firstplayer == 0) || (map.currentside == 1 && map.firstplayer == 1))
                {
                    flag = 1;
                    Console.WriteLine(map.turncount);
                    textBox1.AppendText("Blue Win !" + "\r\n");
                }
                else if ((map.currentside == 1 && map.firstplayer == 0) || (map.currentside == 0 && map.firstplayer == 1))
                {
                    flag = 2;
                    Console.WriteLine(map.turncount);
                    textBox1.AppendText("Red Win !" + "\r\n");
                }
            }
            if (redCount == 0)//Blue win!
            {
                flag = 1;
                Console.WriteLine(map.turncount);
                textBox1.AppendText("Blue Win !" + "\r\n");
            }
            else if (blueCount == 0)//Red win!
            {
                flag = 2;
                Console.WriteLine(map.turncount);
                textBox1.AppendText("Red Win !" + "\r\n");
            }
            else if (deloop(node, map) == true)
            {
                flag = 3;
                textBox1.AppendText("Draw" + "\r\n");
            }
            else if (map.turncount >= 150)
            {
                flag = 4;
                textBox1.AppendText("Draw" + "\r\n");
            }
            else
            {
                flag = Judge_system(map);
            }//采用最终结束式


            textBox1.AppendText("Turn Count: " + (map.turncount - 1) + "\r\n");
            textBox1.AppendText("Red Jiang Remains: " + map.redjiang + "\r\n");
            textBox1.AppendText("Red Shi Remains: " + map.redshi + "\r\n");
            textBox1.AppendText("Red Che Remains: " + map.redche + "\r\n");
            textBox1.AppendText("Red Ma Remains: " + map.redma + "\r\n");
            textBox1.AppendText("Red Pao Remains: " + map.redpao + "\r\n");
            textBox1.AppendText("Red Zu Remains: " + map.redzu + "\r\n");
            textBox1.AppendText("Red Xiang Remians: " + map.redxiang + "\r\n");
            textBox1.AppendText("Blue Jiang Remains: " + map.bluejiang + "\r\n");
            textBox1.AppendText("Blue Shi Remains: " + map.blueshi + "\r\n");
            textBox1.AppendText("Blue Che Remains: " + map.blueche + "\r\n");
            textBox1.AppendText("Blue Ma Remains: " + map.bluema + "\r\n");
            textBox1.AppendText("Blue Pao Remains: " + map.bluepao + "\r\n");
            textBox1.AppendText("Blue Zu Remains: " + map.bluezu + "\r\n");
            textBox1.AppendText("Blue Xiang Remians: " + map.bluexiang + "\r\n");
            textBox1.AppendText("Red Pieces Remaining: " + map.redremain + "\r\n");
            textBox1.AppendText("Blue Pieces Remaining: " + map.blueremain + "\r\n");
            textBox1.AppendText("\r\n");
            textBox1.AppendText("\r\n");
            if (flag == 1)//蓝方胜
            {
                lose_jiang.Add(map.redjiang);
                lose_zu.Add(map.redzu);
                lose_pao.Add(map.redpao);
            }
            else if (flag == 2)//红方胜
            {
                win_jiang.Add(map.redjiang);
                win_zu.Add(map.redzu);
                win_pao.Add(map.redpao);
            }
            return(flag);
        }