单机五子棋

//必须在ImageList控件里加入空白棋子的两幅高和宽都为20的图片.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

 

namespace WindowsApplication2
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.MainMenu mainMenu1;
        private System.Windows.Forms.MenuItem menuItem1;
        private System.Windows.Forms.MenuItem menuItem2;
        private System.Windows.Forms.MenuItem menuItem3;
        private System.Windows.Forms.MenuItem menuItem4;
        private System.Windows.Forms.MenuItem menuItem5;
        private System.Windows.Forms.MenuItem menuItem6;
        private System.Windows.Forms.MenuItem menuItem7;
        private System.ComponentModel.IContainer components;
        private const int None = -1;//没有棋子
        private const int White = 0;//代表白棋
        private const int Black = 1;//代表黑棋
        private int[,] checkerBoard = new int[15, 15];//棋盘(用来保存每一个棋子)
        private int nextPlayer;//下一个选手
        private int Player
        {
            get
            {
                return nextPlayer;
            }
            set
            {
                nextPlayer = value;
                ReDrawNextPlayerMark();
            }
        }
        private System.Windows.Forms.MenuItem menuItem8;
        private System.Windows.Forms.MenuItem menuItem9;
        private System.Windows.Forms.MenuItem menuItem10;//下一次该黑棋还是白棋下
        private Stack History;//下棋的历史记录
        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

 

            //
            // TODO: Add any constructor code after InitializeComponent call
            // checkerBoard = new int [15,15];
            History = new Stack();
            Player = White;//默认设置为白棋先下
            Reset();

 

        }

 

        ///
        /// Clean up any resources being used.
        ///
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

 

        #region Windows Form Designer generated code
        ///
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        ///
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.menuItem8 = new System.Windows.Forms.MenuItem();
            this.menuItem9 = new System.Windows.Forms.MenuItem();
            this.menuItem4 = new System.Windows.Forms.MenuItem();
            this.menuItem5 = new System.Windows.Forms.MenuItem();
            this.menuItem6 = new System.Windows.Forms.MenuItem();
            this.menuItem7 = new System.Windows.Forms.MenuItem();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menuItem10 = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.menuItem3 = new System.Windows.Forms.MenuItem();
            this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
            this.imageList1 = new System.Windows.Forms.ImageList(this.components);
            this.SuspendLayout();
            //
            // menuItem8
            //
            this.menuItem8.Index = 3;
            this.menuItem8.Shortcut = System.Windows.Forms.Shortcut.AltBksp;
            this.menuItem8.Text = "悔一步棋 (&H)";
            this.menuItem8.Click += new System.EventHandler(this.menuItem8_Click);
            //
            // menuItem9
            //
            this.menuItem9.Index = 1;
            this.menuItem9.Text = "-";
            //
            // menuItem4
            //
            this.menuItem4.Index = 1;
            this.menuItem4.Text = "关于… (&A)";
            this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click_1);
            //
            // menuItem5
            //
            this.menuItem5.Index = 0;
            this.menuItem5.Shortcut = System.Windows.Forms.Shortcut.CtrlN;
            this.menuItem5.Text = "重新开始 (&N)";
            this.menuItem5.Click += new System.EventHandler(this.menuItem5_Click);
            //
            // menuItem6
            //
            this.menuItem6.Index = 5;
            this.menuItem6.Shortcut = System.Windows.Forms.Shortcut.CtrlX;
            this.menuItem6.Text = "退出 (&X)";
            this.menuItem6.Click += new System.EventHandler(this.menuItem6_Click);
            //
            // menuItem7
            //
            this.menuItem7.Index = 4;
            this.menuItem7.Text = "-";
            //
            // menuItem1
            //
            this.menuItem1.Index = 0;
            this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem5,
            this.menuItem9,
            this.menuItem10,
            this.menuItem8,
            this.menuItem7,
            this.menuItem6});
            this.menuItem1.Text = "系统 (&S)";
            this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
            this.menuItem1.Popup += new System.EventHandler(this.menuItem1_Popup);
            //
            // menuItem10
            //
            this.menuItem10.Index = 2;
            this.menuItem10.Text = "黑棋先下 (&B)";
            this.menuItem10.Click += new System.EventHandler(this.menuItem10_Click);
            //
            // menuItem2
            //
            this.menuItem2.Index = 1;
            this.menuItem2.MdiList = true;
            this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem3,
            this.menuItem4});
            this.menuItem2.Text = "帮助 (&H)";
            this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
            //
            // menuItem3
            //
            this.menuItem3.Index = 0;
            this.menuItem3.Shortcut = System.Windows.Forms.Shortcut.F1;
            this.menuItem3.Text = "使用方法";
            this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click_1);
            //
            // mainMenu1
            //
            this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem1,
            this.menuItem2});
            //
            // imageList1
            //
            this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
            this.imageList1.Images.SetKeyName(0, "White.bmp");
            this.imageList1.Images.SetKeyName(1, "Black.bmp");
            this.imageList1.Images.SetKeyName(2, "None.bmp");
            //
            // Form1
            //
            this.AccessibleDescription = "";
            this.AllowDrop = true;
            this.ClientSize = new System.Drawing.Size(325, 333);
            this.Cursor = System.Windows.Forms.Cursors.Hand;
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.ImeMode = System.Windows.Forms.ImeMode.Off;
            this.MaximizeBox = false;
            this.Menu = this.mainMenu1;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "五子棋";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);

        }
        #endregion

 

        ///
        /// The main entry point for the application.
        ///
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

 

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

 

        private void menuItem3_Click(object sender, System.EventArgs e)
        {

 

        }

 

        private void Form1_Load(object sender, System.EventArgs e)
        {

        
        
        }

 

        private void menuItem1_Click(object sender, System.EventArgs e)
        {

 

        }

 

        private void menuItem4_Click_1(object sender, System.EventArgs e)
        {
            //(new About()).ShowDialog();
        }

 

        private void menuItem2_Click(object sender, System.EventArgs e)
        {

 

        }

 

        private void menuItem3_Click_1(object sender, System.EventArgs e)
        {
            //new Help().ShowDialog();
        }

 

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

 

        private void menuItem5_Click(object sender, System.EventArgs e)
        {
            if (History.Count > 0) this.Reset();
        }

 

        private void menuItem8_Click(object sender, System.EventArgs e)
        {
            Penitence();
        }

 

        //重载重画函数
        protected override void OnPaint(PaintEventArgs e)
        {
            System.Drawing.Graphics g = this.CreateGraphics();
            for (int x = 0; x < 15; x++)
            {
                for (int y = 0; y < 15; y++)
                {
                    if (checkerBoard[y, x] != None) DrawChess(new Point(x, y), checkerBoard[y, x]);
                }
            }
            ReDrawNextPlayerMark();
            base.OnPaint(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            this.Text = "五子棋   " + "X=" + e.X.ToString() + " Y=" + e.Y.ToString();
        }

        //重载鼠标按下事件
        protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseDown(e);
            switch (e.Button)
            {
                //take left button down
                case MouseButtons.Left:
                    if ((History.Count == 0) && (2 < e.X) && (e.X < 22) && (309 < e.Y) && (e.Y < 329))
                        Player = (Player == White) ? Black : White;
                    else AddChess(MToA(new Point(e.X, e.Y)));
                    break;
                //take right button down
                case MouseButtons.Right:
                    // OnRButtonDown(new Point(e.X,e.Y));
                    break;
            }
        }

 

        //把鼠标坐标转换成棋盘坐标
        private Point MToA(Point p)
        {
            return new Point((p.X - 10) / 20, (p.Y - 6) / 20);
        }

 

        //开始新的棋局,所有数据复位并重画棋盘
        private void Reset()
        {
            for (int i = 0; i < 15; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    checkerBoard[i, j] = None;
                }
            }
            History.Clear();//清空历史记录
            DrawCheckerBoard();//重画棋盘
        }

 

        //重画棋盘
        private void DrawCheckerBoard()
        {
            this.BackColor = System.Drawing.SystemColors.Desktop;
            this.BackColor = System.Drawing.SystemColors.Control;
          
        }

 

        //重画下一个选手的标志棋子
        private void ReDrawNextPlayerMark()
        {
            System.Drawing.Graphics g = this.CreateGraphics();
            imageList1.Draw(g, 2, 309, 20, 20, Player);
        }

 

        //在棋盘上画一个棋子
        private void DrawChess(Point pCoordinates, int iPlayer)
        {
            System.Drawing.Graphics g = this.CreateGraphics();
            imageList1.Draw(g, 10 + pCoordinates.X * 20, 6 + pCoordinates.Y * 20, 20, 20, iPlayer);
        }

 

        //在指定的棋盘坐标位置添加一个棋子
        private void AddChess(Point p)
        {
            //判断是否超出边界
            if ((p.X < 0 || p.X > 14) || (p.Y < 0 || p.Y > 14)) return;
            //判断该位置有无棋子
            if (checkerBoard[p.Y, p.X] != None) return;//如果已经有了棋子则退出(这颗棋不能下)
            DrawChess(p, Player);
            if (Player == White)//该白棋下
            {
                checkerBoard[p.Y, p.X] = White;
                Player = Black;
            }
            else
            {
                checkerBoard[p.Y, p.X] = Black;
                Player = White;
            }
            History.Push(new Point(p.X, p.Y));//添加历史记录
            CheckGameResult(p);
        }

 

        //检查游戏结果
        /*
        * 算法:
        * 由于根据游戏规则,只有先放成 5 个相连的棋子的一方或剩,
        * 所以只要以刚刚下过的那个棋子为中心,检查有没有 5 个相连的同颜色棋子就好了。
        */
        private void CheckGameResult(Point sourcePoint)
        {
            int x, y;
            int LastPlayer = (Player == White) ? Black : White;
            int n;

 

            //检查行
            n = 1;
            y = sourcePoint.Y;
            for (x = sourcePoint.X - 1; x >= 0; x--)
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            for (x = sourcePoint.X + 1; x < 15; x++)
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            if (n >= 5)
            {
                Win(LastPlayer);
                return;
            }

 

            //检查列
            n = 1;
            x = sourcePoint.X;
            for (y = sourcePoint.Y - 1; y >= 0; y--)
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            for (y = sourcePoint.Y + 1; y < 15; y++)
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            if (n >= 5)
            {
                Win(LastPlayer);
                return;
            }

 

            //检查左斜线
            n = 1;
            for (x = sourcePoint.X + 1, y = sourcePoint.Y - 1; x < 15 && y >= 0; x++, y--)//检查左斜线的上半截
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            for (x = sourcePoint.X - 1, y = sourcePoint.Y + 1; x >= 0 && y < 15; x--, y++)//检查左斜线的下半截
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            if (n >= 5)
            {
                Win(LastPlayer);
                return;
            }

 

            //检查右斜线
            n = 1;
            for (x = sourcePoint.X - 1, y = sourcePoint.Y - 1; x >= 0 && y >= 0; x--, y--)//检查右斜线的上半截
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            for (x = sourcePoint.X + 1, y = sourcePoint.Y + 1; x < 15 && y < 15; x++, y++)//检查右斜线的下半截
            {
                if (checkerBoard[y, x] == LastPlayer) n++;
                else break;
            }
            if (n >= 5)
            {
                Win(LastPlayer);
                return;
            }

 

            //棋盘满棋,平手
            if (History.Count >= 225)
            {
                Win(None);
                return;
            }

 

        }

 

        //显示指定选手的获胜信息
        private void Win(int NPlayer)
        {
            switch (NPlayer)
            {
                case None:
                    MessageBox.Show("本局平手!", "恭喜!");
                    break;
                case White:
                    MessageBox.Show("本局 白棋 获胜 !", "恭喜!");
                    break;
                case Black:
                    MessageBox.Show("本局 黑棋 获胜 !", "恭喜!");
                    break;
            }
            Reset();
        }

 

        //悔棋 1 步
        private void Penitence()
        {
            if (History.Count > 0)
            {
                Point p = (Point)History.Pop();
                checkerBoard[p.Y, p.X] = None;
                nextPlayer = (Player == White) ? Black : White;
                DrawCheckerBoard();
            }
        }

 

        private void menuItem10_Click(object sender, System.EventArgs e)
        {
            Player = (Player == White) ? Black : White;
        }

 

        private void menuItem1_Popup(object sender, System.EventArgs e)
        {
            if (History.Count == 0)
            {
                menuItem10.Visible = true;
                menuItem10.Text = (Player == White) ? "黑棋先下 (&B)" : "白棋先下 (&W)";
            }
            else menuItem10.Visible = false;
        }

        private ImageList imageList1;

 

    }
}

 

posted on 2008-10-23 11:06  踏燕归来  阅读(1129)  评论(0编辑  收藏  举报