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