C# Scrabble程序故障求助:单字母计分正常,整词输入报错
Scrabble单词计分程序问题修复建议
我曾尝试用自定义函数实现Scrabble计分程序,但没成功,于是重写了代码。现在单个字母输入能正常计算分数,但输入完整单词时会出错。请问该怎么修复这个问题,或是我是否应该重新采用函数实现方式?
新代码
string Word = ""; int score = 0; Console.WriteLine("Enter a word"); Word = Console.ReadLine(); Word.ToUpper(); string[] arrOneP = new string[] { "A", "O", "I", "U", "R", "S", "E", "T", "N", "L" }; string[] arrTwoP = new string[] { "D", "G" }; string[] arrThreeP = new string[] { "B", "C", "M", "P" }; string[] arrFourP = new string[] { "F", "H", "W", "Y", "V" }; string[] arrFiveP = new string[] { "K" }; string[] arrEightP = new string[] { "J", "X" }; string[] arrTenP = new string[] { "Q", "Z" }; for (int i = 0; i < Word.Length; i++) { if (Word == arrOneP[i]) { score = score + 1; } else if (Word == arrTwoP[i]) { score = score + 2; } else if(Word == arrThreeP[i]) { score = score + 3; } else if (Word == arrFourP[i]) { score = score + 4; } else if (Word == arrFiveP[i]) { score = score + 5; } else if (Word == arrEightP[i]) { score = score + 8; } else if (Word == arrTenP[i]) { score = score + 10; } } Console.WriteLine(score);
旧代码
namespace Scrabble { internal class Program { static void Main(string[] args) { string Word = ""; int score = 0; int WordValue = 0; Console.WriteLine("Enter a word"); Word = Console.ReadLine(); static int CalcVal(char letter) { string[] arrOneP = new string[] { "A", "O", "I", "U", "R", "S", "E", "T", "N", "L" }; string[] arrTwoP = new string[] { "D", "G" }; string[] arrThreeP = new string[] { "B", "C", "M", "P" }; string[] arrFourP = new string[] { "F", "H", "W", "Y", "V" }; string[] arrFiveP = new string[] { "K" }; string[] arrEightP = new string[] { "J", "X" }; string[] arrTenP = new string[] { "Q", "Z" }; for (int i = 0; i < arrOneP.Length; i++) { if (i == arrOneP.Length) { return 1; } } for (int i = 0; i < arrTwoP.Length; i++) { if (i == arrTwoP.Length) { return 2; } } for (int i = 0; i < arrThreeP.Length; i++) { if (i == arrThreeP.Length) { return 3; } } for (int i = 0; i < arrFourP.Length; i++) { if (i == arrFourP.Length) { return 4; } } for (int i = 0; i < arrFiveP.Length; i++) { if (i == arrFiveP.Length) { return 5; } } for (int i = 0; i < arrEightP.Length; i++) { if (i == arrEightP.Length) { return 8; } } for (int i = 0; i < arrTenP.Length; i++) { if (i == arrTenP.Length) { return 10; } } Console.WriteLine("Your score is {0}", CalcVal); } } }
问题分析与修复方案
新代码的核心问题
- 字符串转大写未生效:C#字符串是不可变类型,
Word.ToUpper()不会修改原字符串,必须重新赋值:Word = Word.ToUpper(); - 比较逻辑错误:循环中拿整个
Word和数组元素比较,应该取当前循环的单个字符Word[i],同时要统一类型(数组是string,字符是char,可将数组改为char[],或把字符转成string) - 索引越界风险:当单词长度超过某个分值数组的长度时(比如单词长度11,
arrOneP仅10个元素),arrOneP[i]会触发索引越界异常,因为循环变量i基于单词长度而非数组长度。
修复后的优化版代码
用Dictionary<char, int>存储字母与分值的对应关系,查找效率更高,代码更简洁:
string word = ""; int score = 0; Console.WriteLine("Enter a word"); word = Console.ReadLine()?.ToUpper() ?? ""; // 定义字母分值映射 var letterScores = new Dictionary<char, int> { {'A',1}, {'O',1}, {'I',1}, {'U',1}, {'R',1}, {'S',1}, {'E',1}, {'T',1}, {'N',1}, {'L',1}, {'D',2}, {'G',2}, {'B',3}, {'C',3}, {'M',3}, {'P',3}, {'F',4}, {'H',4}, {'W',4}, {'Y',4}, {'V',4}, {'K',5}, {'J',8}, {'X',8}, {'Q',10}, {'Z',10} }; foreach (char c in word) { if (letterScores.TryGetValue(c, out int value)) { score += value; } // 可选:处理非字母字符,比如忽略或提示 } Console.WriteLine(score);
是否应该采用函数实现?
非常推荐用函数封装计分逻辑,代码结构更清晰,方便复用和维护。比如把单个字母计分的逻辑抽成函数:
static int GetLetterScore(char letter) { letter = char.ToUpper(letter); return letter switch { 'A' or 'O' or 'I' or 'U' or 'R' or 'S' or 'E' or 'T' or 'N' or 'L' => 1, 'D' or 'G' => 2, 'B' or 'C' or 'M' or 'P' => 3, 'F' or 'H' or 'W' or 'Y' or 'V' => 4, 'K' => 5, 'J' or 'X' => 8, 'Q' or 'Z' => 10, _ => 0 // 非字母字符计0分 }; } // 在Main中调用: foreach (char c in word) { score += GetLetterScore(c); }
这种写法的可读性和可维护性远高于原版本,也避免了旧代码中循环逻辑的错误(旧代码的循环永远不会触发返回,因为i永远不会等于数组长度)。
内容的提问来源于stack exchange,提问作者Gene
相关产品推荐
相关产品推荐

