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
相关产品推荐
相关产品推荐

