Язык Си: игра «Эрудит» с другом


На второй неделе обучения по курсу Computer Science CS50 (Harvard) после выполнения всех индивидуальных заданий мы переходим к лабораторной работе по языку C, которую нужно выполнять в группе. Это будет интересная задача — написать код игры «Эрудит» (Scrabble.с). Суть задания: игроки придумывают слова, которые набирают разное количество очков в зависимости от букв в этом слове, при этом каждой букве приписывается разное количество очков от 1 до 10 и затем эти очки складываются (сумма очков букв дает общее количество очков в слове).

Для этой задачи используется следующая таблица соответствий букв и баллов:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
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

*Любой символ, кроме буквы, получает ноль баллов; большие и маленькие буквы оцениваются одинаковым количеством символов.

Игровой процесс: каждый игрок вводит слово, программа рассчитывает количество баллов по каждому слову и выигрывает тот, у кого сумма баллов получилась больше.

Результат игры: после того, как оба игрока введут по слову, компьютер выводит номер выигравшего игрока («Player x wins!«). Если получилась ничья, выводится сообщение «Tie!» (ничья).

Решение (Игроглаз)

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

int scrabble (char *input, int *AZ);
int main()
{
    int AZ[] = {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};
    char input[1000];
    int p1_score, p2_score;

    printf("Player 1: ");
    p1_score = scrabble (input, AZ);

    printf("Player 2: ");
    p2_score = scrabble (input, AZ);

    if (p1_score > p2_score)
        printf("Player 1 wins!");
    else if (p1_score < p2_score)
        printf("Player 2 wins!");
    else
        printf("Tie!");

    getchar();
    getchar();
    return 0;
}

int scrabble (char *input, int *AZ)
{
    int i, x;
    int score = 0;

    for (i = 0; ; i++)
    {
        scanf ("%c", &input[i]);
        if (input[i] == '\n')
            break;    // end input when user press 'Enter'

        // to count score - 1st make letter uppercase
        if (input[i] >= 'a' && input[i] <= 'z')
            input[i] = toupper(input[i]);

        // count only letters (ignore numbers, punctuation marks etc)
        if (input[i] >= 'A' && input[i] <= 'Z')
        {
            // get the ordinal index of letter
            x = (int)input[i] - 65;
            // get score from according index from score array
            score += AZ[x];
        }
    }
    return score;
}

Решение (Штукенция)

Долго я решала эту задачу, и для начала сделала программу без дополнительных функций, так как мне так проще было думать. В итоге первое решение получилось не слишком элегантным, длинным, но зато рабочим. 

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

int main(void)
{
    // Create array with the point values of each of 26 letters
    int values[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};

// Get users input of word:
    printf("Player 1: ");
    string player1 = get_string("");
    printf("Player 2: ");
    string player2 = get_string("");

// Turn characters from plaintxtx to ciphertext with function
    char c1; // character from user input player1
    int n1 = 0; // value of letter player1
    char c2; // character from user input player1
    int n2 = 0; // value of letter player1
    int sum1=0; // sum of letters values player 1
    int sum2=0; // sum of letters values player 2
    int textlen1=strlen(player1);
    int textlen2=strlen(player2);

// Count sum of values for letters from 1 player
    int c_asci_1=0; // ASCII number of player 1 char LETTER (A->65)
    int c_asci_2=0; // ASCII number of player 2 char LETTER (A->65)
    int num_letter_1=0; // index of player 1 letter in alphabet
    int num_letter_2=0; // index of player 2 letter in alphabet
    int i=0;
    int j=0;

    for (i=0; i<=(textlen1-1); i++) // sum char by char values of letters player 1
    {
        c1 = player1[i];
        int check_c_1 = isalpha(c1); // check if char is letter
        if (check_c_1!=0) // if char of player 1 is letter
        {
            int check_upper_1 = isupper(c1); // check if char is uppercase
            if (check_upper_1>0)
            {
                c_asci_1 = (c1); // convert char LETTER to int ASCII number (A->65)
                num_letter_1=(c_asci_1-65); // find numer of upper letter in alphabet (index)
            }
            else if (check_upper_1==0)
            {
                c_asci_1 = (c1);
                num_letter_1=(c_asci_1-97); // convert char LETTER to int ASCII number (a->97)
            }
        n1=values[num_letter_1]; // asign value for letter
        sum1+=n1;
        }
    }


    for (j=0; j<=(textlen2-1); j++) // sum char by char values of letters player 2
    {
        c2 = player2[j];
        int check_c_2 = isalpha(c2); // check if char is letter
        if (check_c_2!=0) // if char of player 2 is letter
        {
            int check_upper_2 = isupper(c2); // check if char is uppercase
            if (check_upper_2>0)
            {
                c_asci_2 = (c2); // convert char LETTER to int ASCII number (A->65)
                num_letter_2=(c_asci_2-65); // find numer of upper letter in alphabet (index)
            }
            else if (check_upper_2==0)
            {
                c_asci_2 = (c2);
                num_letter_2=(c_asci_2-97); // convert char LETTER to int ASCII number (a->97)
            }
        n2=values[num_letter_2]; // asign value for letter
        sum2+=n2;
        }
    }

    if (sum1>sum2)
        {
            printf("Player 1 wins!\n");
        }
        else if (sum1<sum2)
        {
            printf("Player 2 wins!\n");
        }
        else if (sum1==sum2)
        {
            printf("Tie!\n");
        }
    return 0;
}

