Mastermind两行对比方法错误排查及C#代码优化咨询
Mastermind行对比问题修复与代码优化
问题根源
你的代码在统计wrongPosition时存在逻辑错误:未排除已被samePlace占用的目标行(_actualRowPawns)位置,导致重复匹配了已经正确对位的颜色。比如你给出的示例中,行2的位置2已经因samePlace被计数,但代码未标记该位置,导致行1的位置1的2错误匹配行2的位置2的2,最终wrongPosition多算1次。
修复与优化方案
正确逻辑步骤
Mastermind的行对比需遵循以下规则:
- 先统计同位置同颜色的数量(
samePlace),同时标记双方已匹配的位置。 - 对剩余未匹配的颜色,统计每个颜色在双方中的出现次数,取两者最小值相加,得到异位置同颜色的数量(
wrongPosition)。
优化后的代码
private void CompareRows() { if (_resaultPawns.Length != _actualRowPawns.Length) { Debug.LogError("Arrays have different length"); return; } // 提前提取所有颜色,避免重复调用组件接口,降低性能开销 Color[] resultColors = new Color[_resaultPawns.Length]; Color[] actualColors = new Color[_actualRowPawns.Length]; for (int i = 0; i < _resaultPawns.Length; i++) { resultColors[i] = _resaultPawns[i].GetComponent<MeshRenderer>().material.color; actualColors[i] = _actualRowPawns[i].GetComponent<MeshRenderer>().material.color; } int samePlace = 0; // 用HashSet存储已匹配位置,Contains查询效率远高于List HashSet<int> matchedResultIndices = new HashSet<int>(); HashSet<int> matchedActualIndices = new HashSet<int>(); // 统计同位置匹配 for (int i = 0; i < resultColors.Length; i++) { if (resultColors[i].Equals(actualColors[i])) { samePlace++; matchedResultIndices.Add(i); matchedActualIndices.Add(i); } } // 统计异位置匹配 int wrongPosition = 0; // 统计剩余颜色的出现频率 Dictionary<Color, int> resultColorCount = new Dictionary<Color, int>(); Dictionary<Color, int> actualColorCount = new Dictionary<Color, int>(); for (int i = 0; i < resultColors.Length; i++) { if (!matchedResultIndices.Contains(i)) { resultColorCount[resultColors[i]] = resultColorCount.TryGetValue(resultColors[i], out int count) ? count + 1 : 1; } } for (int i = 0; i < actualColors.Length; i++) { if (!matchedActualIndices.Contains(i)) { actualColorCount[actualColors[i]] = actualColorCount.TryGetValue(actualColors[i], out int count) ? count + 1 : 1; } } // 计算两种颜色频率的交集最小值之和 foreach (var color in resultColorCount.Keys) { if (actualColorCount.ContainsKey(color)) { wrongPosition += Math.Min(resultColorCount[color], actualColorCount[color]); } } // 可根据需求输出或返回结果 // Debug.Log($"samePlace: {samePlace}, wrongPosition: {wrongPosition}"); }
核心优化点
- 减少组件调用:提前将所有颜色提取到数组,避免循环中重复调用
GetComponent<MeshRenderer>().material.color,降低性能消耗。 - 高效集合查询:用
HashSet代替List存储已匹配位置,Contains操作时间复杂度从O(n)降至O(1),提升循环效率。 - 逻辑正确性:通过统计剩余颜色频率计算
wrongPosition,彻底解决重复计数问题,符合Mastermind规则。 - 代码可读性:拆分逻辑步骤,每个阶段仅完成单一任务,便于维护与调试。
内容的提问来源于stack exchange,提问作者fer
相关产品推荐
相关产品推荐

