Я новичок в C и программировании в целом, в настоящее время прохожу CS50 и изучаю C. У меня запущена игра в скраббл, которая принимает входные данные игрока 1 и игрока 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};
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 2 wins!...");
}
else if (score1 == score2)
{
printf("Tie!");
}
else
{
printf("Player 1 wins!...");
}
}
int compute_score(string word)
{
// TODO: Compute and return score for string
char letters[26];
int asciiletter = 97;
int score = 0;
int i = 0;
int k = 0;
for (i = 0; i < 26; i++)
{
letters[i] = asciiletter + i;
}
//Get the chars in the string of word and compare to all letters in alphabet letters[26]
for(int j= 0, n = strlen(word); j < n; j++)
{
//if entered values uppercase, convert to lower as points are the same for either case
word[j] = tolower(word[j]);
for(k = 0; k < 26; k++ )
{
if (word[j] == letters[k])
{
score = score + points[k];
}
}
}
return score;
}
1 ответ
и добро пожаловать в программирование на C! Также в Code Review.
Стиль
В вашем коде есть пара «стилевых» проблем. Самым очевидным является то, что ваш отступ непоследователен. Я не знаю, связано ли это с тем, что это было вставлено в браузер, или это выглядит так в вашем коде. Но computescore
нужно очистить.
Далее следует вопрос «понятности». У вас есть этот массив:
// 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};
Быстро, сколько очков за букву «S»?
Этот массив может быть правильным, но он непонятен и не подлежит изменению. Было бы гораздо лучше предоставить какой-либо другой механизм для инициализации массива или инициализации какой-либо другой структуры, чтобы следующий специалист, поддерживающий код, имел шанс увидеть ошибки и / или иметь возможность вносить изменения.
Например:
Вы можете создать перечисление со значениями точек для каждой буквы, а затем инициализировать массив, используя метки перечисления:
enum { A_POINTS = 1, B_POINTS = 3, C_POINTS = 3, : }; int points[] = { A_POINTS, B_POINTS, C_POINTS, : };
Вы могли бы создать умный назначенный инициализатор макрос, который проясняет ситуацию:
#define TILE(CH) [CH - 'a'] int points[] = { TILE('a') = 1, TILE('b') = 3, TILE('c') = 3, : };
Вы можете создать строку и проанализировать ее во время выполнения, например:
const char * points = "A = 1; B = 3; C = 3; ...;" "N = ..." ;
Имейте в виду: суть этого чисто чтобы упростить понимание сопоставления букв и точек. В идеале вы должны сделать его достаточно простым, чтобы понять, что кто-то может взглянуть на код и обнаружить ошибку, прежде чем вы скомпилируете его и отправитесь на тестирование.
Магия
Ваша функция подсчета очков просматривает список символов, чтобы получить индекс конкретного символа. Никогда не делай этого! Ты знать индекс, он просто спрятан за тонким слоем математики.
В ASCII прописные и строчные буквы (а также цифры) представляют собой серии значений кодирования, назначаемых в последовательном возрастающем порядке. Как только вы узнаете, где начинается бег, вы можете добраться до любого другого персонажа простым добавлением. Точно так же вы можете изменить этот трюк, используя простое вычитание:
score_index = ch - 'a';
score += points[score_index];
Спасибо за ваши Коментарии. Мне нужно еще раз вернуться к множеству замечательных моментов. Мне казалось, что я слишком усложняю то, как я имел дело с символами ascii, и ваши комментарии помогают этому.
— Js94