C#控制台版Battleship舰船位置校验触发数组越界问题
Battleship游戏输入校验越界问题修复
异常触发根因
- 数组访问无前置边界校验:代码获取第二个输入字母在
validInputs数组的索引后,直接计算validInputIndex ±4就访问对应数组元素,未判断运算后的下标是否落在0 ~ validInputs.Length -1的合法区间内。 - 逻辑表达式无法规避访问越界:C#的
||逻辑或虽然有短路特性,但只要任意一个分支的数组访问涉及非法下标,就会直接抛出异常,不会等分支判断走完。
典型触发场景:输入
E3A3时,第二个校验字母为'A',在validInputs中的索引为0,此时计算validInputIndex -4得到-4,属于非法下标,直接触发越界;而正向输入A3E3时,第二个校验字母为'E',索引为4,4-4=0、4+4=8均为合法下标,因此能正常走完校验逻辑。
最小侵入修复方案
在访问数组元素前,先对运算后的下标做合法性判断,只有下标在有效区间内时才执行数组访问,修改后的核心代码如下:
public static char[] validInputs = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '1', '2', '3', '4', '5', '6', '7', '8', '9', 't' }; if (placementInput[1] - placementInput[3] == 0) { char validInputCheck = placementInput[2]; int validInputIndex = Array.IndexOf(validInputs, validInputCheck); // 未匹配到合法字符时直接跳过 if (validInputIndex == -1) { continue; } // 先校验-4的下标合法性,再做匹配判断 if (validInputIndex - 4 >= 0 && placementInput[0] == validInputs[validInputIndex - 4]) { validationCounter++; break; } // 先校验+4的下标合法性,再做匹配判断 if (validInputIndex + 4 < validInputs.Length && placementInput[0] == validInputs[validInputIndex + 4]) { validationCounter++; break; } }
长期优化方案
- 拆分混合的合法值数组:当前
validInputs将列字母(A-J)和行数字(1-9)混在同一个数组中,极易出现校验逻辑串用的问题。建议拆分独立的列字母校验数组、行数字校验数组,从根源避免索引计算混乱。 - 改用索引差值判断舰船长度:不需要通过数组反查对应位置的字符,直接计算两个列字母的索引绝对差值,只要差值等于舰船长度-1(比如5格巡洋舰对应差值为4)即满足长度要求,从逻辑上完全规避数组越界风险。
优化后的核心代码示例:
// 拆分独立的校验数组 public static char[] validColumnLetters = {'A','B','C','D','E','F','G','H','I','J'}; public static char[] validRowNumbers = {'1','2','3','4','5','6','7','8','9'}; // 水平放置5格巡洋舰的校验逻辑 if (placementInput[1] == placementInput[3]) { int firstColIndex = Array.IndexOf(validColumnLetters, placementInput[0]); int secondColIndex = Array.IndexOf(validColumnLetters, placementInput[2]); // 两个列坐标合法,且索引差为4(对应5格长度) if (firstColIndex != -1 && secondColIndex != -1 && Math.Abs(firstColIndex - secondColIndex) == 4) { validationCounter++; break; } }
内容的提问来源于stack exchange,提问作者Deanjvande
相关产品推荐
相关产品推荐

