RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1594879
Accepted
AslanPAPA
AslanPAPA
Asked:2024-09-26 01:27:52 +0000 UTC2024-09-26 01:27:52 +0000 UTC 2024-09-26 01:27:52 +0000 UTC

在 C# 中将船只放置在战场上(控制台海战)

  • 772

我想写一个控制台海战,现在我只显示玩家字段。

using System;


class Program
{
    static int fieldSize = 10;
    static char[,] PlayerField = new char[fieldSize, fieldSize];
    static char[,] OpponentField = new char[fieldSize, fieldSize];
    static Random rnd = new Random();

    static void Main(string[] args)
    {
        InitializateField(PlayerField);
        InitializateField(OpponentField);

        PrintField(PlayerField, "Поле игрока:");
            

    }

    static void InitializateField(char [,] field)
    {
        for (int i = 0; i < fieldSize; ++i)
        {
            for (int j = 0; j < fieldSize; ++j)
            {
                field[i,j] = '~';
            }
        }
    }


    static void PrintField(char[,] field, string nameOfField)
    {
        Console.WriteLine(nameOfField);
        Console.Write("  ");
        for (int i = 0; i < fieldSize; ++i)
            Console.Write($"{i + 1} ");
        Console.WriteLine();  

        for (int i = 0; i < fieldSize; ++i)
        {
            Console.Write($"{(char)('A' + i)} ");
            for (int j = 0; j < fieldSize; ++j)
            {
                Console.Write($"{field[i,j]} ");
            }
            Console.WriteLine();
        }  
    }

}

我真的不明白如何在场上安排船只,我所能做的就是自己随机安排船只 10 次,然后在 (0, 9) 范围内调用随机,对于每个值都会有case它的值自己手动放置。那么如何理解在战场上放置船只的算法呢?

以下是放置船只的方法:

 static void PlaceShips(char[,] field)
        {
            PlaceShip(field, 4); 
            for (int i = 0; i < 2; i++) PlaceShip(field, 3); 
            for (int i = 0; i < 3; i++) PlaceShip(field, 2); 
            for (int i = 0; i < 4; i++) PlaceShip(field, 1); 
        }

    
        static void PlaceShip(char[,] field, int size)
        {
            bool placed = false;
            while (!placed)
            {
                // Выбираем случайное направление: 0 - горизонтально, 1 - вертикально
                int direction = rnd.Next(2);
                // Случайные координаты для начальной точки корабля
                int row = rnd.Next(fieldSize);
                int col = rnd.Next(fieldSize);

                if (CanPlaceShip(field, row, col, size, direction))
                {
                    // Размещаем корабль
                    for (int i = 0; i < size; i++)
                    {
                        if (direction == 0)
                            field[row, col + i] = 'S'; // горизонтально
                        else
                            field[row + i, col] = 'S'; // вертикально
                    }
                    placed = true;
                }
            }
        }

    // Проверка, можно ли разместить корабль
        static bool CanPlaceShip(char[,] field, int row, int col, int size, int direction)
        {
            // Проверяем, не выходит ли корабль за границы
            if (direction == 0 && col + size > fieldSize) return false; // горизонтально
            if (direction == 1 && row + size > fieldSize) return false; // вертикально

            // Проверяем, что на пути корабля нет других кораблей
            for (int i = 0; i < size; i++)
            {
                int r = row + (direction == 1 ? i : 0);
                int c = col + (direction == 0 ? i : 0);

                if (field[r, c] == 'S' || !IsSurroundingAreaClear(field, r, c))
                {
                    return false; // Есть пересечения
                }
            }

            return true;
        }

    // Проверка, что вокруг клетки корабля нет других кораблей
        static bool IsSurroundingAreaClear(char[,] field, int row, int col)
        {
            for (int i = row - 1; i <= row + 1; i++)
            {
                for (int j = col - 1; j <= col + 1; j++)
                {
                    if (i >= 0 && i < fieldSize && j >= 0 && j < fieldSize)
                    {
                        if (field[i, j] == 'S')
                            return false;
                    }
                }
            }
            return true;
        }

但我认为解析起来会非常困难,我该如何解析这些方法以便了解它是如何生成船舶的?

c#
  • 1 1 个回答
  • 82 Views

