首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我在BattleShip控制台上做了一个简单的C#游戏

我在BattleShip控制台上做了一个简单的C#游戏
EN

Code Review用户
提问于 2021-11-03 20:35:11
回答 2查看 1.6K关注 0票数 1

我在C#控制台上做了一艘简单的战舰,使用一点AI (只是一点点),这个练习的目标是提高我对OOP的了解。

游戏规则:

1.你攻击敌人,然后敌人攻击你。

2.如果你没有在暗示的帮助下找到任何船只,你自己的一艘船就会沉没。

3.我写了一个简单的小小AI。如果敌人在他的回合中找不到你的飞船,他可以在附近搜索并找到下一个回合的船只(如果它在飞船附近)。

4.你和你的敌人只有5艘船。

首先,我把我的所有代码,然后解释它。

我的程序类主要方法:

代码语言:javascript
复制
    {
        static void Main()
        {

            GameEngine myGameEngine = new GameEngine();

            while (true)
            {
                myGameEngine.Engine();
            }
        }
    }

很简单很干净。

然后是gameEngine类:

代码语言:javascript
复制
class GameEngine
    {
        List<char> _myIsland = new List<char>();
        List<char> _enemyIsland = new List<char>();
        List<char> _enemyIslandCover = new List<char>();
        bool isGenerate;
        int hint;
        int cubePosition;
        char saveCharacter;
        private Ships ships;

        enum Direction
        {
            Up = -10,
            Left = -1,
            Right = 1,
            Down = 10
        }

        public GameEngine()
        {
            ships = new Ships(this, 5);
            hint = 1;
        }

        public void DrawIslands()
        {
            int Counter = 0;
            int HowManyTime = 0;
            Console.Clear();

            while (true)
            {
                HowManyTime += 10;
                while (Counter < HowManyTime)
                {
                    Console.Write("{0} ", _myIsland[Counter]);
                    Counter++;
                }

                Console.Write("║ ");
                Counter -= 10;

                while (Counter < HowManyTime)
                {
                    Console.Write("{0} ", _enemyIslandCover[Counter]);
                    Counter++;
                }

                Console.WriteLine();

                if (HowManyTime == 100)
                {
                    break;
                }
            }
        }

        private void ShowInformation()
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("░ YOUR SHIPS: {0} \t ENEMY's SHIP: {1} \t HINT: {2}", ships.YourShip, ships.EnemyShip, hint);
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("░ 1. ATTACK \t 2. HINT \t 3. EXIT");
            Console.ForegroundColor = ConsoleColor.White;
        }

        public void Engine()
        {
            if (!isGenerate)
            {
                FirstTimeGenerate();
            }
            DrawIslands();
            ShowInformation();
            string userInput = GetString("░ Choose a number > ");

            switch (userInput)
            {
                case "1":
                    cubePosition = 0;
                    saveCharacter = _enemyIslandCover[cubePosition];
                    _enemyIslandCover[cubePosition] = '■';
                    DrawIslands();
                    bool isEnter = false;
                    
                    while (!isEnter)
                    {
                        ConsoleKeyInfo readKey = Console.ReadKey();

                        switch (readKey.Key)
                        {
                            case ConsoleKey.UpArrow:
                                Move(Direction.Up);
                                break;

                            case ConsoleKey.DownArrow:
                                Move(Direction.Down);
                                break;

                            case ConsoleKey.RightArrow:
                                Move(Direction.Right);
                                break;

                            case ConsoleKey.LeftArrow:
                                Move(Direction.Left);
                                break;

                            case ConsoleKey.Enter:
                                isEnter = true;
                                bool result = ships.Attack(_enemyIsland, _enemyIslandCover , cubePosition);

                                if (result)
                                {
                                    GetSucces("You Sink One of the Enemy's Ship!! POWER");
                                    if (hint == 0)
                                    {
                                        hint++;
                                    }
                                    HasAnyoneWon();
                                }
                                else
                                {
                                    GetError("DAMN IT ADMIRAL!!!");
                                }
                                break;
                        }
                    }

                    ships.EnemyAttack(_myIsland);
                    HasAnyoneWon();

                    break;

                case "2":
                    if (hint == 1)
                    {
                        string userChoice = GetString("Are you sure for use hint [PRESS Y]? (if there is no ship in row, One of your ship will sink)");
                        if (userChoice == "y")
                        {
                            bool result = ships.Hint(_enemyIsland, _enemyIslandCover);
                            hint = 0;
                            if (!result)
                            {
                                for (int i = 0; i < 3; i++)
                                {
                                    int index = _myIsland.LastIndexOf('@');
                                    _myIsland.RemoveAt(index);
                                    _myIsland.Insert(index, '░');
                                }
                                DrawIslands();
                                HasAnyoneWon();
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        GetError("You have no any hint.");
                    }
                    break;

                case "3":
                    Console.Clear();
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Thank you for choose my game. See you later");
                    Console.ForegroundColor = ConsoleColor.White;
                    Environment.Exit(0);
                    break;

                default:
                    GetError("You Put Wrong Value!");
                    break;
            }
        }

        private void FirstTimeGenerate()
        {
            for (int i = 0; i < 100; i++)
            {
                _myIsland.Add('■');
                _enemyIsland.Add('■');
                _enemyIslandCover.Add('·');
            }
            ships.GenerateShips(_myIsland);
            ships.GenerateShips(_enemyIsland);
            isGenerate = true;
        }

        private void Move(Direction dir)
        {
            _enemyIslandCover[cubePosition] = saveCharacter;
            cubePosition += (int)dir;

            if (cubePosition > 0 && cubePosition < 100)
            {
                saveCharacter = _enemyIslandCover[cubePosition];
                _enemyIslandCover[cubePosition] = '■';
                DrawIslands();
            }
            else
            {
                GetError("You Can't Move Outer the Field");
                cubePosition = 0;
            }
        }

        private void HasAnyoneWon()
        {
            if (ships.EnemyShip == 0 || ships.YourShip == 0)
            {
                int Counter = 0;
                int HowManyTime = 0;
                Console.Clear();

                while (true)
                {
                    HowManyTime += 10;
                    while (Counter < HowManyTime)
                    {
                        Console.Write("{0} ", _myIsland[Counter]);
                        Counter++;
                    }

                    Console.Write("║ ");
                    Counter -= 10;

                    while (Counter < HowManyTime)
                    {
                        Console.Write("{0} ", _enemyIsland[Counter]);
                        Counter++;
                    }

                    Console.WriteLine();

                    if (HowManyTime == 100)
                    {
                        break;
                    }
                }

                if (ships.EnemyShip == 0)
                {
                    GetSucces("YOU WON ADMIRAL! WE BACK TO THE COUNTRY AND TELL TO PEOPLE ABOUT YOUR BRAVE!!!! HOOOOOOOOOORAY");
                }
                else
                {
                    GetError("YOU LOOSE ADMIRAL! DON'T BE UPSET. PLAY GAME AGAIN!");
                }

                Environment.Exit(0);
            }
        }

        // STATIC METHOD - ONCE WRITE EVERYWHERE USE
        public static string GetString(string message)
        {
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.Write(message.ToLower());
            Console.ForegroundColor = ConsoleColor.White;
            return Console.ReadLine();
        }

        public static void GetError(string message)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message);
            Console.ForegroundColor = ConsoleColor.White;
            Thread.Sleep(3000);
        }

        public static void GetSucces(string message)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(message);
            Console.ForegroundColor = ConsoleColor.White;
            Thread.Sleep(2000);
        }
    }

