Нужна помощь в возврате очков на основе проверки буквы строки - PullRequest
0 голосов
/ 07 июня 2019

Я пытаюсь проверить, имеет ли строка букву на основе данного теста. Однако буква a имеет исключение, каждая буква a будет считаться как половина значения. Например, буква a стоит 300, но мы хотим разделить на 2, а каждая буква будет стоить 150 баллов.

UnitTest:

[TestCase("software", 'w', 250, 250)]
[TestCase("craftmanship", 'a', 300, 300)]
public void WheelofFortune(string secretWord, char letterGuess, int pointValue, int expected)
    {
        var actual = warmups.WheelofFortune(secretWord, letterGuess, pointValue);
        Assert.AreEqual(expected, actual);
    }

Единица измерения:

//Given a target word, a letter guess by a customer, and a point value. 
//Return the number of points earned.

    public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
    {
        int sum = 0;
        int pointValue2 = (pointValue / 2);

        for (int i = 0; i < secretWord.Length; i++)
        {
            if (secretWord[i] == letterGuess)
                sum += pointValue;

            if (secretWord[i] == letterGuess && letterGuess == 'a')
                sum += pointValue2;

            if (secretWord[i] == secretWord.Length - 1)
                return sum;
        }
        return sum;            
    }

Проблема в мастерстве: Сообщение: Ожидаемое: 300 Но было: 900

Почему я получаю 900, а не 300?

Ответы [ 3 ]

3 голосов
/ 07 июня 2019

Бен и Мринал показали вам непосредственную проблему в коде.Я собираюсь сосредоточиться больше на структуре кода.

Из вашего вопроса звучит так, как будто вы хотите что-то вроде этого:

С учетом слова, символа догадки иоценка, умножьте оценку на количество совпадающих символов.Если угадающий символ равен 'a', тогда он набирает половину.

В этом случае код может быть значительно упрощен до:

public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
{
    int count = secretWord.Count(letter => letter == letterGuess);
    int sum = pointValue * count;
    if (letterGuess == 'a')
        sum /= 2;
    return sum;
}

Это дает значения, которые вы тестируетедля, абстрагирует цикл и читает намного больше как описание.Это также упрощает логику до такой степени, что вы с меньшей вероятностью пропустите что-то вроде двойного совпадения.

Не уверен, почему ваш код включает в себя тест на символ, равный длине строки меньше единицы,так как это не имеет отношения к вопросу.Рад исправить, если это необходимо.

1 голос
/ 07 июня 2019

Это происходит из-за того, что ваша логика неверна при простой отладке, и предлагает, когда вы найдете букву a, тогда обе логики выполняются и, таким образом, вместо 150 за итерацию ваше значение становится 450 и, следовательно, 450 * 2 = 900 :

if (secretWord[i] == letterGuess)
                sum += pointValue;

 if (secretWord[i] == letterGuess && letterGuess == 'a')
                sum += pointValue2;

Исправление 1 с использованием распределительного шкафа:

public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
{
    int sum = 0;

    for (int i = 0; i < secretWord.Length; i++)
    {
        switch(secretWord[i])
        {
            case 'a':
                sum += pointValue/2;
            break;
            default:
                if (secretWord[i] == letterGuess)
                  sum += pointValue;
            break;          
        }
    }
    return sum;
}

Исправление 2: улучшенный дизайн с использованием словаря (просто добавьте еще один ключ в словарь, и он автоматически вычислит согласно новой логике)

public static Dictionary<char,double> sampleData = new Dictionary<char, double>
{
    ['a'] = 0.5
};

public int WheelofFortune(string secretWord, char letterGuess, int pointValue)
{
    int sum = 0;

    for (int i = 0; i < secretWord.Length; i++)
        if(sampleData.ContainsKey(secretWord[i]))
            sum += (int)(pointValue * sampleData[letterGuess]);

    return sum;
}
0 голосов
/ 07 июня 2019

Вы выполняете оба условия if, поэтому:

if (secretWord[i] == letterGuess)
            sum += pointValue;

Вы дважды сопоставляете a, поэтому вы добавляете к сумме 2x300 = 600.Тогда

if (secretWord[i] == letterGuess && letterGuess == 'a')
            sum += pointValue2;

Это также совпадает, поэтому вы добавляете 2 * 150 = 300 к сумме.600 + 300 = 900.

Вам нужно либо использовать if else, либо оператор case.Так что-то вроде:

    for (int i = 0; i < secretWord.Length; i++)
    {
        if (secretWord[i] == letterGuess && letterGuess == 'a')
        {
            sum += pointValue2;
        }
        else if (secretWord[i] == letterGuess)
        {
            sum += pointValue;
        }
        //if (secretWord[i] == secretWord.Length - 1)
        //{
        //    return sum;
        //}

    }

Таким образом, как только одна фраза if удовлетворяется, она игнорирует остальные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...