-
Notifications
You must be signed in to change notification settings - Fork 0
/
hangman.c
227 lines (199 loc) · 7.64 KB
/
hangman.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#define WORD_SIZE 10
// Deklarieren von Funktionen
int readData(char* , char*[]); // Einlesen der "wordlist.txt"
int testForLetter(char, char*, int); // Testet ob ein Buchstabe in einem String vorhanden ist
int menue(); // Das Menue des Spieles (Auswahl von Single und Mulitplayer)
void update(int, char*, char*, int); // Die ausgabe des Aktuellen Spielfeldes
void selectionsort(int, char[]); // Sortieren
int main() {
// Deklarierne von Variablen
int words, lives, i, finish, lettersOfWord, mode;
char wrongLetters[27], rightLetters[27], wordToFind[WORD_SIZE], *wordList[100], temp[WORD_SIZE], input;
lettersOfWord = 0;
words = readData("wordlist.txt", wordList); // Lese Wörter aus Datei ein
if(!words) return words;
do{
system("cls");
lives = 11;
finish = 0;
// ALLES RESETEN
for(i = 0; i < WORD_SIZE; i++){
wordToFind[i] = '\0';
temp[i] = '\0';
}
for(i = 0; i < 27; i++){
wrongLetters[i] = '\0';
rightLetters[i] = '\0';
}
// Modus wählen
mode = menue();
switch (mode){
case 1: // Zufalls-Wort aus "wordlist.txt" (Singleplayer)
// Ein Zufällieges Wort in "wordToFind" Speichern.
srand(time(NULL));
int index = rand() % words;
strcpy(wordToFind, wordList[index]);
// Für jeden Buchstaben einen "_"
// Wortlänge herrausfinden und speichern
for(lettersOfWord = 0; wordToFind[lettersOfWord] != '\0' && wordToFind[lettersOfWord] != '\n'; lettersOfWord++){
wordToFind[lettersOfWord] = toupper(wordToFind[lettersOfWord]);
rightLetters[lettersOfWord] = '_';
}
break;
case 2: // Benutzereingabe einen Wortes (Multiplayer)
do{
// Wort einlesen
finish = 1;
printf("Bitte gib ein Wort ein: ");
fflush(stdin);
fgets(temp, WORD_SIZE, stdin);
// Testen ob Wort zugelassene unzugelassen Buchstaben hat (Zugelassene Buchstaben [A-Z])
for(i = 0; temp[i] != '\n' && temp[i] != '\0'; i++){
temp[i] = toupper(temp[i]);
if(temp[i] < 'A' || temp[i] > 'Z'){
finish = 0;
printf("%c\n", temp[i]);
}
}
}while(!finish); // Wiederhole solange, bis Wort zugelassen ist
// Für Buchstabe in Wort ein "_"
for(i = 0; temp[i] != '\0' && temp[i] != '\n'; i++){
rightLetters[i] = '_';
}
rightLetters[i] = '\0'; // Den String sicherheitshalber noch mal Manuell beenden
strcpy(wordToFind, temp); // Speichern des Wortes in "wordToFind"
lettersOfWord = i; // Länge des Wortes Speichern
break;
default:break;
}
// Das eigentliche Spiel...
finish = 0;
do{
// Gebe das aktuelle Spielfeld aus
update(lives, wrongLetters, rightLetters, lettersOfWord);
do{
// Lese Buchstaben von User ein
printf("Bitte gib einen Buchstaben ein: ");
fflush(stdin);
scanf("%c", &input);
input = toupper(input); // Formatiere eingabe zu Großbuchstabe
if(testForLetter(input, wrongLetters, 27)) input = '0'; // Teste ob der Buchstabe schon mal vorgekommen ist
if(testForLetter(input, rightLetters, 27)) input = '0'; // Teste ob der Buchstabe schon mal vorgekommen ist
}while(input < 'A' || input > 'Z'); // Wiederhohle solange die eingabe unzulässig ist (Eingabe außerhalb von [A-Z])
// Teste ob Buchstabe gesucht wird oder nicht
if(!testForLetter(input, wordToFind, 27)){
// Aktuallisiere die Falschbuchstabenliste
/*
Zählen bis jetzt Falscher Eingaben und füge die neue dann hinzu
*/
for(i = 0; wrongLetters[i]; i++){}
wrongLetters[i] = input;
selectionsort(i+1, wrongLetters); // Sortieren der Buchstaben
lives--; // Ziehe ein Leben ab
}else{
for(i = 0; wordToFind[i]; i++){ // Ersetze die "_" mit dem richtiegen Buchstaben
if(wordToFind[i] == input){
rightLetters[i] = input;
}
}
}
if(!testForLetter('_', rightLetters, WORD_SIZE)) finish = 1; // Teste ob Wort gefunden ist.
}while(!finish && lives); // Wiederhohle solange nicht fertig oder keine Leben mehr
system("cls");
if(finish){ // Wenn keine Leben mehr vorhanden sind -> Verloren
printf("\t\tGLUECKWUNSCH!\n\tDu hast das Wort gefunden!!!");
}else { // Sonst -> Gewonnen
printf("\t\tVERLOREN!\n\tDu hast leider keine Leben mehr!");
}
printf("\n\nMoechtest du nochmal spielen? [Y|N]");
fflush(stdin);
}while(toupper(getchar()) == 'Y'); // Wiederhohle solange user noch spielen möchte
// Freigeben des Spiechers
for(i = 0; i < words; i++){
free(wordList[i]);
}
return 0;
}
int readData(char *path, char *data[]){
// Deklarieren
FILE *wordList;
char buffer[40];
int i = 0, j = 0;
int words;
// Öffnen der Datei im lese modus
wordList = fopen(path, "r");
if (wordList){ // Prüfe auf existends der Datie
while (fgets(buffer, 40, wordList)){ // Einlesen eine Zeile
data[i] = (char *) malloc(40*sizeof(char)); // Reservieren des Speichers für die Wörter
for(j = 0; buffer[j] && buffer[j] != '\n'; j++){ // Bearbeitung der Buchstaben
buffer[j] = toupper(buffer[j]);
if(buffer[j] < 'A' || buffer[j] > 'Z'){ // Überprüfe auf unerlaubte Zeichen
system("cls");
printf("ERROR: Ein unerwartetes Zeichen wurde in \"wordlist.txt\" gefunden. (Zeile %i > '%c')\n", i+1, buffer[j]);
printf("\tPruefe ob alle eingaben korrekt sind.\n");
printf("\tEs sind nur Buchstaben des Englischen Alphabetes erlaubt [A-Z]!");
return 0;
}
}
strcpy(data[i], buffer); // Kopiere bearbeitete eingabe in "data[i]"
i++;
}
}else
printf("Konnte Datei %s nicht finden", path);
return i;
}
int testForLetter(char letter, char *sequenze, int length) {
int i = 0;
while (sequenze[i]){ // Gehe jeden einzelnen Buchstaben im String durch
if(tolower(sequenze[i]) == tolower(letter)) return 1; // Wenn vorhanden -> gebe 1 zurück
i++;
}
return 0; // Wenn buchstabe nicht vorhanden -> Gebe 0 zurück
}
int menue(){
char input[3];
int x;
do{
printf("Willkommen bei Hangman!\n");
printf("Bitte waehle eine der folgenden Optionen:\n");
printf("1 - Bekomme ein zufaelliges Wort aus einer Datei\n");
printf("2 - Gib ein Wort ein, und lass deine Freunde raten!\n\n\n");
printf("Waehle bitte deine Option: ");
fflush(stdin);
fgets(input, 3, stdin); // Lese eingabe ein ( Als Buchstaben )
x = atoi(input); // Wandle eingabe in Zahl um
}while (x < 1 || x > 2); // Wiederhohle solange eingabe nicht gültig
return x;
}
void update(int lives, char *wrongLetters, char *rightLetters, int wordSize){
int i;
system("cls");
printf("\t\tFinde das Wort!\n\n\n");
for(i = 0; i < wordSize; i++){ // Gebe Wort aus (Mit "_" und den Buchstaben) Bsp.: "W _ R T"
printf("%c ", rightLetters[i]);
}
printf("%70s: %i\n\n","Leben", lives); // Gebe aktuelle Leben aus
printf("Falsche Buchstaben: ");
for(i = 0; wrongLetters[i]; i++){ // Gebe alle Buchstaben die Falsch eingegeben wurden aus
printf("%c | ", wrongLetters[i]);
}
printf("\n\n");
}
void selectionsort(int anzahl, char daten[]){
int i, k, t, min;
for( i = 0; i < anzahl-1; i++){
min = i;
for( k = i+1; k < anzahl; k++){
if( daten[k] < daten[min])
min = k;
}
t = daten[min];
daten[min] = daten[i];
daten[i] = t;
}
}