如何修复单词搜索谜题矩阵生成代码中的无限循环问题?
修复单词搜索谜题的无限循环问题
以下是原代码的核心问题及修复方案:
核心问题分析
- 边界判断错误:原代码中
I > 0和J > 0的限制会排除第0行/列的合法位置,导致单词无法放在矩阵边缘,同时可能误判位置越界。 - 字符处理不完整:循环条件
i < s.Length-1会漏掉单词的最后一个字符,导致单词放置不完整。 - 矩阵赋值错误:
MatriceChars[placeJ, placeJ]错误地重复使用列索引,应该使用行+列的正确索引。 - 初始位置未处理:检查阶段判断了初始位置,但放置阶段没有给初始位置赋值标记和字符。
- 无重试次数限制:当单词无法找到合法位置时,
while(placed == false)会无限循环。
修复后的代码
static void PlaceWords(List<string> words) { Random rn = new Random(); foreach (string p in words) { string s = p.Trim().ToUpper(); bool placed = false; int retryCount = 0; const int maxRetries = 1000; // 限制重试次数,避免无限循环 while (!placed && retryCount < maxRetries) { retryCount++; int nRow = rn.Next(0, 10); int nCol = rn.Next(0, 10); int nDirX = 0; int nDirY = 0; // 随机生成方向(上下左右及四个对角线) while (nDirX == 0 && nDirY == 0) { nDirX = rn.Next(3) - 1; nDirY = rn.Next(3) - 1; } placed = PlaceWord(s, nRow, nCol, nDirX, nDirY); } if (!placed) { // 可选:输出警告,提示单词无法放置 Console.WriteLine($"无法放置单词:{s}"); } } } static bool PlaceWord(string s, int nRow, int nCol, int nDirX, int nDirY) { int length = s.Length; // 先检查整个单词的路径是否在矩阵范围内且未被占用 int currentRow = nRow; int currentCol = nCol; for (int i = 0; i < length; i++) { // 正确的边界判断:索引0-9都是合法的 if (currentRow < 0 || currentRow >= 10 || currentCol < 0 || currentCol >= 10) { return false; } // 如果位置已被占用,直接返回false if (MatriceIndice[currentRow, currentCol] != 0) { return false; } currentRow += nDirX; currentCol += nDirY; } // 路径合法,开始放置单词 currentRow = nRow; currentCol = nCol; for (int i = 0; i < length; i++) { MatriceIndice[currentRow, currentCol] = 1; MatriceChars[currentRow, currentCol] = s[i]; // 正确的行+列索引 currentRow += nDirX; currentCol += nDirY; } return true; }
关键修复点说明
- 修正边界判断:使用
currentRow >=0 && currentRow <10替代原错误判断,确保所有合法索引都被允许。 - 完整处理所有字符:循环条件改为
i < length,确保单词的每个字符都被处理。 - 修复矩阵赋值:将
MatriceChars[placeJ, placeJ]改为MatriceChars[currentRow, currentCol],使用正确的行列索引。 - 处理初始位置:在放置阶段先处理初始位置的标记和字符,再遍历后续位置。
- 添加重试次数限制:设置
maxRetries,当超过重试次数后退出循环,避免无限等待。
内容的提问来源于stack exchange,提问作者nai hamdan
相关产品推荐
相关产品推荐

