我的 CS50 第 2 周的拼字游戏解决方案与符号作斗争。想不通为什么

问题描述 投票:0回答:3

所以我为 CS50 第 2 周的实验室的拼字游戏问题编写了这段代码。其要点是,我们需要编写代码来计算两个玩家给出的两个单词的分数,然后根据分配给两个单词中每个字母的分数来宣布获胜者。分配给每个字母的点在数组“POINTS”中给出。

如果您需要更多信息,这里是问题的链接:https://cs50.harvard.edu/x/2023/labs/2/

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

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

string convert_upper(string word);
int compute_score(string upper_word);
void print_winner(int score1, int score2);

int main(void)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    // Convert to uppercase
    string upper_word1 = convert_upper(word1);
    string upper_word2 = convert_upper(word2);

    // Calculate scores
    int score1 = compute_score(upper_word1);
    int score2 = compute_score(upper_word2);

    // TODO: Print the winner
    print_winner(score1, score2);
}

string convert_upper(string word)
{
    // Convert to uppercase
    int length = strlen(word);
    for (int i = 0; i < length; i++)
    {
        word[i] = toupper(word[i]);
    }
    printf("%s\n", word);
    return word;
}

int compute_score(string upper_word)
{
    // Add score for each letter
    int score = 0;
    for (int i = 0; i < strlen(upper_word); i++)
    {
        score = score + POINTS[upper_word[i]-65];
    }
    return score;
}

void print_winner(int score1, int score2)
{
    // Print result based on the scores
    if (score1 > score2)
    {
        printf("Player 1 wins \n");
    }
    else if (score2 > score1)
    {
        printf("Player 2 wins \n");
    }
    else
    {
        printf("Tie! \n");
    }
}

如果我只使用普通单词,代码就可以正常工作。但一旦我使用像

question?
这样结尾带有符号的单词,分数就会变得太高,并且无法按预期工作。我的代码处理符号的方式似乎存在一些问题。我知道
isupper()
是一种更好的实现方式,不会出现任何错误,但我想知道这里到底出了什么问题。

c cs50 scrabble
3个回答
2
投票

compute_score
中,您可以通过
POINTS[upper_word[i] - 65];
访问给定图块的分数。 如果偏移量
i
处的字符不是大写字母,则计算为
upper_word[i] - 65
的索引超出了数组
POINTS
的范围,因此访问此条目具有未定义的行为。请注意,您假设大写字母在字符集中是连续的,并且
A
被编码为
65
,这是 ASCII 特有的。该程序将在使用 EBCDIC 的目标上失败(但您不太可能找到一个)。

您应该拒绝不完全由字母组成的单词,可能还有一些通配符,例如

*
 
作为占位符。

这是修改后的版本:

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

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

string convert_upper(string word);
int compute_score(string upper_word);
void print_winner(int score1, int score2);

int main(void)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    // Convert to uppercase
    string upper_word1 = convert_upper(word1);
    string upper_word2 = convert_upper(word2);

    // Calculate scores
    int score1 = compute_score(upper_word1);
    int score2 = compute_score(upper_word2);

    // TODO: Print the winner
    print_winner(score1, score2);
}

string convert_upper(string word)
{
    // Convert to uppercase
    int length = strlen(word);
    for (int i = 0; i < length; i++) {
        unsigned char cc = word[i];
        word[i] = toupper(cc);
    }
    printf("%s\n", word);
    return word;
}

int compute_score(string upper_word)
{
    // Add score for each letter
    int length = strlen(word);
    int score = 0;
    for (int i = 0; i < length; i++) {
        unsigned char cc = upper_word[i];
        if (!isupper(cc)) {
            if (cc != ' ' && cc != '*') {
                printf("invalid word: %s\n", upper_word);
                return 0;
            }
        } else {
            score = score + POINTS[cc - 'A'];
        }
    }
    return score;
}

void print_winner(int score1, int score2)
{
    // Print result based on the scores
    if (score1 > score2) {
        printf("Player 1 wins \n");
    } else
    if (score2 > score1) {
        printf("Player 2 wins \n");
    } else {
        printf("Tie! \n");
    }
}

0
投票
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int calculateTotalScore(string value);
string convertToUpperCase(string value);

int Points[26] = {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 main(void)
{
    string player1 = get_string("Player 1: ");
    string player2 = get_string("Player 2: ");

    string upperCasePlayer1 = convertToUpperCase(player1);

    string upperCasePlayer2 = convertToUpperCase(player2);

    int player1Score = calculateTotalScore(upperCasePlayer1);
    int player2Score = calculateTotalScore(upperCasePlayer2);

    if (player1Score > player2Score)
    {
        printf("Player 1 wins!\n");
    }

    else if (player2Score > player1Score)
    {
        printf("Player 2 wins!\n");
    }
    else
    {
        printf("Tie!\n");
    }
}

int calculateTotalScore(string value)
{
    int score = 0;
    for (int i = 0, length = strlen(value); i < length; i++)
    {
        if (value[i] >= 'A' && value[i] <= 'Z')
        {

            score = score + Points[value[i] - 'A'];
        }
    }
    return score;
}

string convertToUpperCase(string value)
{
    for (int i = 0, length = strlen(value); i < length; i++)
    {

        if (value[i] >= 'a' && value[i] <= 'z')
        {

            value[i] = (value[i] - 32);
        }
    }
    return value;
}

-1
投票
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>

// 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)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    // Score both words
    int score1 = compute_score(word1);
    int score2 = compute_score(word2);

    // TODO: Print the winner
    if(score1>score2)
    printf("Player 1 wins!\n");
    else if (score2>score1)
    printf("Player 2 wins\n");
    else printf("Tie!\n");
}

int compute_score(string word)
{
    // TODO: Compute and return score for string
    int sum=0;
    // loop to iterate across string
    for(int i=0;i<strlen(word);i++)
    {
        //reject all the characters that come before letters in ascii chart
        //make them 0 so that they dont add up the score and return garbage value
        if(word[i]>=1 &&word[i]<=64)
        {
            word[i]=0;
        }
        //convert all to uppercase so we dont have to check twice
        word[i]=toupper(word[i]);
        int a=word[i]-'A';
        // counter
        sum=sum+POINTS[a];

    }
     return sum;

}

// anant 代码

© www.soinside.com 2019 - 2024. All rights reserved.