c#掃雷遊戲

來源:互聯網
上載者:User

一、C#實現掃雷

1、在form中

BombClass bombClass = new BombClass();        /*布雷按鈕事件*/        private void initBombBtn_Click(object sender, EventArgs e)        {            bombClass.InitBombData();            bombClass.winHandle = bombPanel.Handle;            bombPanel.Width = bombClass.Width;            bombPanel.Height = bombClass.Height;            bombClass.BombDraw();    //使用方法一畫雷盤            //bombClass.DispBomb();  //使用方法二畫雷盤        }        /*雷盤的滑鼠點擊事件:方法一 */        private void bombPanel_MouseClick(object sender, MouseEventArgs e)        {            //擷取滑鼠點擊時的位置            int row = e.Y / (bombClass.CellSize + 1);            int column = e.X / (bombClass.CellSize + 1);            //如果已經點擊過了            if (bombClass.BombDataFlag[row, column] == 1)                return;            //可以顯示標誌            bombClass.BombDataFlag[row, column] = 1;            //如果踩到的方格是數字            if (bombClass.BombData[row, column] > 0)            {                ;            }            else if (bombClass.BombData[row, column] == BombClass.BombInt)            {                bombClass.ShowAllBomb();                MessageBox.Show("踩到地雷了!");                return;            }            else if (bombClass.BombData[row, column] == 0)            {                //bombClass.NullDepthFindFirst(row, column);//深度優先搜尋                bombClass.NullWidthFindFirst(row, column);    //廣度優先搜尋            }            if (bombClass.CheckFinishFirst())            {                MessageBox.Show("成功!");                bombClass.ShowAllBomb();            }            else                bombClass.BombDraw();                    }        
/*掃雷panel重繪事件*/        private void bombPanel_Paint(object sender, PaintEventArgs e)        {            if (bombClass.BombStartFlag)            {                if (bombClass.winHandle == null)                    bombClass.winHandle = bombPanel.Handle;                bombClass.BombDraw();            }                    }

2、掃雷類 

public class BombClass    {        #region 參數        /*掃雷是否開始標誌*/        public bool BombStartFlag = false;        /*座標點資料結構*/        public struct point        {            public int row;            public int column;        };        /*雷數*/        public int BombCount;        /*雷數組*/        public int[,] BombData;        /*是否點擊的標誌*/        public int[,] BombDataFlag;        /*棋子大小*/        public int CellSize = 30;        /*表示地雷的數字*/        public const int BombInt = -2;        public System.IntPtr winHandle;        public int Width;        public int Height;        #endregion        /*初始化雷數組(點擊布雷按鈕之後才用)*/        public void InitBombData()        {            BombStartFlag = true;            BombCount = 10;            BombData = new int[BombCount, BombCount];            BombDataFlag = new int[BombCount, BombCount];  //是否點擊了的標誌數組            List<point> bombs = RadomBomb(BombCount);            SetBomb(bombs);            Width = (CellSize + 1) * BombCount + 1;            Height = (CellSize + 1) * BombCount + 1;                    }        /*隨機數產生雷的位置*/        protected List<point> RadomBomb(int BombCount)        {            List<point> bombs = new List<point>();            for (int i = 0; i < BombCount; i++)            {                Random rad = new Random();                int row = rad.Next(0, BombCount - 1);   //行號                int column = rad.Next(0, BombCount - 1);  //列號                bool checkFlag = false;                for (int j = 0; j < bombs.Count; j++)                {                    if (row == ((point)bombs[j]).row && column == ((point)bombs[j]).column)                    {                        checkFlag = true;//找到一個相同位置的點                        break;                    }                }                if (checkFlag)                {                    i--;  //退一位                    continue;                }                else                {                    point newPoint = new point() { row = row, column = column };                    bombs.Add(newPoint);                }            }            return bombs;        }        /*布雷(以雷為中心訪問四周)*/        protected void SetBomb(List<point> bombs)        {            for (int i = 0; i < bombs.Count; i++)            {                point onePoint = bombs[i];                //用-2表示地雷 -1表示已經遍曆過的空                BombData[onePoint.row, onePoint.column] = BombInt;                int[] locationRound = GetRoundLocation(onePoint.row, onePoint.column);                for (int j = 0; j < 8; j++)                {                    if (locationRound[j * 2] == -1)                        break;                    else if (BombData[locationRound[j * 2], locationRound[j * 2 + 1]] != BombInt)                        BombData[locationRound[j * 2], locationRound[j * 2 + 1]]++;                }            }        }        /*擷取四周合法的座標並返回*/        public int[] GetRoundLocation(int row, int column)        {            //不合法的用-1代替            int[] locationRound = new int[16];            for (int j = 0; j < 16; j++)            {                locationRound[j] = -1;            }            int i = 0;            //左上            if (row - 1 >= 0 && column - 1 >= 0)            {                locationRound[i++] = row - 1;                locationRound[i++] = column - 1;            }            //上            if (row - 1 >= 0)            {                locationRound[i++] = row - 1;                locationRound[i++] = column;            }            //右上            if (row - 1 >= 0 && column + 1 < BombCount)            {                locationRound[i++] = row - 1;                locationRound[i++] = column + 1;            }            //左            if (column - 1 >= 0)            {                locationRound[i++] = row;                locationRound[i++] = column - 1;            }            //右            if (column + 1 < BombCount)            {                locationRound[i++] = row;                locationRound[i++] = column + 1;            }            //左下            if (row + 1 < BombCount && column - 1 >= 0)            {                locationRound[i++] = row + 1;                locationRound[i++] = column - 1;            }            //下            if (row + 1 < BombCount)            {                locationRound[i++] = row + 1;                locationRound[i++] = column;            }            //右下            if (row + 1 < BombCount && column + 1 < BombCount)            {                locationRound[i++] = row + 1;                locationRound[i++] = column + 1;            }            return locationRound;        }        /*使用畫圖方法:畫雷盤一 */        public void BombDraw()        {            Image myImage = new Bitmap(Width, Height);            Graphics g = Graphics.FromImage(myImage);            //畫線(正方形的)            for (int i = 0; i <= BombCount; i++)            {                g.DrawLine(new Pen(Color.Black), (CellSize + 1) * i, 0,                    (CellSize + 1) * i, Height);                g.DrawLine(new Pen(Color.Black), 0, (CellSize + 1) * i,                    Width, (CellSize + 1) * i);            }            //畫方格及數字            for (int i = 0; i < BombCount; i++)            {                for (int j = 0; j < BombCount; j++)                {                    SolidBrush brush = new SolidBrush(Color.Gold);  //預設金色背景畫刷                    FontFamily fontFamily = new FontFamily("Arial");                    Font font = new Font(fontFamily, 16, FontStyle.Regular, GraphicsUnit.Pixel);                    string strTemp = "";  //預設需要寫的字                    //如果已經點擊過了,需要處理顯示行為                    if (BombDataFlag[i, j] == 1)                    {                        //如果點擊到的是大於0的數字                        if (BombData[i, j] > 0)                        {                            brush = new SolidBrush(Color.White);                            strTemp = BombData[i, j].ToString();                        }                        //如果點擊到的是空                        else if (BombData[i, j] == 0 || BombData[i, j] == -1)                        {                            brush = new SolidBrush(Color.White);                        }                        //如果點擊到的是地雷                        else if (BombData[i, j] == -2)                        {                            strTemp = "*";                        }                    }                    g.FillRectangle(brush, (CellSize + 1) * j + 1                                , (CellSize + 1) * i + 1, CellSize, CellSize);                    g.DrawString(strTemp, font, new SolidBrush(Color.Black),                                (CellSize + 1) * j + 8, (CellSize + 1) * i + 8);                }            }            Graphics gg = Graphics.FromHwnd(winHandle);            //Graphics gg = bombPanel.CreateGraphics();            gg.DrawImage(myImage, 0, 0);        }        /*踩到空時處理方法(深度優先搜尋):方法一*/        public void NullDepthFindFirst(int row, int column)        {            //遍曆到空,置為-1            BombData[row, column] = -1;            //擷取周圍8個座標位置(有時候四周並不具有8個位置,用-1表示不合法的位置)            int[] eightLocation = GetRoundLocation(row, column);            for (int i = 0; i < 8; i++)            {                //如果要訪問的座標位置不存在                if (eightLocation[i * 2] == -1)                    break;                else                {                    BombDataFlag[eightLocation[i * 2], eightLocation[i * 2 + 1]] = 1;                    if (BombData[eightLocation[i * 2], eightLocation[i * 2 + 1]] == 0)                    {                        //遞迴調用                        NullDepthFindFirst(eightLocation[i * 2], eightLocation[i * 2 + 1]);                    }                }            }        }        /*踩到空時處理方法(廣度優先搜尋):方法一*/        public void NullWidthFindFirst(int row, int column)        {            BombData[row, column] = -1;            BombDataFlag[row,column] = 1;   //可以顯示標誌            //存放為空白的方格座標的隊列            int[] waitCheck = new int[BombCount * BombCount * 2];            for (int k = 0; k < waitCheck.Length; k++)            {                waitCheck[k] = -1;            }            waitCheck[0] = row;            waitCheck[1] = column;            int frontCount = 0;   //隊頭            int backCount = frontCount + 2;  //隊尾            //隊頭不等於隊尾            while (frontCount != backCount)            {                //置為已經訪問過                BombData[waitCheck[frontCount], waitCheck[frontCount + 1]] = -1;                                //得到周圍8個方位的座標                int[] eightLocation = GetRoundLocation(waitCheck[frontCount], waitCheck[frontCount + 1]);                //遍曆8個方位的座標,選擇可以加入候選隊列的座標                for (int i = 0; i < 8; i++)                {                    if (eightLocation[i * 2] == -1)                        break;                    else                    {                        BombDataFlag[eightLocation[i * 2], eightLocation[i * 2 + 1]] = 1;   //可以顯示標誌                        if (BombData[eightLocation[i * 2], eightLocation[i * 2 + 1]] == 0)                        {                            BombData[eightLocation[i * 2], eightLocation[i * 2 + 1]] = -1;                            //加入候選隊列                            waitCheck[backCount++] = eightLocation[i * 2];                            waitCheck[backCount++] = eightLocation[i * 2 + 1];                        }                    }                }                frontCount += 2;  //隊列指標移動            }        }                /*檢查掃雷是否完成:方法一*/        public bool CheckFinishFirst()        {            int leftCount = 0; //剩餘雷數            for (int i = 0; i < BombCount; i++)            {                bool flag = false;                for (int j = 0; j < BombCount; j++)                {                    if (BombDataFlag[i, j] == 0)                    {                        //未點擊且是雷                        if (BombData[i, j] == BombInt)                            leftCount++;                        //為點擊且不是雷,直接退出所有迴圈                        else                        {                            flag = true;                            break;                        }                    }                }                if (flag)                    break;            }            if (leftCount == BombCount)            {                return true;            }            else                return false;        }        /*踩到雷時顯示所有:方法一*/        public void ShowAllBomb()        {            for (int i = 0; i < BombCount; i++)            {                for (int j = 0; j < BombCount; j++)                {                    BombDataFlag[i, j] = 1;                }            }            BombDraw();        }    }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.