c#实现扫雷游戏

using System;
using System.Collections.Generic;

namespace ClearMinesProject
{

    class Program
    {
        static void Main(string[] args)
        {
            //数字代表周围有几个雷
            GameController controller = new GameController(DifficultyLevel.Difficult);
            controller.StartGame();
        }
    }

    class GameController
    {
        public static Position[,] grids;   //雷区矩阵
        private int[,] gridsView;    //游戏显示矩阵,显示有几个雷
        public static int row;  //行
        public static int col;  //列
        private int mineCount;  //雷的个数
        private bool isGameOver = false;   //是否游戏结束
        private bool isWin = false;    //玩家是否胜利
        private bool isFirstPosition = true;  //标记是否是第一个打开的点
        /// <summary>
        /// 选择难度
        /// 1:9 X 9   10个雷
        /// 2.16 X 16  40个雷
        /// 3.16 X 30  99个雷
        /// </summary>
        /// <param name="level">难度等级</param>
        public GameController(DifficultyLevel level)
        {
            switch (level)
            {
                case DifficultyLevel.Easy:
                    grids = new Position[9, 9];
                    mineCount = 10;
                    break;
                case DifficultyLevel.Middle:
                    grids = new Position[16, 16];
                    mineCount = 40;
                    break;
                case DifficultyLevel.Difficult:
                    grids = new Position[16, 32];
                    mineCount = 99;
                    break;
                default:
                    break;
            }
            row = grids.GetLength(0);
            col = grids.GetLength(1);
            gridsView = new int[row, col];
            //实例化每个格子
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    grids[i, j] = new Position(i, j);
                }
            }

        }
        public void StartGame()
        {
            SetMines();
            while (isGameOver == false && isWin == false)
            {
                PrintView();
                Play();
            }
            if (isWin)
            {
                Console.WriteLine("玩家胜利!");
            }
            else
            {
                Console.WriteLine("点中了雷,游戏结束!");
            }
        }
        //输出雷盘
        public void PrintView()
        {
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    if (grids[i, j].IsOpen == false)
                    {
                        Console.Write("* ");
                    }
                    else
                    {
                        Console.Write(gridsView[i, j] + " ");
                    }
                }
                Console.WriteLine();
            }
        }

        //布置雷
        public void SetMines()
        {
            Random random = new Random();

            int i = mineCount;
            //此处不能用for循环(如果生成了同一个位置的点,必须重新生成)
            while (i > 0)
            {
                int x = random.Next(0, row);
                int y = random.Next(0, col);
                if (!grids[x, y].IsMine)   //如果该点不是雷
                {
                    grids[x, y].IsMine = true;
                    i--;
                }
            }
        }

        //判断是否胜利,所有空格都是打开状态就代表胜利
        public void IsWin()
        {
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    if ((grids[i, j].IsOpen == false))
                    {
                        //如果是雷(如果是雷,该点必定为false),跳过
                        if (grids[i, j].IsMine == true)
                        {
                            continue;
                        }
                        isWin = false;
                        return;
                    }
                }
            }
            isWin = true;
        }

        //开始下棋
        public void Play()
        {
            int x = 0;
            int y = 0;
            while (true)
            {
                Console.WriteLine("请输入下棋点坐标【(0,0)到({0},{1})】,一共有{2}个雷,输入类似于“5 5”:", row - 1, col - 1, mineCount);
                Console.Write("下棋点:");
                string str = Console.ReadLine();
                string[] nums = str.Split(' ');
                try
                {
                    x = int.Parse(nums[0]);
                    y = int.Parse(nums[1]);
                }
                catch (Exception e)
                {
                    Console.WriteLine("输入无效,请重新输入!");
                    continue;
                }

                if (isFirstPosition)
                {
                    isFirstPosition = false;
                    MoveFirstMine(x, y);
                }

                //x,y不能超过数组界限
                if (x < 0 || y < 0 || x >= row || y >= col)
                {
                    Console.WriteLine("超过网格界限,请重新输入!!!");
                    continue;
                }

                if (grids[x, y].IsOpen)   //该点已经被打开
                {
                    Console.WriteLine("该点已经被打开,请重新输入!!!");
                    continue;
                }
                else
                {
                    gridsView[x, y] = 1;
                    break;
                }
            }

            if (grids[x, y].IsMine)  //如果是雷,游戏结束
            {
                isGameOver = true;
                return;
            }

            //如果不是雷
            CheckAround(x, y);
            IsWin();
        }
        //如果一个点周围没有雷,展开这个点的周围
        public void CheckAround(int x, int y)
        {
            if (grids[x, y].IsOpen)
            {
                return;
            }
            grids[x, y].IsOpen = true;
            gridsView[x, y] = grids[x, y].mineAroundCount;
            if (grids[x, y].mineAroundCount == 0)
            {
                for (int i = x - 1; i <= x + 1; i++)
                {
                    for (int j = y - 1; j <= y + 1; j++)
                    {
                        if (i >= 0 && j >= 0 && i < row && j < col)
                        {
                            CheckAround(i, j);
                        }
                    }
                }
            }
        }

        //规避第一个点击的为雷,且控制第一点周围(九宫格)也没有雷
        public void MoveFirstMine(int x,int y)
        {
            int count = 2;   
            while (true)
            {
                for (int i = x - 1; i <= x + 1; i++)
                {
                    for (int j = y - 1; j <= y + 1; j++)
                    {
                        if (i >= 0 && j >= 0 && i < GameController.row && j < GameController.col)
                        {
                            //如果是雷,移到其他位置,且重新将扫描次数置为2,因为可能会将雷移到该九宫格其他的位置
                            if (grids[i, j].IsMine)   
                            {
                                MoveMineToOtherPosition(i, j);
                                count = 2;
                            }
                        }
                    }
                }
                count--;
                if (count == 0)
                {
                    break;
                }
            }
        }
        public void MoveMineToOtherPosition(int x,int y)
        {
            Random random = new Random();
            while (true)
            {
                int i = random.Next(0, row);
                int j = random.Next(0, col);
                if (!grids[i, j].IsMine)   //如果该点不是雷
                {
                    //将x,y点的雷移到i,j点上来
                    grids[x, y].IsMine = false;
                    grids[i, j].IsMine = true;
                    break;
                }
            }
        }
    }
    /// <summary>
    /// Position:一个单元格(坐标)信息
    /// </summary>
    class Position
    {
        //位置
        public int X;
        public int Y;
        public bool IsMine;   //是否是雷
        public bool IsOpen;   //该单元格是否点开
        public int mineAroundCount
        {
            get
            {
                //扫描该点的九宫格,遇到雷count加1
                int count = 0;
                for (int i = X - 1; i <= X + 1; i++)
                {
                    for (int j = Y - 1; j <= Y + 1; j++)
                    {
                        if (i >= 0 && j >= 0 && i < GameController.row && j < GameController.col)
                        {
                            if (GameController.grids[i, j].IsMine)
                            {
                                count++;
                            }
                        }
                    }
                }
                return count;
            }
        }

        public Position(int x, int y)
        {
            this.X = x;
            this.Y = y;
            IsMine = false;
            IsOpen = false;
        }
    }
    enum DifficultyLevel
    {
        Easy,
        Middle,
        Difficult
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_34937637/article/details/80990448
今日推荐