Scrabble

Aufgabe
So werden Wörter bewertet
- Jeder Buchstabe hat einen festen Punktwert, siehe Tabelle (Werte der englischen Ausgabe von Scrabble).
- Groß- und Kleinschreibung spielt keine Rolle:
czählt so viel wieC. - Zeichen, die keine Buchstaben sind (Satzzeichen, Ziffern, Leerzeichen), zählen 0 Punkte.
- Die Punktzahl eines Wortes ist die Summe der Punktwerte seiner Zeichen. Wer mehr Punkte hat, gewinnt.
| 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 |
Beispiel Code!:
| Zeichen | C | o | d | e | ! | Summe |
|---|---|---|---|---|---|---|
| Punkte | 3 | 1 | 2 | 1 | 0 | 7 |
Demo
Spezifikation
- Implementieren Sie Ihr Programm in C in einer Datei namens
scrabble.cin einem Ordner namensscrabble. - Ihr Programm fragt mit
get_stringzuerst mit der AufforderungPlayer 1:, dann mitPlayer 2:nach je einem Wort. - Es berechnet die Punktzahl beider Wörter nach den Regeln 1 bis 4 oben.
- Es gibt danach genau eine Zeile aus:
Player 1 wins!,Player 2 wins!oderTie!, jeweils mit Zeilenumbruch, und sonst nichts (keine Punktzahlen).
Ordner und Datei anlegen
Öffnen Sie VS CodeVisual Studio Code, der kostenlose Code-Editor von Microsoft, in dem Sie im Kurs programmieren. Glossar → entsprechend Ihrem Setup; eine einfache Installation von VS Code reicht nicht. Führen Sie im TerminalfensterFenster, in dem Sie dem Computer Befehle als Text eintippen statt zu klicken. In VS Code liegt es im unteren Bereich des Fensters. Glossar → cdWechselt das Verzeichnis: cd me geht in den Ordner me, cd .. eine Ebene nach oben, cd allein ins Homeverzeichnis. Glossar → aus; die EingabeaufforderungDas Zeichen am Anfang der Zeile im Terminal, etwa $ oder me/ $. Es zeigt, dass das Terminal auf Ihren nächsten Befehl wartet. Steht davor ein Ordnername wie me/, befinden Sie sich gerade in diesem Ordner. Glossar → zeigt dann nur $. Legen Sie nun Ordner und Datei an:
mkdir scrabble
cd scrabble
code scrabble.cDie Eingabeaufforderung zeigt jetzt scrabble/ $. Nach der Aufgabe kommen Sie mit cd ../ wieder eine Ebene nach oben.
Hilfestellung
Klicken Sie auf die folgenden Tipps, um einige Ratschläge zu erhalten. Versuchen Sie aber zunächst, selbst so weit wie möglich zu kommen.
Beginnen Sie mit Code, der kompilierbar ist
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
}Beachten Sie, dass in diesem Grundgerüst mehrere Header-Dateien eingebunden sind, die Ihnen Zugriff auf Funktionen geben, die Ihnen bei der Lösung dieses Problems helfen könnten.
Versuchen Sie das Problem in Pseudocode zu beschreiben
Wenn Sie unsicher sind, wie Sie das eigentliche Problem lösen können, unterteilen Sie es in kleinere Probleme, die Sie wahrscheinlich einfacher lösen können. Das Problem dieser Aufgabe besteht eigentlich nur aus einer Handvoll kleinerer Probleme:
- Die Aufforderung an den Benutzer zur Eingabe von zwei Wörtern.
- Das Berechnen der Punktzahl für jedes Wort.
- Das Ausgeben des Gewinners.
Fügen Sie diese kleineren Probleme nun in Form von Pseudocode als Kommentare ein, um sie dann nacheinander bearbeiten zu können:
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
// Prompt the user for two words
// Compute the score of each word
// Print the winner
}Wandeln Sie den Pseudocode in Code um
Überlegen Sie zunächst, wie Sie den Benutzer nach zwei Wörtern fragen könnten. Erinnern Sie sich, dass get_string, eine Funktion der CS50-Bibliothek, den Benutzer nach einer Zeichenkette fragt.
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
// Prompt the user for two words
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
// Compute the score of each word
// Print the winner
}Überlegen Sie nun, wie Sie die Punktzahl für jedes Wort berechnen können. Da für beide Wörter derselbe Bewertungsalgorithmus gilt, bietet sich eine gute Gelegenheit zur Abstraktion. Daher werden wir eine Funktion namens compute_score definieren, die einen string als Argument entgegennimmt, auf den innerhalb der Funktion über word zugegriffen werden kann. Die Punktzahl von word wird dann als int zurückgegeben. Wie immer gilt: Den Funktionsprototypen oberhalb der main-Funktion nicht vergessen!
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int compute_score(string word);
int main(void)
{
// Prompt the user for two words
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
// Compute the score of each word
int score1 = compute_score(word1);
int score2 = compute_score(word2);
// Print the winner
}
int compute_score(string word)
{
// Compute and return score for word
}Wenden wir uns nun der Implementierung von compute_score zu. Um die Punktzahl eines Wortes zu berechnen, müssen wir den Punktwert jedes Buchstabens im Wort kennen. Man kann Buchstaben und ihre Punktwerte mit einem Array verknüpfen. Stellen Sie sich ein Array mit 26 int vor, genannt POINTS, in dem die erste Zahl der Punktwert für ‘A’ ist, die zweite Zahl der Punktwert für ‘B’, und so weiter. Wenn Sie ein solches Array außerhalb aller Funktionen deklarieren und initialisieren, kann jede Funktion auf dieses Array zugreifen, einschließlich compute_score.
#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)
{
// Prompt the user for two words
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
// Compute the score of each word
int score1 = compute_score(word1);
int score2 = compute_score(word2);
// Print the winner
}
int compute_score(string word)
{
// Compute and return score for word
}Damit die Implementation von compute_score die Punktzahl des Wortes richtig berechnet, versuchen Sie zunächst, den Punktwert eines einzelnen Buchstabens in word zu finden.
- Erinnern Sie sich, dass Sie
s[n]schreiben können, um das Zeichen am n-ten Index einer Zeichenketteszu finden. So liefertword[0]zum Beispiel das erste Zeichen vonword. - Erinnern Sie sich nun daran, dass Computer Zeichen mit ASCII darstellen, einem Standard, der jedes Zeichen als eine Zahl repräsentiert.
- Erinnern Sie sich auch daran, dass der 0. Index von
POINTS,POINTS[0], Ihnen den Punktwert von ‘A’ liefert. Überlegen Sie, wie Sie die numerische Darstellung von ‘A’ in den Index seines Punktwerts umwandeln können. Und was ist dann mit ‘a’? Entweder behandeln Sie Groß- und Kleinbuchstaben getrennt, oder Sie wandeln jeden Buchstaben vorher mittoupperum. Für den ersten Weg sind vermutlich die Funktionenisupperundislowerrecht hilfreich. - Beachten Sie auch, dass Zeichen, die keine Buchstaben sind, mit null Punkten bewertet werden sollten. Zum Beispiel ist
!0 Punkte wert.
Wenn Sie den Wert von einem Zeichen in word richtig berechnen können, können Sie eine Schleife verwenden, um die Punkte für die restlichen Zeichen zu addieren.
Wenn Sie die obigen Hinweise selbst ausprobiert haben, vergleichen Sie Ihren Ansatz mit dem folgenden Code-Snippet (Achtung: Spoiler!).
#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)
{
// Prompt the user for two words
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
// Compute the score of each word
int score1 = compute_score(word1);
int score2 = compute_score(word2);
// Print the winner
}
int compute_score(string word)
{
// Keep track of score
int score = 0;
// Compute score for each character
for (int i = 0, len = strlen(word); i < len; i++)
{
if (isupper(word[i]))
{
score += POINTS[word[i] - 'A'];
}
else if (islower(word[i]))
{
score += POINTS[word[i] - 'a'];
}
}
return score;
}Beachten Sie, dass die Prüfung mit isupper und islower in den if-Bedingungen implizit auch prüft, ob es sich überhaupt um einen Buchstaben handelt. Ist ein Zeichen im Wort z.B. ein !, so wird keine der beiden if-Bedingungen als true ausgewertet und das Zeichen wird gewissermaßen einfach übersprungen, was einer Bewertung mit 0 Punkten gleichkommt. Das Weglassen der zweiten if-Bedingung – unter der naiven Annahme, dass jedes Zeichen, das nicht großgeschrieben ist, ein Kleinbuchstabe sein muss – würde also problematisch werden, sobald ein Wort z. B. ein ! enthält.
Fehlt nur noch der letzte Schritt des Pseudocodes: das Ausgeben des Gewinners. Wie bereits im vorherigen Code-Snippet verwendet, kann mit einer if-Bedingung geprüft werden, ob eine Bedingung wahr ist, und mit der zusätzlichen Verwendung von else if oder else können weitere (exklusive) Bedingungen geprüft werden.
if (/* Player 1 wins */)
{
// ...
}
else if (/* Player 2 wins */)
{
// ...
}
else
{
// ...
}Wenn Sie die obigen Schritte ausprobiert haben, können Sie sich das letzte Code-Snippet (oder besser gesagt die vollständige Lösung!) ansehen und Ihren Code vergleichen:
#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)
{
// Prompt the user for two words
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
// Compute the score of each word
int score1 = compute_score(word1);
int score2 = compute_score(word2);
// Print the winner
if (score1 > score2)
{
printf("Player 1 wins!\n");
}
else if (score1 < score2)
{
printf("Player 2 wins!\n");
}
else
{
printf("Tie!\n");
}
}
int compute_score(string word)
{
// Keep track of score
int score = 0;
// Compute score for each character
for (int i = 0, len = strlen(word); i < len; i++)
{
if (isupper(word[i]))
{
score += POINTS[word[i] - 'A'];
}
else if (islower(word[i]))
{
score += POINTS[word[i] - 'a'];
}
}
return score;
}Testen
KompilierenProgramm, das Quellcode in Maschinencode übersetzt; diesen Vorgang nennt man kompilieren. Jedes C-Programm muss kompiliert werden, bevor es laufen kann. Glossar → Sie Ihr Programm mit make scrabble und starten Sie es mit ./scrabble. Wenn Sie eine Fehlermeldung beim Kompilieren nicht verstehen, erklärt help50 make scrabble sie Ihnen. Das Programm sollte sich so verhalten:
$ ./scrabble
Player 1: Question?
Player 2: Question!
Tie!Weitere Testeingaben mit den Punktzahlen, die Ihr Programm berechnen sollte:
| Player 1 | Player 2 | Punkte | Ausgabe |
|---|---|---|---|
Question? | Question! | 17 : 17 | Tie! |
red | wheelbarrow | 4 : 22 | Player 2 wins! |
COMPUTER | science | 14 : 11 | Player 1 wins! |
Scrabble | wiNNeR | 14 : 9 | Player 1 wins! |
Korrektheit
Führen Sie in Ihrem Terminal den folgenden Befehl aus, um die Korrektheit Ihrer Arbeit zu überprüfen. Die Datei muss scrabble.c heißen, und Sie müssen sich im Ordner scrabble befinden.
check50 -l inf-zone/exercises/2026/scrabbleStyle
Führen Sie den folgenden Befehl aus, um den Stil Ihres Codes mit style50Prüfprogramm von CS50, das zeigt, wo Ihr Code von den Formatierungsregeln abweicht. In Grün zeigt es, was Sie ergänzen sollten, in Rot, was wegfallen soll. Glossar → zu analysieren:
style50 scrabble.cAbgeben
Geben Sie im Ordner scrabble ab:
inf upload scrabbleDanach sehen Sie, welche Tests Ihr Programm besteht und ob die Übung für die Bonuspunkte zählt. Wie Sie inf installieren und sich anmelden, steht unter Abgeben mit inf.
Diese Seite als Markdown: ansehen herunterladen