I'm doing a CS50 problem set where I have to make a game of scrabble basically two people write a word and each letter in the word gives certain amount of points. E.g. A gives one point and Z gives 10
I was trying to make the storing system using a switch statement and a couple of char arrays containing each letter and how many points it gives. E.g. array One stores letters that give one point and Two two points and so on
but I figured out I can't put arrays in x position the (case x:)
so i tried a few things and got this.
Is there a way to make this more efficient or should I go back to switch statements or what?
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
//get the strings from the players and store them in a string data type
string p1 = get_string("Player 1: ");
string p2 = get_string("Player 2: ");
//make score data types for each player
int score1 = 0;
int score2 = 0;
char one[20] = {'a','A','e','E','i','I','l','L','n','N','o','O','r','R','s','S','t','T','u','U'};
char two[4] = {'d','D','g','G'};
char three[8] = {'b','B','c','C','m','M','p','P'};
char four[10] = {'f','F','h','H','v','V','w','W','y','Y'};
char five[2] = {'k','K'};
char eight[4] = {'j','J','x','X'};
char ten[4] = {'q','Q','z','Z'};
int str = strlen(p1);
for (int N = 0; N < str; N++)
{
if (p1[N] == one[0] || p1[N] == one[1] || p1[N] == one[2] || p1[N] == one[3] || p1[N] == one[4] || p1[N] == one[5] || p1[N] == one[6] || p1[N] == one[7] || p1[N] == one[8] || p1[N] == one[9] || p1[N] == one[10] || p1[N] == one[11] || p1[N] == one[12] || p1[N] == one[13] || p1[N] == one[14] || p1[N] == one[15] || p1[N] == one[16] || p1[N] == one[17] || p1[N] == one[18] || p1[N] == one[19])
{
score1++;
} else if (p1[N] == two[0] || p1[N] == two[1] || p1[N] == two[2] || p1[N] == two[3])
{
score1 += 2;
} else if (p1[N] == three[0] || p1[N] == three[1] || p1[N] == three[2] || p1[N] == three[3] || p1[N] == three[4] || p1[N] == three[5] || p1[N] == three[6] || p1[N] == three[7])
{
score1 += 3;
}
}
}
I think @TangentiallyPerpedicular is right to suggest a lookup table, but memory is cheap, so rather than make your array have 26 elements and do math to convert a character to an index, make it larger and do the lookups right on the ASCII value of each character.
Designated initializers make the initialization quite straightforward.
int main() {
int char_vals[256] = {
['A'] = 1, ['E'] = 1, ['I'] = 1,
['L'] = 1, ['N'] = 1, ['O'] = 1,
['R'] = 1, ['S'] = 1, ['T'] = 1,
['U'] = 1,
['D'] = 2, ['G'] = 2,
['B'] = 3, ['C'] = 3, ['M'] = 3,
['P'] = 3,
['F'] = 4, ['H'] = 4, ['V'] = 4,
['W'] = 4, ['Y'] = 4,
['K'] = 5,
['J'] = 8, ['X'] = 8,
['Q'] = 10, ['Z'] = 10
};
// ...
}
Alternatively when you want to check for membership in an array, you should be using a loop.
char one[20] = {'a', 'A', 'e', 'E', 'i', 'I', 'l', 'L', 'n', 'N', 'o', 'O', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U'};
for (size_t N = 0; N < str; N++)
int worth_one = 0;
for (size_t i = 0; i < sizeof(one); i++) {
if (str[N] == one[i]) {
worth_one = 1;
break;
}
}
if (worth_one) {
score1++;
continue;
}
// Repeat for two, three, four, etc.
}
Beware that such an approach has linear runtime complexity while the lookup table has constant runtime complexity.
In addition to multiple correct solutions using arrays, you can also use a switch statement if that is what you are expected to:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
int compute_score(const char *word) {
int score = 0;
for (size_t i = 0; word[i]; i++) {
unsigned char uc = word[i]; // always use unsigned char with ctype macros
switch (toupper(uc)) {
case ' ': // Accept space as wildcard. No points.
break;
case 'A':
case 'E':
case 'I':
case 'L':
case 'N':
case 'O':
case 'R':
case 'S':
case 'T':
case 'U':
score += 1;
break;
case 'D':
case 'G':
score += 2;
break;
case 'B':
case 'C':
case 'M':
case 'P':
score += 3;
break;
case 'F':
case 'H':
case 'V':
case 'W':
case 'Y':
score += 4;
break;
case 'K':
score += 5;
break;
case 'J':
case 'X':
score += 8;
break;
case 'Q':
case 'Z':
score += 10;
break;
default:
printf("not a letter: `%c`\n", uc);
return -1;
}
}
return score;
}
int main(void) {
//get the strings from the players and store them in a string data type
string p1 = get_string("Player 1: ");
string p2 = get_string("Player 2: ");
//compute the player scores
int score1 = compute_score(p1);
int score2 = compute_score(p2);
printf("Player 1 got %d points for '%s'\n", score1, p1);
printf("Player 2 got %d points for '%s'\n", score2, p2);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With