Далее я решила реализовать этот код более компактно при помощи функции compute_score(), как требовалось в задании. В итоге код получился в несколько раз короче, видимо в этом и есть главная польза функций. 

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

int compute_score(int c, int n, int values[]);

int main(void)
{
    // Create array with the point values of each of 26 letters
    int values[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};

// Get users input of word:
    printf("Player 1: ");
    string player1 = get_string("");
    printf("Player 2: ");
    string player2 = get_string("");

// Turn characters from plaintxtx to ciphertext with function
    char c; // character from user input
    int n = 0; // value of letter
    int sum1 = 0; // sum of letters values player 1
    int sum2 = 0; // sum of letters values player 2
    int textlen1 = strlen(player1);
    int textlen2 = strlen(player2);

    int i = 0;
    int n1 = 0;
    for (i = 0; i <= (textlen1 - 1); i++) // sum char by char values of letters player 1
    {
        c = player1[i];
        n1 = compute_score(c, n, values);
        sum1 += n1;
    }

    int j = 0;
    int n2 = 0;
    for (j = 0; j <= (textlen2 - 1); j++) // sum char by char values of letters player 2
    {
        c = player2[j];
        n2 = compute_score(c, n, values);
        sum2 += n2;
    }

    if (sum1 > sum2)
    {
        printf("Player 1 wins!\n");
    }
    else if (sum1 < sum2)
    {
        printf("Player 2 wins!\n");
    }
    else if (sum1 == sum2)
    {
        printf("Tie!\n");
    }
    return 0;
}

int compute_score(int c, int n, int values[])
{
// Count sum of values for letters from 1 player
    int c_asci = 0; // ASCII number of player 1 char LETTER (A->65)
    int num_letter = 0; // index of player 1 letter in alphabet

    int check_c = isalpha(c); // check if char is letter

    if (check_c != 0) // if char of player 1 is letter
    {
        int check_upper = isupper(c); // check if char is uppercase

        if (check_upper > 0)
        {
            c_asci = (c); // convert char LETTER to int ASCII number (A->65)
            num_letter = (c_asci - 65); // find numer of upper letter in alphabet (index)
        }

        else if (check_upper == 0)
        {
            c_asci = (c);
            num_letter = (c_asci - 97); // convert char LETTER to int ASCII number (a->97)
        }
        n = values[num_letter]; // asign value for letter
    }
    return n;
}

Сыграем несколько раз, чтобы проверить правильность кода программы:

Что вы поняли, пока выполняли это задание?


Запись опубликована в рубрике С (Си). Добавьте в закладки постоянную ссылку.

Добавить комментарий

🇬🇧 Attention! Comments with URLs/email are not allowed.
🇷🇺 Комментарии со ссылками/email удаляются автоматически.