1 个回答

  • Voted
  1. Best Answer
    aepot
    2024-09-26T06:03:34Z2024-09-26T06:03:34Z

    我查看了你的代码,查看了@EvgeniyZ 的代码并在两者之间写了一些东西。

    首先引起我注意的是检查安装这艘船的可能性。如果相邻单元格的检查会相交,为什么还要通过坐标检查 9 个单元格?一次性检查整个矩形不是更容易吗?

    例如,这个是 4 层甲板的?

    ~ ~ ~ ~ ~ ~
    ~ S S S S ~
    ~ ~ ~ ~ ~ ~
    

    也就是3到6,这不符合逻辑吗?

    好吧,方法诞生了:

    static bool CanPlaceShip(char[,] grid, int row, int col, int height, int width)
    {
        for (int i = row; i < row + height; i++)
        {
            for (int j = col; j < col + width; j++)
            {
                if (i >= 0 && i < grid.GetLength(0) && j >= 0 && j < grid.GetLength(1) && grid[i, j] == 'S')
                {
                    return false;
                }
            }
        }
        return true;
    }
    

    现在是船舶发电机

    我们本质上有一个基于船舶尺寸的生成顺序[4, 3, 3, 2, 2, 2, 1, 1, 1, 1]。这样的序列是由两个嵌套循环通过算法生成的。其中,最外层是从 4 到 1 的尺寸列表,内层是它们的数量,由公式 计算得出4 - размер + 1。

    然后,就像 @EvgeniyZ 所做的那样,我们尝试将船固定在随机坐标和随机方向上,直到它粘住为止。

    另一种方法诞生了:

    static void PlaceShips(char[,] grid)
    {
        Random rnd = Random.Shared;
        for (int shipSize = 4; shipSize > 0; shipSize--)
        {
            for (int count = 0; count <= 4 - shipSize; count++)
            {
                while (true)
                {
                    int vertical = rnd.Next(2);
                    int horizontal = 1 - vertical;
                    int rowOffset = (shipSize - 1) * vertical;
                    int colOffset = (shipSize - 1) * horizontal;
                    int row = rnd.Next(grid.GetLength(0) - rowOffset);
                    int col = rnd.Next(grid.GetLength(1) - colOffset);
    
                    if (CanPlaceShip(grid, row - 1, col - 1, 3 + rowOffset, 3 + colOffset))
                    {
                        for (int s = 0; s < shipSize; s++)
                        {
                            grid[row + s * vertical, col + s * horizontal] = 'S';
                        }
                        break;
                    }
                }
            }
        }
    }
    

    这里几乎没有什么条件,只有一件事。其他一切都是平庸的数学。

    • vertical随机数0或1,如果船是垂直的,则为1。
    • horizontal- 1(如果水平)。

    使用这种方法来确定船舶的方向,可以轻松地以数学方式计算其边界的坐标和单元的位置。

    好吧,有一些创建矩阵并打印它的实用方法:

    static char[,] CreateGrid(int size)
    {
        char[,] grid = new char[size, size];
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                grid[i, j] = '~';
            }
        }
        return grid;
    }
    
    static void Print(char[,] grid)
    {
        for (int i = 0; i < grid.GetLength(0); i++)
        {
            for (int j = 0; j < grid.GetLength(1); j++)
            {
                Console.Write($"{grid[i, j]} ");
            }
            Console.WriteLine();
        }
    }
    

    我们走吧:

    static void Main(string[] args)
    {
        char[,] grid = CreateGrid(10);
        PlaceShips(grid);
        Print(grid);
    }
    

    控制台输出:

    ~ ~ S S S ~ ~ S ~ ~
    ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
    S ~ ~ ~ ~ ~ S S ~ ~
    ~ ~ ~ ~ S ~ ~ ~ ~ ~
    S ~ ~ ~ S ~ S ~ ~ ~
    ~ ~ ~ ~ S ~ S ~ ~ S
    ~ S ~ ~ S ~ ~ ~ ~ ~
    ~ S ~ ~ ~ ~ ~ ~ ~ ~
    ~ S ~ ~ ~ ~ ~ S ~ ~
    ~ ~ ~ ~ ~ ~ ~ S ~ ~
    
    • 1

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5