0

I am working on a problem that is asking to determine which word has a higher point value according to the Scrabble board game. My thought process is to:

  1. take user inputs (i.e. two words) in strings
  2. convert user inputs to lowercase
  3. call functions that calculate scores for each input
  4. Output which word has a higher point value

Here is what I have so far:

// Points assigned to each letter of the alphabet
int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};

int compute_score(string word);

int main(void)
{
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    //convert each word inputs to lowercase using 'tolower()' function
    for (int m=0; m<strlen(word1); m++)
    {
        word1[m]=tolower(word1[m]);
    }
    for (int n=0; n<strlen(word2); n++)
    {
        word2[n]=tolower(word2[n]);
    }
    // Score both words
    int score1 = compute_score(word1);
    int score2 = compute_score(word2);
    if (score1<score2)
    {
        printf("Player2 wins!");
        printf("\n");
    }
    if (score2<score1)
    {
        printf("Player1 wins!");
        printf("\n");
    }
    if (score1==score2)
    {
        printf("Tie!");
        printf("\n");
    }
    printf("this is the score for word 1: ""%i\n", score1);
    printf("this is the score for word 2: ""%i\n", score2);
}
int compute_score(string word) //uppercase letters are converted in the main();
{
    int wordScore=0;
    //the loop below converts each char in 'word' into int values according to ASCII. Then, it converts each int values mod 97
    for(int i=0; i<=strlen(word); i++)
    {
        word[i]=((int)word[i]);
        word[i]=word[i]%97;
        printf("each letter is now converted to this int value: ""%i\n",word[i]);
    }
    for(int j=0; j<=strlen(word); j++)
    {
        for (int k=0; k<26; k++)
        {
            if(word[j]==k)
            {
                word[j]=POINTS[k];
            }
        }  
    }
    for(int l=0; l<strlen(word); l++)
    {
        if(word[l]<33)//word[l]<33 since special characters will have values from 33~47;
        {
            wordScore+=word[l];
        }
    }
    return wordScore;
}

For some reason, some letters, such as b, do not get calculated correctly. What is the error? For the life of me, I can't figure out why any words with b calculate the character b as 2 points.

ksohan
  • 1,165
  • 2
  • 9
  • 23

1 Answers1

2

Your calculation word[i] = word[i] % 97 is quite bogus. This ignores the character encoding, and creates a value between 0 and 96 via modulo arithmetic. One of the weird things that will happen is the letter 'a' will prematurely terminate your string, because 'a' % 97 is zero. That means you cannot rely on strlen afterwards.

You should avoid modifying the string itself. It makes no sense to do so. It's quite simple to compute the score as follows:

int compute_score(string word)
{
    int wordScore = 0;
    for(int j = 0, len = strlen(word); j < len; j++)
    {
        if (isalpha(word[j])) {
           wordScore += POINTS[tolower(word[j]) - 'a'];
        } 
    }
    return wordScore;
}

This also rolls the lowercasing into the score calculation so there is no need to pre-convert your strings to lowercase.

Speaking of that, this is probably a good time to point out that you're using loops incorrectly. You keep using <= when iterating over a string length. That is incorrect, unless you're also wanting to process the string's NUL terminator.

Regarding using hard-coded integers for character values, please stop doing that. Use character literals instead (notice how I use the literal 'a' instead of 97 ). There's nothing clever about knowing the ASCII table and hardcoding integer constants -- all that does is make the code less portable and less readable. So please stop doing that and consider it a public service.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • Oops, I used <= in the loops because I was trying everything under the sun to fix what was wrong with the code. Didn't fix it back to <, that's my bad! Thank you for taking the time to explain. Also, could you elaborate on why the letter 'a' will prematurely terminate the string? Curious. Reading resources regarding it would be appreciated. Also also, what exactly is "-'a'" in "POINTS[tolower(word[j])-'a'] doing? – raspberry_flapper Apr 05 '22 at 17:40
  • As I wrote in the answer, the way you had it you were taking a character modulo 97. Because the value of `'a'` is 97 (in ASCII, at least) then it will result in the value 0. But by convention in C, the character value 0 is used as a terminator so that the string functions know where the string stops. That's what `strlen` looks for. Regarding `POINTS[tolower(word[j])-'a']` this calculates the lowercase value of `word[j]` then it subtracts 'a' which turns your lowercased letter into a value from 0 to 25. That's then used to index the POINTS array. We first test `isalpha` to ensure it's a letter. – paddy Apr 05 '22 at 23:16