cif-statementcs50scrabble

cs50 scabble problem not working. can anyone help plz?


I'm doing the cs50 scrabble problems from problem set 2 and my 'point' function doesn't add points correctly. The function keeps ignoring all the 'if' and 'else if' statements even when there are char that corresponds with that 'if' statement.

#include <cs50.h>
#include <stdio.h>
#include <string.h>

int score1 = 0;
int score2 = 0;
int point(string ply);
void compare(int pl1, int pl2);

int main(void)
{
    string ply1 = get_string("Player 1: ");
    string ply2 = get_string("Player 2: ");

    score1 = point(ply1);
    score2 = point(ply2);
    compare(score1, score2);
}



//calculate point
int point(string ply)
{
    int score = 0;

    for(int i = 0; i < strlen(ply); i++)
    {
        if(ply[i] == ('a'|'e'|'i'|'l'|'n'|'o'|'r'|'s'|'t'|'u'))
        {
            score += 1;
            printf("yes\n");
        }
        else if(ply[i] == ('d'|'g'))
        {
            score += 2;
        }
        else if(ply[i] == ('b'|'c'|'m'|'p'))
        {
            score += 3;
        }
        else if(ply[i] == ('f'|'h'|'v'|'w'|'y'))
        {
            score += 4;
        }
        else if(ply[i] == 'k')
        {
            score +=5;
        }
        else if(ply[i] == ('j'|'x'))
        {
            score += 8;
        }
        else
        (
            score += 10
        );
    }
    return score;
}

//compare score
void compare(int pl1, int pl2)
{
    if(pl1 < pl2)
    {
        printf("Player 2 won!\n");
    }
    else if(pl1 > pl2)
    {
        printf("player 1 won!\n");
    }
    else
    {
        printf("tie\n");
    }
}

I run this in the cs50 debugger and when it came to the if function, it doesn't add anything to the score but instead just skips over.


Solution

  • The conditions you have aren't doing what you think they're doing.

    First, as a reminder, char literals like 'a' are in fact just a fancy way of writing numbers - they are interpreted as their ASCII values. | is the bitwsie or operator. So when you have a statement like ply[i] == ('a'|'e'|'i'|'l'|'n'|'o'|'r'|'s'|'t'|'u'), the right side of the equality is calculated (it's equal to 127), and then ply[i] is compared to it.

    The right way, syntactically, to write the condition you intended to write is as a series of logical or conditions:

    if (ply[i] == 'a' ||
        ply[i] == 'e' ||
        ply[i] == 'i' || 
        ply[i] == 'l' ||
        ply[i] == 'n' ||
        ply[i] == 'o' ||
        ply[i] == 'r' ||
        ply[i] == 's' ||
        ply[i] == 't' ||
        ply[i] == 'u') {
    score += 1;
    }
    // else if etc...
    

    But that's very cumbersome. A neater solution could be to implement a poor-man's hashmap.
    Each character from 'a' to 'z' is worth a specific amount of points. And since char literals are just fancy numbers, if you subtract 'a' from each char, you'd get numbers from 0 to 25, which can be used as array indexes.
    You can create an array of point values:

    const 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 points (char* str) {
        int score = 0;
        for (int i = 0; i < strlen(str); ++i) {
            score += POINTS[str[i] - 'a'];
        }
        return score;
    }