You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#战舰类终端游戏:如何将用户输入坐标字符串转为对应Box对象?

解决C#中坐标字符串到Box对象的映射问题

嘿,我懂你现在要解决的问题——把用户输入的e4这类坐标字符串,对应到你一个个创建的Box实例上对吧?说实话,你现在把每个Box都单独命名成a1、a2...这种方式,后续维护和映射会特别麻烦,我给你推荐两种更优雅的实现思路,从存储到输入解析一步搞定:

方法1:使用Dictionary<string, Box>存储网格(最直观)

用字典来把坐标字符串(比如"a1")直接作为键,对应的值就是你的Box实例,这样解析用户输入时直接通过键取值,非常方便。

代码示例:

// 先定义你的Box类
public class Box
{
    public bool hasShip { get; set; }
    // 可以按需添加其他属性,比如是否被击中过等
}

// 在游戏逻辑类里初始化字典网格
private Dictionary<string, Box> _gameGrid = new Dictionary<string, Box>();

// 初始化25个Box实例并填充到字典
public void InitializeGrid()
{
    // 遍历a-e行,1-5列
    for (char rowChar = 'a'; rowChar <= 'e'; rowChar++)
    {
        for (int colNum = 1; colNum <= 5; colNum++)
        {
            string coordinate = $"{rowChar}{colNum}";
            _gameGrid[coordinate] = new Box();
            // 这里可以随机设置战舰位置,比如:
            // _gameGrid[coordinate].hasShip = new Random().Next(2) == 1;
        }
    }
}

// 处理用户输入的核心方法
public void HandleUserInput(string userInput)
{
    // 统一转小写,避免大小写输入问题
    string normalizedInput = userInput.Trim().ToLower();

    if (_gameGrid.TryGetValue(normalizedInput, out Box targetBox))
    {
        if (targetBox.hasShip)
        {
            targetBox.hasShip = false;
            Console.WriteLine("Ship destroyed");
        }
        else
        {
            Console.WriteLine("Missed! No ship at this coordinate.");
        }
    }
    else
    {
        Console.WriteLine("Invalid coordinate! Please enter something like 'e2'.");
    }
}

方法2:使用二维数组(更贴合网格结构)

因为你的网格是5x5的,字母对应行(a=0、b=1...e=4),数字对应列(1=0、2=1...5=4),用二维数组存储会更符合网格的逻辑结构。

代码示例:

public class Box
{
    public bool hasShip { get; set; }
}

private Box[,] _gameGrid = new Box[5, 5];

public void InitializeGrid()
{
    for (int row = 0; row < 5; row++)
    {
        for (int col = 0; col < 5; col++)
        {
            _gameGrid[row, col] = new Box();
            // 随机放置战舰
            // _gameGrid[row, col].hasShip = new Random().Next(2) == 1;
        }
    }
}

public void HandleUserInput(string userInput)
{
    if (string.IsNullOrWhiteSpace(userInput) || userInput.Length < 2)
    {
        Console.WriteLine("Invalid coordinate! Please enter something like 'e2'.");
        return;
    }

    // 解析行:第一个字符转成数组索引
    char rowChar = char.ToLower(userInput[0]);
    if (rowChar < 'a' || rowChar > 'e')
    {
        Console.WriteLine("Invalid row! Please use letters a-e.");
        return;
    }
    int rowIndex = rowChar - 'a'; // 'a' -> 0, 'b' ->1 ...

    // 解析列:从第二个字符开始的数字转成数组索引
    if (!int.TryParse(userInput.Substring(1), out int colNumber) || colNumber < 1 || colNumber > 5)
    {
        Console.WriteLine("Invalid column! Please use numbers 1-5.");
        return;
    }
    int colIndex = colNumber - 1; // 转成0-based索引

    Box targetBox = _gameGrid[rowIndex, colIndex];
    if (targetBox.hasShip)
    {
        targetBox.hasShip = false;
        Console.WriteLine("Ship destroyed");
    }
    else
    {
        Console.WriteLine("Missed! No ship at this coordinate.");
    }
}

如果非要保留单独命名的Box实例(不推荐)

如果你因为某些原因必须保留a1、a2...这些单独的变量,那只能手动把它们映射到字典里,但这种方式非常繁琐,后续扩展网格会很痛苦:

// 假设你已经创建了a1到e5的Box实例
Dictionary<string, Box> _gridMap = new Dictionary<string, Box>
{
    {"a1", a1}, {"a2", a2}, {"a3", a3}, {"a4", a4}, {"a5", a5},
    {"b1", b1}, {"b2", b2}, {"b3", b3}, {"b4", b4}, {"b5", b5},
    // ... 手动添加剩下的15个变量
};

// 之后的输入处理逻辑和方法1一致,用_gridMap.TryGetValue即可

总的来说,推荐用字典或者二维数组的方式,代码更简洁、易维护,也更容易扩展网格大小。

内容的提问来源于stack exchange,提问作者Emp1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:37:56