我的最后一门课叫做“船”,因为这个类生成和创建船,以及所有关于船的东西:

代码语言:javascript
复制
class Ships
    {
        public int YourShip { get; set; }
        public int EnemyShip { get; set; }
        int indexOfAI = 0;
        private GameEngine gameEnigne;

        public Ships(GameEngine gameEngine, int howManyShip)
        {
            this.gameEnigne = gameEngine;
            YourShip = howManyShip;
            EnemyShip = howManyShip;
        }

        public void GenerateShips(List<char> island)
        {
            int counter = 0;
            Random randomGenerator = new Random();
            while (true)
            {
                if (counter == YourShip)
                {
                    break;
                }

                int index = randomGenerator.Next(0, island.Count);

                if (FindBestPlace(index, island))
                {
                    island[index] = '@';
                    island[index - 1] = '@';
                    island[index + 1] = '@';

                    counter++;
                }
                else
                {
                    continue;
                }
            }
        }

        private bool FindBestPlace(int index, List<char> island)
        {
            try
            {
                int Counter = index - (index % 10);
                for (int i = Counter; i < Counter + 10; i++)
                {
                    if (island[i] != '■')
                    {
                        return false;
                    }
                }
                if (index % 10 > 2 && index % 10 < 9)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        public bool Hint(List<char> enemyIsland, List<char> enemyIslandCover)
        {
            Random rnd = new Random();
            int index = 0;
            bool sunkenShip = false;
            bool thereIsAnyShip = false;

            while (!sunkenShip)
            {
                index = enemyIsland.Count / 10 * (rnd.Next(0, 10));

                sunkenShip = true;
                thereIsAnyShip = false;

                for (int i = index; i < index + 10; i++)
                {
                    if (enemyIsland[i] == '░')
                    {
                        sunkenShip = false;
                        break;
                    }
                    if (enemyIsland[i] == '@')
                    {
                        thereIsAnyShip = true;
                    }
                }
            }

            for (int i = index; i < index + 10; i++)
            {
                enemyIslandCover[i] = enemyIsland[i];
            }
            gameEnigne.DrawIslands();
            Thread.Sleep(1000);
            for (int i = index; i < index + 10; i++)
            {
                enemyIslandCover[i] = '·';
            }
            gameEnigne.DrawIslands();

            if (!thereIsAnyShip)
            {
                YourShip--;
            }

            return thereIsAnyShip;
        }

        public bool Attack(List<char> enemyIsland, List<char> enemyIslandCover, int cubePosition)
        {
            if (enemyIsland[cubePosition] == '@')
            {
                int rowIndex = cubePosition - (cubePosition % 10);
                for (int i = rowIndex; i < rowIndex + 10; i++)
                {
                    if (enemyIsland[i] == '@')
                    {
                        enemyIsland[i] = '░';
                        enemyIslandCover[i] = '░';
                    }
                }
                gameEnigne.DrawIslands();
                EnemyShip--;

                return true;
            }
            else
            {
                enemyIslandCover[cubePosition] = '%';
                return false;
            }

        }

        public void EnemyAttack(List<char> MyIsland)
        {
            GameEngine.GetError("It's Turn of enemy | HIDE HIDE HIIIIIIIDE !!!! ");

            int index;
            Random rnd = new Random();
            if (indexOfAI > 0)
            {
                if (indexOfAI < 70)
                {
                    index = rnd.Next(indexOfAI, indexOfAI + 30);
                }
                else
                {
                    index = rnd.Next(indexOfAI, MyIsland.Count);
                }
            }
            else
            {
                index = rnd.Next(0, MyIsland.Count);
            }

            char saveChar = MyIsland[index];
            MyIsland[index] = 'Ö';
            gameEnigne.DrawIslands();
            GameEngine.GetError("Enemy Choose His Location!! DON'T MOVE!! Sheeeeesh");

            MyIsland[index] = saveChar;

            bool isThereAnyShip = false;

            if (MyIsland[index] == '@')
            {
                int Counter = index - (index % 10);

                for (int i = Counter; i < Counter + 10; i++)
                {
                    if (MyIsland[i] == '@')
                    {
                        MyIsland[i] = '░';
                        isThereAnyShip = true;
                    }
                }
            }

            gameEnigne.DrawIslands();
            if (isThereAnyShip)
            {
                YourShip--;
                GameEngine.GetError("Enemy Sink One Of Your Ship Admiral, What's The Next Order ?");
                indexOfAI = 0;
            }
            else
            {
                GameEngine.GetSucces("The danger was eliminated. The enemy does not know the location of our ship!!");
                if (indexOfAI == 0)
                {
                    SimpleEnemyAI(index, MyIsland);
                }
                else
                {
                    indexOfAI = 0;
                }
            }  
        }

        private void SimpleEnemyAI(int index , List<char> Island)
        {
            // it's a algorithm for Simple AI
            if (index > 10)
            {
                index = index - (index % 10) - 10;
            }
            bool isAnyShipFind = false;

            if (index < 70)
            {
                for (int i = index; i < index + 20; i++)
                {
                    if (Island[i] == '@')
                    {
                        indexOfAI = index;
                        isAnyShipFind = true;
                        break;
                    }
                }
            }
            else
            {
                for (int i = index; i < Island.Count; i++)
                {
                    if (Island[i] == '@')
                    {
                        indexOfAI = index;
                        isAnyShipFind = true;
                        break;
                    }
                }
            }

            if (isAnyShipFind)
            {
                GameEngine.GetError("But Careful! Enemy Have Radar And He Saw Vague Things In It!!");
            }
            else
            {
                indexOfAI = 0;
            }
        }
    }

解释:

首先,我创建一个类并将其命名为GameEngine,并从Ships类创建一个对象,并将其保留为空,并为其创建一个构造函数:

代码语言:javascript
复制
        private Ships ships;

        public GameEngine()
        {
            ships = new Ships(this, 5);
            hint = 1;
        }

我将船只改装到一艘新船上,并将这个类作为一个对象发送给它(我确实发送了这个游戏引擎参考,并且没有创建一个新的GameEngine,因为如果我创建了一个新的GameEngine对象,那么我就无法访问已填充的列表)

通过这种方式(再次感谢@aepot),我可以访问Ships成员,并将一个GameEngine对象发送到Ships类,而且我可以神奇地访问ships类中的GameEngine成员,因为我将一个对象从GameEngine发送到Ships类。然后,我将5个动态参数发送给船舰构造器。这个数字是关于敌舰和我们自己的数量(我本可以让它变得动态,但是我更专注于游戏,所以我发送了一个类似5的const号码),参见:

代码语言:javascript
复制
        public int YourShip { get; set; }
        public int EnemyShip { get; set; }
        int indexOfAI = 0;
        private GameEngine gameEnigne;

        public Ships(GameEngine gameEngine, int howManyShip)
        {
            this.gameEnigne = gameEngine;
            YourShip = howManyShip;
            EnemyShip = howManyShip;
        }

我解释一下indexOfAI。

我列了三张单子。其中之一是我的岛或海。其中之一是敌人的岛屿或海洋。最后一个是敌人的岛屿,但是我用点的方式覆盖了它,因为我们没有任何许可去看敌人的岛的细节。

代码语言:javascript
复制
        List<char> _myIsland = new List<char>();
        List<char> _enemyIsland = new List<char>();
        List<char> _enemyIslandCover = new List<char>();

然后编写一个FirstTimeGenerate方法并将其调用到Engine方法:

代码语言:javascript
复制
private void FirstTimeGenerate()
        {
            for (int i = 0; i < 100; i++)
            {
                _myIsland.Add('■');
                _enemyIsland.Add('■');
                _enemyIslandCover.Add('·');
            }
            ships.GenerateShips(_myIsland);
            ships.GenerateShips(_enemyIsland);
            isGenerate = true;
        }

在FirstTimeGenerate中,您可以看到GenerateShips Method.This方法和FindBestPlace将船只放置在岛上或海上:

代码语言:javascript
复制
        public void GenerateShips(List<char> island)
        {
            int counter = 0;
            Random randomGenerator = new Random();
            while (true)
            {
                if (counter == YourShip)
                {
                    break;
                }

                int index = randomGenerator.Next(0, island.Count);

                if (FindBestPlace(index, island))
                {
                    island[index] = '@';
                    island[index - 1] = '@';
                    island[index + 1] = '@';

                    counter++;
                }
                else
                {
                    continue;
                }
            }
        }

FindBestPlaceMethod:

代码语言:javascript
复制
        private bool FindBestPlace(int index, List<char> island)
        {
            try
            {
                int Counter = index - (index % 10);
                for (int i = Counter; i < Counter + 10; i++)
                {
                    if (island[i] != '■')
                    {
                        return false;
                    }
                }
                if (index % 10 > 2 && index % 10 < 9)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

FindBestPlace在岛上搜索并生成随机数,如果行数为空(没有船在行),则创建一个船,否则再次搜索并再次生成编号。

在此之后,我创建了绘制海岛的方法,并显示了用户选择和评分等信息。

代码语言:javascript
复制
         public void DrawIslands()
        {
            int Counter = 0;
            int HowManyTime = 0;
            Console.Clear();

            while (true)
            {
                HowManyTime += 10;
                while (Counter < HowManyTime)
                {
                    Console.Write("{0} ", _myIsland[Counter]);
                    Counter++;
                }

                Console.Write("║ ");
                Counter -= 10;

                while (Counter < HowManyTime)
                {
                    Console.Write("{0} ", _enemyIslandCover[Counter]);
                    Counter++;
                }

                Console.WriteLine();

                if (HowManyTime == 100)
                {
                    break;
                }
            }
        }

        private void ShowInformation()
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("░ YOUR SHIPS: {0} \t ENEMY's SHIP: {1} \t HINT: {2}", 
            ships.YourShip, ships.EnemyShip, hint);
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("░ 1. ATTACK \t 2. HINT \t 3. EXIT");
            Console.ForegroundColor = ConsoleColor.White;
        }

在该算法中,从我们自己的海域显示前10步,然后显示出距离敌人海10步的距离(注意,在敌人的海上,我们只看到点,因为我们无权进入敌舰的位置)

然后我写了提示方法,但首先看一下提示引擎:

代码语言:javascript
复制
               case "2":
                    if (hint == 1)
                    {
                        string userChoice = GetString("Are you sure for use hint [PRESS Y]? (if 
                        there is no ship in row, One of your ship will sink)");
                        if (userChoice == "y")
                        {
                            bool result = ships.Hint(_enemyIsland, _enemyIslandCover);
                            hint = 0;
                            if (!result)
                            {
                                for (int i = 0; i < 3; i++)
                                {
                                    int index = _myIsland.LastIndexOf('@');
                                    _myIsland.RemoveAt(index);
                                    _myIsland.Insert(index, '░');
                                }
                                DrawIslands();
                                HasAnyoneWon();
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        GetError("You have no any hint.");
                    }
                    break;

提示方法:

代码语言:javascript
复制
        public bool Hint(List<char> enemyIsland, List<char> enemyIslandCover)
        {
            Random rnd = new Random();
            int index = 0;
            bool sunkenShip = false;
            bool thereIsAnyShip = false;

            while (!sunkenShip)
            {
                index = enemyIsland.Count / 10 * (rnd.Next(0, 10));

                sunkenShip = true;
                thereIsAnyShip = false;

                for (int i = index; i < index + 10; i++)
                {
                    if (enemyIsland[i] == '░')
                    {
                        sunkenShip = false;
                        break;
                    }
                    if (enemyIsland[i] == '@')
                    {
                        thereIsAnyShip = true;
                    }
                }
            }

            for (int i = index; i < index + 10; i++)
            {
                enemyIslandCover[i] = enemyIsland[i];
            }
            gameEnigne.DrawIslands();
            Thread.Sleep(1000);
            for (int i = index; i < index + 10; i++)
            {
                enemyIslandCover[i] = '·';
            }
            gameEnigne.DrawIslands();

            if (!thereIsAnyShip)
            {
                YourShip--;
            }

            return thereIsAnyShip;
        }

如果用户选择2提示方法运行,但首先我为用户添加一些表达式:首先检查用户是否有提示。然后我问一个问题,你确定要使用你的提示吗?因为如果你使用它而找不到任何一艘船,你就会失去你的船。然后我发送敌人岛名单和掩护名单。在提示方法中,将创建一个随机数并检查该随机数行是否有接收器船,再次搜索新行并创建新的随机数。

如果你按1,如果轮到你,你就可以攻击

代码语言:javascript
复制
                    case "1":
                    cubePosition = 0;
                    saveCharacter = _enemyIslandCover[cubePosition];
                    _enemyIslandCover[cubePosition] = '■';
                    DrawIslands();
                    bool isEnter = false;
                    
                    while (!isEnter)
                    {
                        ConsoleKeyInfo readKey = Console.ReadKey();

                        switch (readKey.Key)
                        {
                            case ConsoleKey.UpArrow:
                                Move(Direction.Up);
                                break;

                            case ConsoleKey.DownArrow:
                                Move(Direction.Down);
                                break;

                            case ConsoleKey.RightArrow:
                                Move(Direction.Right);
                                break;

                            case ConsoleKey.LeftArrow:
                                Move(Direction.Left);
                                break;

                            case ConsoleKey.Enter:
                                isEnter = true;
                                bool result = ships.Attack(_enemyIsland, _enemyIslandCover , 
                                cubePosition);

                                if (result)
                                {
                                    GetSucces("You Sink One of the Enemy's Ship!! POWER");
                                    if (hint == 0)
                                    {
                                        hint++;
                                    }
                                    HasAnyoneWon();
                                }
                                else
                                {
                                    GetError("DAMN IT ADMIRAL!!!");
                                }
                                break;
                        }
                    }

                    ships.EnemyAttack(_myIsland);
                    HasAnyoneWon();

                    break;

在第一次,我把光标或点在敌人的第一个海(在零)。然后,您可以使用此方法实时地移动诅咒器,并进行以下操作:

Enum:

代码语言:javascript
复制
        enum Direction
        {
            Up = -10,
            Left = -1,
            Right = 1,
            Down = 10
        }

Up = -10意味着如果您选择向上游标移动-10步回到列表和.

移动方法:

代码语言:javascript
复制
        private void Move(Direction dir)
        {
            _enemyIslandCover[cubePosition] = saveCharacter;
            cubePosition += (int)dir;

            if (cubePosition > 0 && cubePosition < 100)
            {
                saveCharacter = _enemyIslandCover[cubePosition];
                _enemyIslandCover[cubePosition] = '■';
                DrawIslands();
            }
            else
            {
                GetError("You Can't Move Outer the Field");
                cubePosition = 0;
            }
        }

在这个方法中,我保存了正方形在saveCharacter变量中将要占用的下一个house字符,我以前在这个方法的外部和在同一个类中定义了这个变量。

如果你按回车,你就可以攻击正方形的房子:

代码语言:javascript
复制
                           case ConsoleKey.Enter:
                                isEnter = true;
                                bool result = ships.Attack(_enemyIsland, _enemyIslandCover , 
                                cubePosition);

                                if (result)
                                {
                                    GetSucces("You Sink One of the Enemy's Ship!! POWER");
                                    if (hint == 0)
                                    {
                                        hint++;
                                    }
                                    HasAnyoneWon();
                                }
                                else
                                {
                                    GetError("DAMN IT ADMIRAL!!!");
                                }
                                break;

我发送敌人名单和立方体位置(立方体索引)。在攻击方法中,我写了一个算法。如果我是在船上开枪的话,那么船沉了,敌人输了一分,否则什么都不会发生,只会显示一个“%”的标志,因为你还记得你拍过这个位置

代码语言:javascript
复制
        public bool Attack(List<char> enemyIsland, List<char> enemyIslandCover, int cubePosition)
        {
            if (enemyIsland[cubePosition] == '@')
            {
                int rowIndex = cubePosition - (cubePosition % 10);
                for (int i = rowIndex; i < rowIndex + 10; i++)
                {
                    if (enemyIsland[i] == '@')
                    {
                        enemyIsland[i] = '░';
                        enemyIslandCover[i] = '░';
                    }
                }
                gameEnigne.DrawIslands();
                EnemyShip--;

                return true;
            }
            else
            {
                enemyIslandCover[cubePosition] = '%';
                return false;
            }

        }

这正是敌人进攻时发生的情况,但差别不大。看:

代码语言:javascript
复制
        public void EnemyAttack(List<char> MyIsland)
        {
            GameEngine.GetError("It's Turn of enemy | HIDE HIDE HIIIIIIIDE !!!! ");

            int index;
            Random rnd = new Random();
            if (indexOfAI > 0)
            {
                if (indexOfAI < 70)
                {
                    index = rnd.Next(indexOfAI, indexOfAI + 30);
                }
                else
                {
                    index = rnd.Next(indexOfAI, MyIsland.Count);
                }
            }
            else
            {
                index = rnd.Next(0, MyIsland.Count);
            }

            char saveChar = MyIsland[index];
            MyIsland[index] = 'Ö';
            gameEnigne.DrawIslands();
            GameEngine.GetError("Enemy Choose His Location!! DON'T MOVE!! Sheeeeesh");

            MyIsland[index] = saveChar;

            bool isThereAnyShip = false;

            if (MyIsland[index] == '@')
            {
                int Counter = index - (index % 10);

                for (int i = Counter; i < Counter + 10; i++)
                {
                    if (MyIsland[i] == '@')
                    {
                        MyIsland[i] = '░';
                        isThereAnyShip = true;
                    }
                }
            }

            gameEnigne.DrawIslands();
            if (isThereAnyShip)
            {
                YourShip--;
                GameEngine.GetError("Enemy Sink One Of Your Ship Admiral, What's The Next Order 
                ?");
                indexOfAI = 0;
            }
            else
            {
                GameEngine.GetSucces("The danger was eliminated. The enemy does not know the 
                location of our ship!!");
                if (indexOfAI == 0)
                {
                    SimpleEnemyAI(index, MyIsland);
                }
                else
                {
                    indexOfAI = 0;
                }
            }  
        }

敌人会随机生成我的岛屿或海洋的房屋,如果它恰好是在我的船上被击中,那么我的得分就会下降,但是如果他不能射中我的船,那么运行一个名为SimpleEnemyAI()的方法。这个方法在枪口附近找到,然后看着我的船。如果有船在该地区,然后设置敌人的指数更近。

SimpleEnemyAI方法:

代码语言:javascript
复制
         private void SimpleEnemyAI(int index , List<char> Island)
        {
            // it's a algorithm for Simple AI
            if (index > 10)
            {
                index = index - (index % 10) - 10;
            }
            bool isAnyShipFind = false;

            if (index < 70)
            {
                for (int i = index; i < index + 20; i++)
                {
                    if (Island[i] == '@')
                    {
                        indexOfAI = index;
                        isAnyShipFind = true;
                        break;
                    }
                }
            }
            else
            {
                for (int i = index; i < Island.Count; i++)
                {
                    if (Island[i] == '@')
                    {
                        indexOfAI = index;
                        isAnyShipFind = true;
                        break;
                    }
                }
            }

            if (isAnyShipFind)
            {
                GameEngine.GetError("But Careful! Enemy Have Radar And He Saw Vague Things In 
                It!!");
            }
            else
            {
                indexOfAI = 0;
            }
        }

为了使游戏不困难,如果你注意这个方法,你就会意识到这并不是每次都发生的。

这是我的练习。如果你能提醒我我的问题,如果有什么能改善我的地方,我将不胜感激。

EN

回答 2

Code Review用户

发布于 2021-11-04 11:42:38

试着注意你如何命名事物,因为当其他人阅读你的代码时,它真的很重要。

方法名:

方法名应该永远是动词而不是名词,因为方法可以做事情。

  • myGameEngine.Engine()应该是myGameEngine.startEngine()myGameEngine.runEngine()或简单的myGameEngine.start()
  • FirstTimeGenerate()应该是GenerateFirstTime(),或者更清楚的名称应该是GenerateFirstFram()
  • Hint()应该是displayHint()PrintHint()

属性名称:

字段名应该是描述性名词,不使用代词你的,我的,...etc。

  • _myIsland应该更具有描述性,比如_userIsland
  • YourShip用作用户船舶计数的计数器,因此您应该将其命名为UserShipsCount,类似于EnemyShip应该是EnemyShipsCount
  • hint在GameEngine类中应该是hintCounter或更多的描述性displayedHintCounter

在接下来的和平中

代码语言:javascript
复制
private bool FindBestPlace(int index, List<char> island)
{
    try
    {
        int Counter = index - (index % 10);  // << what is 10 
        for (int i = Counter; i < Counter + 10; i++)
        {
            if (island[i] != '■')
            {
                return false;
            }
        }
        if (index % 10 > 2 && index % 10 < 9)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }
}

我不知道数字10在这个上下文中代表什么,您不应该在代码中使用普通数字,而是可以定义一个常量并使用它。

代码语言:javascript
复制
const int ROW_LENTH = 10; 
票数 2
EN

Code Review用户

发布于 2021-11-04 14:01:08

使用有意义的名称

我同意易卜拉欣的观点,你说事情的方式有点混乱。

GetError应该做什么?更好的名字应该是ShowError

GetSucces也是如此。为什么不选择ShowSuccessMessage呢?

无限环

HasAnyoneWon中,您有一个无限循环,但是当HowManyTime达到100时就会爆发。以下内容本可读得更清楚:

代码语言:javascript
复制
while (HowManyTime < 100)
{
    // ...
}

这同样适用于GenerateShips

代码语言:javascript
复制
public void GenerateShips(List<char> island)
{
    int counter = 0;
    var randomGenerator = new Random();
    while (counter < YourShip)
    {
        int index = randomGenerator.Next(0, island.Count);
        if (FindBestPlace(index, island))
        {
            island[index] = '@';
            island[index - 1] = '@';
            island[index + 1] = '@';
            counter++;
        }
    }
}

将复杂性分解为函数

void Engine()中发生的事情太多了。我建议你把它分成以下几个部分:

代码语言:javascript
复制
void Attach()
{
    // ...
}

void ShowHint()
{
    // ...
}

void ExitGame()
{
    // ...
}

public void Engine()
{
    if (!isGenerate)
    {
        FirstTimeGenerate();
    }
    DrawIslands();
    ShowInformation();
    string userInput = GetString("░ Choose a number > ");

    switch (userInput)
    {
        case "1":
            Attach();
            break;

        case "2":
            ShowHint();
            break;

        case "3":
            ExitGame();
            break;

        default:
            GetError("You Put Wrong Value!");
            break;
    }
}

屏幕闪烁

这款游戏看上去更加完美,没有Console.Clear()引起的闪烁。我建议您使用Console.SetCursorPosition并覆盖所需的文本。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/269715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档