在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → c# 五子棋 游戏完整源码下载

c# 五子棋 游戏完整源码下载

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:1.35M
  • 下载次数:47
  • 浏览次数:1205
  • 发布时间:2014-12-08
  • 实例类别:C#语言基础
  • 发 布 人:uhkjh
  • 文件格式:.rar
  • 所需积分:3
 相关标签: 五子棋

实例介绍

【实例简介】

【实例截图】

【核心代码】

    public partial class Form1 : Form
    {
        //数据区××××××××××××××××××××数据区×××××××××××××××××××××××××××××
        public class StepPoint//下棋点,用于回溯
        {
            public int x;
            public int y;
            public int color;
        };
        public FormSet formSet;//设置对话框
        public FormAbout formAbout;//关于对话框

        public Bitmap blackBmp;//黑子
        public Bitmap whiteBmp;//白子
        public Bitmap boardBmp;//棋盘

        bool end = false;
        public int[,] chessBoard;//1:黑子,-1:白子,0:无子
        Bitmap backGroundImage;//直接设为前景,从而不用重绘控件
        Graphics pbGraph;//把缓冲图画到前景上
        public int computerColor;
        public int manColor;

        public Stack<Point> tryStepStack = new Stack<Point>();//用来试探步子回溯的栈
        public Stack<StepPoint> backStack = new Stack<StepPoint>();//悔棋用的。

        int totalChessCount = 0;//棋盘上的棋子数
        //数据区×××××××××××××××××××××××数据区××××××××××××××××××××××××××

        public Form1()//初始化
        {
            InitializeComponent();
            formSet = new FormSet();
            formAbout = new FormAbout();
            blackBmp = new Bitmap("black.bmp");
            blackBmp.MakeTransparent(Color.Red);
            whiteBmp = new Bitmap("white.bmp");
            whiteBmp.MakeTransparent(Color.Red);
            boardBmp = new Bitmap("board.bmp");

            chessBoard = new int[15, 15];

            backGroundImage = new Bitmap(pbBoard.Width, pbBoard.Height);
            pbGraph = Graphics.FromImage(backGroundImage);
            pbBoard.BackgroundImage = boardBmp;
            pbGraph.DrawImage(boardBmp, 0, 0);
            pbBoard.Image = backGroundImage;//哈哈,Lisa的聪明之计,不用刷新窗体。
            pbBoard.Refresh();
            totalChessCount = 0;

            if (formSet.isComputerFirst)
            {
                computerColor = 1;
                manColor = -1;
            }
            else
            {
                computerColor = -1;
                manColor = 1;
            }
            if (formSet.isComputerFirst)
            {
                putChess(1, 7, 7);//在棋盘中心画下一个黑棋
            }
            end = false;
        }

        private void btnNewGame_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 15; i  )//初始化棋盘
                for (int j = 0; j < 15; j  )
                {
                    chessBoard[i, j] = 0;
                }
            if (formSet.isComputerFirst)
            {
                computerColor = 1;
                manColor = -1;
            }
            else
            {
                computerColor = -1;
                manColor = 1;
            }
            totalChessCount = 0;
            pbGraph.DrawImage(boardBmp, 0, 0);
            pbBoard.Refresh();
            if (formSet.isComputerFirst)
            {
                putChess(1, 7, 7);//在棋盘中心画下一个黑棋
            }
            end = false;
            
            backStack.Clear();
        }

        private void btnSet_Click(object sender, EventArgs e)
        {
            if (formSet.ShowDialog() == DialogResult.OK)
            {
                for (int i = 0; i < 15; i  )//初始化棋盘
                    for (int j = 0; j < 15; j  )
                    {
                        chessBoard[i, j] = 0;
                    }
                if (formSet.isComputerFirst)
                {
                    computerColor = 1;
                    manColor = -1;
                }
                else
                {
                    computerColor = -1;
                    manColor = 1;
                }
                totalChessCount = 0;
                pbGraph.DrawImage(boardBmp, 0, 0);
                pbBoard.Refresh();
                if (formSet.isComputerFirst)
                {
                    putChess(1, 7, 7);//在棋盘中心画下一个黑棋
                }
                end = false;
                
                backStack.Clear();
            }
        }

        //放一个棋子到棋盘上////////////////////////////////////
        private void putChess(int color, int x, int y)
        {
            StepPoint point = new StepPoint();
            point.x = x;
            point.y = y;
            point.color = color;
            backStack.Push(point);
            if (color == 1)
            {
                chessBoard[x, y] = 1;
                pbGraph.DrawImage(blackBmp, x * 23   2, y * 23   2);//画棋子
            }
            else
            {
                chessBoard[x, y] = -1;
                pbGraph.DrawImage(whiteBmp, x * 23   2, y * 23   2);//画棋子
            }
            totalChessCount  ;
            pbBoard.Refresh();
        }//放一下棋子到棋盘上

        //悔棋////////////////////////////////////
        private void btnBack_Click(object sender, EventArgs e)
        {
            if (backStack.Count > 0)
            {
                StepPoint point = backStack.Pop();
                if (point.color == computerColor)
                {
                    if (backStack.Count == 0)
                    {
                        backStack.Push(point);
                        return;
                    }
                    chessBoard[point.x, point.y] = 0;
                    totalChessCount--;
                    point = backStack.Pop();
                }
                chessBoard[point.x, point.y] = 0;
                totalChessCount--;
                pbGraph.DrawImage(boardBmp, 0, 0);
                for (int i = 0; i < 15; i  )
                {
                    for (int j = 0; j < 15; j  )
                    {
                        if (chessBoard[i, j] == 1) pbGraph.DrawImage(blackBmp, i * 23   2, j * 23   2);
                        if (chessBoard[i, j] == -1) pbGraph.DrawImage(whiteBmp, i * 23   2, j * 23   2);
                    }
                }
                pbBoard.Refresh();
                end = false;
            }
        }//悔棋

        private void btnAbout_Click(object sender, EventArgs e)
        {
            formAbout.ShowDialog();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void pbBoard_MouseClick(object sender, MouseEventArgs e)
        {
            int x = (e.X   2) / 23;
            int y = (e.Y   2) / 23;
            if ( x < 15 && y < 15 && chessBoard[x, y] == 0)
            {
                if (!end)
                {
                    int weightTmp = pointWeight(manColor, x, y);//先称一称该点的权重
                    if (weightTmp == -2)//长连禁手
                    {
                        MessageBox.Show("抱歉!本点为长连禁手点,你不能下!", "警告", MessageBoxButtons.OK);
                        return;
                    }
                    else if (weightTmp >= 150000)//赢了
                    {
                        putChess(manColor, x, y);
                        MessageBox.Show("恭喜,你赢了!", "本局结果", MessageBoxButtons.OK);
                        end = true;
                        return;
                    }
                    else if (weightTmp == -1)
                    {
                        MessageBox.Show("抱歉!本点为禁手点,你不能下!", "警告", MessageBoxButtons.OK);
                        return;
                    }
                    else if (totalChessCount >= 224)
                    {
                        putChess(manColor, x, y);
                        MessageBox.Show("棋盘已满,本局平棋!", "本局结果", MessageBoxButtons.OK);
                        end = true;
                        return;
                    }
                    else
                    {
                        putChess(manColor, x, y);
                        int bx = 0, by = 0;
                        if (searchBestPoint(computerColor, ref bx, ref by))
                        {
                            weightTmp = pointWeight(computerColor, bx, by);
                            putChess(computerColor, bx, by);
                            if (weightTmp >= 150000)
                            {
                                MessageBox.Show("抱歉,你输了!要加油哦!", "本局结果", MessageBoxButtons.OK);
                                end = true;
                                return;
                            }
                            else if (totalChessCount == 225)
                            {
                                MessageBox.Show("棋盘已满,本局平棋!", "本局结果", MessageBoxButtons.OK);
                                end = true;
                                return;
                            }
                        }
                        else
                        {
                            MessageBox.Show("恭喜你,你赢了!棋盘上所有的点都是电脑的禁手点!", "本局结果", MessageBoxButtons.OK);
                            end = true;
                            return;
                        }
                    }
                }
            }
        }

        //判断点(x,y)放入黑棋后是否形成长连////////////////////////////////////
        private bool hasLongLink(int x, int y)
        {
            int count = 1;
            for (int i = 5; i >= 0; i--)
            {
                int c = x, d = y, cmin = 0, cmax = 9, dmin = 0, dmax = 9, xp = 1, yp = 0;
                for (int t = 0; t < 2; t  )
                {
                    if (c - i >= cmin && c - i <= cmax)
                    {
                        for (int j = 0; j < 6; j  )// -水平|垂直
                        {
                            count  = chessBoard[x - (i - j) * xp, y - (i - j) * yp];
                        }
                        if (count == 6) return true;
                        count = 1;
                        if (yp < 1) yp = 1; else xp = -1;
                        if (d - i * xp >= dmin && d - i * xp <= dmax)// \/方向
                        {
                            for (int j = 0; j < 6; j  )
                            {
                                count  = chessBoard[x - (i - j) * xp, y - (i - j) * yp];
                            }
                            if (count == 6) return true;
                            count = 1;
                        }
                    }
                    xp = 0; yp = 1; c = y; d = x; dmin = 5; dmax = 14;
                }

            }
            return false;
        }//判断点(x,y)放入黑棋后是否形成长连

        //判断两点(x1,y1),(x2,y2)间是否存在活的count////////////////////////////////////
        private bool liveCount(int color, int count, int x1, int y1, int x2, int y2)
        {
            int x, y, i, j, length, xPlus = 0, yPlus = 0, sum;
            int temp1, temp2;
            temp1 = Math.Min(Math.Min(Math.Min(5 - count, x1), y1), 14 - y1);
            temp2 = Math.Min(Math.Min(Math.Min(5 - count, 14 - x2), 14 - y2), y2);
            length = Math.Max(Math.Abs(x1 - x2), Math.Abs(y1 - y2))   1   temp1   temp2;
            if (x1 != x2) xPlus = 1;
            if (y1 != y2) yPlus = (y2 - y1) / Math.Abs(y2 - y1);
            for (i = 0; i < length - 4; i  )
            {
                x = x1 - temp1 * xPlus   i * xPlus;
                y = y1 - temp1 * yPlus   i * yPlus;
                if (x   4 * xPlus > 14 || y   4 * yPlus > 14)
                    break;
                sum = 0;
                for (j = 0; j < 4; j  )
                {
                    if (chessBoard[x   j * xPlus, y   j * yPlus] == color)
                        sum  ;
                    else if (chessBoard[x   j * xPlus, y   j * yPlus] == -color)
                    {
                        sum = 0;
                        break;
                    }
                }
                if (0 < x && 0 <= y - yPlus && y - yPlus <= 14)
                {
                    if (sum == count && chessBoard[x - xPlus, y - yPlus] == 0 && chessBoard[x   4 * xPlus, y   4 * yPlus] == 0)
                        return true;
                }
            }
            return false;
        }//判断两点(x1,y1),(x2,y2)间是否存在活的count

        //求两点(x1,y1),(x2,y2)间最长的color色连的棋的数目////////////////////////////////////
        private int linkCount(int color, int x1, int y1, int x2, int y2)
        {
            int x, y, i, j, length, xPlus = 0, yPlus = 0, sum, maxSum = 0;
            length = Math.Max(Math.Abs(x1 - x2), Math.Abs(y1 - y2))   1;
            if (x1 != x2) xPlus = 1;
            if (y1 != y2) yPlus = (y2 - y1) / Math.Abs(y2 - y1);
            for (i = 0; i < length - 4; i  )
            {
                x = x1   i * xPlus;
                y = y1   i * yPlus;
                sum = 0;
                for (j = 0; j < 5; j  )
                {
                    if (chessBoard[x   j * xPlus, y   j * yPlus] == color)
                        sum  ;
                    else if (chessBoard[x   j * xPlus, y   j * yPlus] == -color)
                    {
                        sum = 0;
                        break;
                    }
                }
                if (maxSum < sum)
                    maxSum = sum;
            }
            return maxSum;
        }//求两点(x1,y1),(x2,y2)间可能形成五连的color色棋的数目

        //(x,y)处放color色棋后是否能在(x1,y1)和(x2,y2)之间形成活count且不被另一色棋时不被破坏////////////////////////////////////
        private bool breakLiveCount(int color, int count, int x, int y, int x1, int y1, int x2, int y2)
        {
            if (!liveCount(color, count, x1, y1, x2, y2)) return false;
            if (count == 5) return false;
            else if (count == 4) return true;
            else
            {
                bool blnFlag;
                chessBoard[x, y] = -color;
                blnFlag = !liveCount(color, count - 1, x1, y1, x2, y2);
                chessBoard[x, y] = color;
                return blnFlag;
            }
        }//(x,y)处放color色棋后是否能形成活count且放另一色棋时不被破坏

        //寻找最好的10个下棋点,如有多个最大值,则采用随机方式给出。找不到就返回false////////////////////////////////////
        private bool searchBestPoint(int color, ref int x, ref int y)
        {
            int[,] weight=new int[15,15];
            int[] ww = new int[10];
            int[] xx = new int[10];
            int[] yy = new int[10];
            int max = 0;
            for (int i = 0; i < 15; i  )
                for (int j = 0; j < 15; j  )
                    weight[i, j] = pointWeight(color, i, j);
            for (int i = 0; i < 10; i  )//找出weight值最高的十个点
            {
                max = -4;//权值最小也就-3
                for (int m = 0; m < 15; m  )
                    for (int n = 0; n < 15; n  )
                        if (max < weight[m, n])
                        {
                            max = weight[m, n];
                            xx[i] = m;
                            yy[i] = n;
                            weight[m, n] = -5;
                        }
                ww[i]=max;
                
            }
            if (ww[0] < 0)//最高值小于0,说明无子可子
                return false;
            else
            {
                int count = 1;
                while (count<10&&ww[count] == ww[0]) count  ;
                Random ra = new Random();
                int index=ra.Next(count);
                x = xx[index];
                y = yy[index];
                return true;
            }
        }

        //求color色棋在(x,y)点的权重////////////////////////////////////
        private int pointWeight(int color, int x, int y)
        {
            int totalWeight;
            int[] colorLink = new int[6];//下棋方棋连数从0~5
            int[] colorLive = new int[6];//下棋方连棋数从0~5
            int[] fcolorLink = new int[6];//对手方棋连数从0~5
            int[] fcolorLive = new int[6];//对手方棋连数从0~5
            int tempLive3 = 0, temp, linkCounts;

            Point left = new Point(Math.Max(0, x - 5), y);
            Point right = new Point(Math.Min(14, x   5), y);
            Point top = new Point(x, Math.Max(0, y - 5));
            Point down = new Point(x, Math.Min(14, y   5));
            temp = Math.Min(x - left.X, y - top.Y);
            Point leftTop = new Point(x - temp, y - temp);
            temp = Math.Min(x - left.X, down.Y - y);
            Point leftDown = new Point(x - temp, y   temp);
            temp = Math.Min(right.X - x, y - top.Y);
            Point rightTop = new Point(x   temp, y - temp);
            temp = Math.Min(right.X - x, down.Y - y);
            Point rightDown = new Point(x   temp, y   temp);

            if (chessBoard[x, y] != 0) return -3;
            else
            {

                //下方棋连子的情况/////////////////////////////////////////////////////////////
                chessBoard[x, y] = color;
                //左右方向
                linkCounts = linkCount(color, left.X, left.Y, right.X, right.Y);
                colorLink[linkCounts]  ;
                if (liveCount(1, linkCounts, left.X, left.Y, right.X, right.Y))
                {
                    colorLink[linkCounts]--;
                    colorLive[linkCounts]  ;
                }
                //上下方向
                linkCounts = linkCount(color, top.X, top.Y, down.X, down.Y);
                colorLink[linkCounts]  ;
                if (liveCount(1, linkCounts, top.X, top.Y, down.X, down.Y))
                {
                    colorLink[linkCounts]--;
                    colorLive[linkCounts]  ;
                }
                //左上_右下方向
                linkCounts = linkCount(color, leftTop.X, leftTop.Y, rightDown.X, rightDown.Y);
                colorLink[linkCounts]  ;
                if (liveCount(1, linkCounts, leftTop.X, leftTop.Y, rightDown.X, rightDown.Y))
                {
                    colorLink[linkCounts]--;
                    colorLive[linkCounts]  ;
                }
                //左下_右上方向
                linkCounts = linkCount(color, leftDown.X, leftDown.Y, rightTop.X, rightTop.Y);
                colorLink[linkCounts]  ;
                if (liveCount(1, linkCounts, leftDown.X, leftDown.Y, rightTop.X, rightTop.Y))
                {
                    colorLink[linkCounts]--;
                    colorLive[linkCounts]  ;
                }

                ///对方棋连子的情况/////////////////////////////////////////////////////////////
                chessBoard[x, y] = -color;
                //左右方向
                linkCounts = linkCount(-color, left.X, left.Y, right.X, right.Y);
                fcolorLink[linkCounts]  ;
                if (breakLiveCount(-color, linkCounts, x, y, left.X, left.Y, right.X, right.Y))
                {
                    fcolorLink[linkCounts]--;
                    fcolorLive[linkCounts]  ;
                }
                //上下方向
                linkCounts = linkCount(-color, top.X, top.Y, down.X, down.Y);
                fcolorLink[linkCounts]  ;
                if (breakLiveCount(-color, linkCounts, x, y, top.X, top.Y, down.X, down.Y))
                {
                    fcolorLink[linkCounts]--;
                    fcolorLive[linkCounts]  ;
                }
                //左上_右下方向
                linkCounts = linkCount(-color, leftTop.X, leftTop.Y, rightDown.X, rightDown.Y);
                fcolorLink[linkCounts]  ;
                if (breakLiveCount(-color, linkCounts, x, y, leftTop.X, leftTop.Y, rightDown.X, rightDown.Y))
                {
                    fcolorLink[linkCounts]--;
                    fcolorLive[linkCounts]  ;
                }
                //左下_右上方向
                linkCounts = linkCount(-color, leftDown.X, leftDown.Y, rightTop.X, rightTop.Y);
                fcolorLink[linkCounts]  ;
                if (breakLiveCount(-color, linkCounts, x, y, leftDown.X, leftDown.Y, rightTop.X, rightTop.Y))
                {
                    fcolorLink[linkCounts]--;
                    fcolorLive[linkCounts]  ;
                }

                if (liveCount(-color, 3, left.X, left.Y, right.X, right.Y) && linkCount(-color, left.X, left.Y, right.X, right.Y) <= 3) tempLive3  ;
                if (liveCount(-color, 3, top.X, top.Y, down.X, down.Y) && linkCount(-color, top.X, top.Y, down.X, down.Y) <= 3) tempLive3  ;
                if (liveCount(-color, 3, leftTop.X, leftTop.Y, rightDown.X, rightDown.Y) && linkCount(-color, leftTop.X, leftTop.Y, rightDown.X, rightDown.Y) <= 3) tempLive3  ;
                if (liveCount(-color, 3, leftDown.X, leftDown.Y, rightTop.X, rightTop.Y) && linkCount(-color, leftDown.X, leftDown.Y, rightTop.X, rightTop.Y) <= 3) tempLive3  ;
                chessBoard[x, y] = 0;

                //开始求权重/////////////////////////////////////////////////////////////////////
                if (color == 1)//如果是下棋方是黑子,有禁手
                {
                    if (hasLongLink(x, y))//对不起,长连
                        return -2;//禁手
                    else if (colorLink[5] > 0)//自己可以形成5
                        return 150000;
                    else if (colorLive[3] > 1 || colorLive[4]   colorLink[4] > 1)//四四,活三三,都是禁手
                        return -1;
                    else if (fcolorLink[5] > 0)//破坏对方的5
                        return 140000;
                    else if (colorLive[4] == 1)//可以形成一个活四
                        return 130000;
                    else if (colorLink[4] == 1 && colorLive[3] == 1)//可以形成一个四三
                        return 120000;
                    else if (colorLink[4] == 1 && colorLink[3] > 0)
                        return 110000;
                    //防守式战略
                    else if (fcolorLive[4] > 0 || fcolorLink[4] > 1)
                        return 100000;
                    else if (fcolorLink[4] == 1 && tempLive3 == 1)
                        return 90000;
                    else if (fcolorLive[3] > 1)
                        return 80000;
                    else if (fcolorLink[4] == 1 && fcolorLink[3] > 0)
                        return 70000;
                    else
                    {
                        totalWeight = (colorLink[4]   colorLive[3]) * 6250   (colorLink[3]   colorLive[2]   fcolorLink[4]   fcolorLive[3]) * 1250
                          (colorLink[2]   fcolorLink[3]   fcolorLive[2]) * 250   colorLive[1] * 50   (colorLink[1]   fcolorLink[2]   fcolorLive[1]) * 10   fcolorLink[1] * 2;
                        return totalWeight;
                    }
                }
                else//如果是下棋方是白子,考虑黑子的禁手
                {
                    bool isBlackForbiden = (tempLive3 > 1 || colorLive[4] > 1 || hasLongLink(x, y));//黑棋有禁手
                    bool isBlackLongLink = hasLongLink(x, y);//黑手有长连禁手
                    if (colorLink[5] > 0)//自已可以形成5
                        return 150000;
                    else if (fcolorLink[5] > 0 && !isBlackLongLink)//对方可以形成5,且没有长连禁手限制
                        return 140000;
                    //进攻与防守相结合的战略
                    else if (colorLive[4] > 0 || fcolorLink[4] > 1)//自己可以形成活四,或者对方可以形成两个四连
                        return 130000;
                    else if (colorLink[4] == 1 && fcolorLive[3] > 0)
                        return 120000;
                    else if (fcolorLive[4] == 1 && !isBlackForbiden || colorLink[4] > 1 && !isBlackForbiden)
                        return 110000;
                    else if (colorLink[4] == 1 && fcolorLink[3] > 0)
                        return 100000;
                    else if (fcolorLink[4] > 0 && tempLive3 == 1 && !isBlackForbiden)
                        return 90000;
                    else if (colorLive[3] > 1)
                        return 80000;
                    else if (fcolorLink[4] > 0 && colorLink[3] > 0 && !isBlackForbiden)
                        return 70000;
                    else
                    {
                        totalWeight = (colorLink[4]   colorLive[3]) * 6250   (colorLink[3]   colorLive[2]   fcolorLink[4]   fcolorLive[3]) * 1250
                          (colorLink[2]   fcolorLink[3]   fcolorLive[2]) * 250   colorLive[1] * 50   (colorLink[1]   fcolorLink[2]   fcolorLive[1]) * 10   fcolorLink[1] * 2;
                        return totalWeight;
                    }
                }
            }
        }//求color色棋在(x,y)点的权重
    }

标签: 五子棋

实例下载地址

c# 五子棋 游戏完整源码下载

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警