You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
}
}
}

问题分析与修复方案

新代码的核心问题

  1. 字符串转大写未生效:C#字符串是不可变类型,Word.ToUpper()不会修改原字符串,必须重新赋值:Word = Word.ToUpper();
  2. 比较逻辑错误:循环中拿整个Word和数组元素比较,应该取当前循环的单个字符Word[i],同时要统一类型(数组是string,字符是char,可将数组改为char[],或把字符转成string)
  3. 索引越界风险:当单词长度超过某个分值数组的长度时(比如单词长度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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:34:57