五子棋研究 判断输赢条件,及不复杂的AI算法 2个 。

来源:互联网 发布:英语语法 大总汇 知乎 编辑:程序博客网 时间:2024/04/30 18:27

//自己写的判断输赢,及电脑简单AI ,电脑AI不高容易输,不过算法实现简单,完善中,花了1天时间,AI算法深度不够

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace DouDiZhu.WuZi
{
    /// <summary>
    /// 判断五子输赢
    /// </summary>
    class WuziWin
    {
        //八个方向数组 记录状态用来进行robot方位计算
        int[] direct_0 = new int[5];

        int[] direct_90 = new int[5];

        int[] direct_180 = new int[5];

        int[] direct_270 = new int[5];

        int[] direct_45 = new int[5];

        int[] direct_135 = new int[5];

        int[] direct_225 = new int[5];

        int[] direct_315 = new int[5];

        int[,] qiZi2 = new int[15, 15];

        int[] recordX = new int[100];//记录100步内记录,超过则判断玩家输

        int[] recordY = new int[100];//记录100步内记录,超过则判断玩家输

        int playerStep;//记录玩家走了第几步

        int tX, tY;//记录目标点X,Y

        int preX, preY;//记录上一步目标点X,Y

        int[] countTemp = new int[8];//记录count值

        int[] blank = new int[224];//空白位棋子的权值,记录所下子7*7范围内的空白子权值

        public WuziWin()
        { }

        /// <summary>
        /// 返回是否赢棋
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <param name="qiZiState">1为白棋子 2为黑棋子</param>
        /// <returns>bool</returns>
        public bool isWin(int[,] qiZi, int targetX, int targetY, int qiZiState)
        {
            int[] count = new int[8];//计数器,判断是否五连

            this.tX = targetX;

            this.tY = targetY;

            this.qiZi2 = qiZi;

            if (qiZiState == 2)
            {
                playerStep++;
            }

            recordX[playerStep] = this.tX;

            recordY[playerStep] = this.tY;

            //0度方向判断,遍历5个棋子  
            for (int i = 0; i < 5; i++)
            {
                if (targetY - i >= 0)

                    if (qiZi[targetX , targetY - i] == qiZiState)
                    {
                        direct_0[i] = qiZi[targetX, targetY - i];

                        count[0]++;
                    }
                    else
                    {
                        break;
                    }
            }
 
            //90度方向判断,遍历5个棋子
            for (int i = 0; i < 5; i++)
            {
                if (targetX + i <= 14)

                    if (qiZi[targetX+i, targetY] == qiZiState)
                    {
                        direct_90[i] = qiZi[targetX + i, targetY];

                        count[1]++;
                    }
                    else
                    {
                        break;
                    }
            }

            //180度方向判断,遍历5个棋子
            for (int i = 0; i < 5; i++)
            {
                if (  targetY + i <= 14)

                    if (qiZi[targetX , targetY+i] == qiZiState)
                    {
                        direct_180[i] = qiZi[targetX, targetY + i];

                        count[2]++;
                    }
                    else
                    {
                        break;
                    }
            }
         

            //270度方向判断,遍历5个棋子
            for (int i = 0; i < 5; i++)
            {
                if (targetX - i >= 0)

                    if (qiZi[targetX - i, targetY] == qiZiState)
                    {
                        direct_270[i] = qiZi[targetX - i, targetY];

                        count[3]++;
                    }
                    else
                    {
                        break;
                    }
            }

            //45度方向判断,遍历5个棋子
            for (int i = 0; i < 5; i++)
            {
                if ( targetX + i <= 14 && targetY - i >= 0)

                    if (qiZi[targetX + i, targetY - i] == qiZiState)
                    {
                        direct_45[i] = qiZi[targetX + i, targetY - i];

                        count[4]++;
                    }
                    else
                    {
                        break;
                    }
            }

            //135度方向判断,遍历5个棋子         
            for (int i = 0; i < 5; i++)
            {
                if (targetX + i <= 14 && targetY + i <= 14)

                    if (qiZi[targetX + i, targetY + i] == qiZiState)
                    {
                        direct_135[i] = qiZi[targetX + i, targetY + i];

                        count[5]++;
                    }
                    else
                    {
                        break;
                    }
            }

            //225度方向判断,遍历5个棋子
            for (int i = 0; i < 5; i++)
            {
                if (targetX - i >= 0 && targetY + i <= 14)

                    if (qiZi[targetX - i, targetY + i] == qiZiState)
                    {
                        direct_225[i] = qiZi[targetX - i, targetY + i];

                        count[6]++;
                    }
                    else
                    {
                        break;
                    }
            }

            //315度方向判断,遍历5个棋子
            for (int i = 0; i < 5; i++)
            {
                if (targetX - i >= 0 && targetY - i >= 0)

                    if (qiZi[targetX - i, targetY - i] == qiZiState)
                    {
                        direct_315[i] = qiZi[targetX - i, targetY - i];

                        count[7]++;
                    }
                    else
                    {
                        break;
                    }
            }

            countTemp = count;

            //x轴方向是否存在5连
            if (count[1] + count[3] > 5)
            {
                return true;
            }
            //y轴方向是否存在5连
            else if(count[0]+count[2] > 5)
            {
                return true;
            }
            //45度方向是否存在5连
            else if(count[4]+count[6] > 5)
            {
                return true;
            }
            //225度方向是否存在5连
            else if (count[5] + count[7] > 5)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        /// <summary>
        /// 返回电脑下子坐标,必须判断isWin()后才能使用
        /// 电脑AI
        /// </summary>
        /// <returns>int[]</returns>
        public int[] robotPosition()
        {
            int[] position = new int[2];

            int[] blankX = new int[224];

            int[] blankY = new int[224];

            int[] blank2 = new int[224];

            int[] directs = new int[8];//某空点 8方向 权值

            int step = 0;
            //================================================================
            //判断棋盘范围内的所有空白子权值,并取得其坐标                 
            //================================================================
            for (int i = 0; i < 15; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    if (this.tX - i >= 0 && this.tX + i <= 14 && this.tY - j >= 0 && this.tY + j <= 14)
                    {
                        if (this.qiZi2[i, j] == 0)
                        {
                            directs[0] = this.direct0(this.qiZi2, i, j);
                            directs[1] = this.direct90(this.qiZi2, i, j);
                            directs[2] = this.direct180(this.qiZi2, i, j);
                            directs[3] = this.direct270(this.qiZi2, i, j);
                            directs[4] = this.direct45(this.qiZi2, i, j);
                            directs[5] = this.direct135(this.qiZi2, i, j);
                            directs[6] = this.direct225(this.qiZi2, i, j);
                            directs[7] = this.direct315(this.qiZi2, i, j);

 

                            blank2[step] = this.maxValue(directs);//获取最大权值 这算法有待调整

                            blankX[step] = i;

                            blankY[step] = j;

                            step++;
                        }
                    }
                }
            }

          
          //倒序排列权值
            for (int i = 0; i < 224; i++)
            {
                blank[i] = blank2[i];
               
            }

            int temps = 0;

            int index = 0;

            for (int i = 0; i < blank2.Length - 1; i++)
            {
                for (int j = i + 1; j < blank2.Length; j++)
                {
                    if (blank2[i] < blank2[j])
                    {
                        temps = blank2[i];

                        blank2[i] = blank2[j];

                        blank2[j] = temps;

                    }

                }
            }

 

            //取得最大权值的索引,算法改善中
            for (int i = 0; i < blank2.Length; i++)
            {
                if (blank2[0] == blank[i])
                {
                    index = i;

                }
            }

            position[0] = blankX[index];

            position[1] = blankY[index];
           
            return position;
        }

        /// <summary>
        /// 返回该空子位置direct_0上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct0(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;
            //0度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetY - i >= 0)

                    if (qiZi[targetX, targetY - i] == 2)
                    {
                        countDirect++;
                    }
            }

            return countDirect;
        }

        /// <summary>
        /// 返回该空子位置direct_90上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct90(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //90度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetX + i <= 14)

                    if (qiZi[targetX + i, targetY] == 2)
                    {
                        countDirect++;
                    }                  
            }
            return countDirect;
        }


        /// <summary>
        /// 返回int数组中最大值
        /// </summary>
        /// <param name="array">数组</param>
        /// <returns>int[]</returns>
        public int maxValue(int[] array)
        {
            int  maxValue = array[0];

            for (int i = 1; i < array.Length; i++)
            {
                if (maxValue < array[i])
                {
                    maxValue = array[i];
                }
            }           

            return maxValue;
        }

        /// <summary>
        /// 返回该空子位置direct_180上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct180(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //180度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetY + i <= 14)

                    if (qiZi[targetX, targetY + i] == 2)
                    {
                        countDirect++;
                    }                
            }

            return countDirect;
        }

        /// <summary>
        /// 返回该空子位置direct_270上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct270(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //270度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetX - i >= 0)

                    if (qiZi[targetX - i, targetY] == 2)
                    {
                        countDirect++;
                    }
            }

            return countDirect;
        }


        /// <summary>
        /// 返回该空子位置direct_45上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct45(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //45度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetX + i <= 14 && targetY - i >= 0)

                    if (qiZi[targetX + i, targetY - i] == 2)
                    {
                        countDirect++;
                    }
            }

            return countDirect;
        }

        /// <summary>
        /// 返回该空子位置direct_135上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct135(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //135度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetX + i <= 14 && targetY + i <= 14)

                    if (qiZi[targetX + i, targetY + i] == 2)
                    {
                        countDirect++;
                    }
            }

            return countDirect;
        }

        /// <summary>
        /// 返回该空子位置direct_225上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct225(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //225度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetX - i >= 0 && targetY + i <= 14)

                    if (qiZi[targetX - i, targetY + i] == 2)
                    {
                        countDirect++;
                    }
            }

            return countDirect;
        }

        /// <summary>
        /// 返回该空子位置direct_315上的权值
        /// </summary>
        /// <param name="qiZi">状态数组</param>
        /// <param name="targetX">目标棋在数组中X位置</param>
        /// <param name="targetY">目标棋在数组中Y位置</param>
        /// <returns>int</returns>
        public int direct315(int[,] qiZi, int targetX, int targetY)
        {
            int countDirect = 0;

            //315度方向判断,遍历3个棋子  
            for (int i = 0; i < 3; i++)
            {
                if (targetX - i >= 0 && targetY - i >= 0)

                    if (qiZi[targetX - i, targetY - i] == 2)
                    {
                        countDirect++;
                    }
            }

            return countDirect;
        }
    }
}

原创粉丝点击