На второй неделе обучения по курсу 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;
}
Сыграем несколько раз, чтобы проверить правильность кода программы:
Что вы поняли, пока выполняли это задание?

