-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathhangman.c
372 lines (247 loc) · 12.1 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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
// Week 2 Extra Credit: Hangman
// Marcus Kapoor (Columbia University)
// Instructor: Sonny Li
// gcc -lform -lncurses -Wall hangman.c -o hangman
// ./hangman
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <time.h>
#include <ncurses.h>
#include <unistd.h>
#include <ctype.h>
int terminate();
int dyingimages();
int randdict;
char enter, leave;
const char *words[10] = {
"computer",
"communism",
"mathematics",
"macintosh",
"lamborghini",
"apricot",
"dentist",
"earthquake",
"hexagon",
"electricity"
};
char word[12]; // the answer word chosen from the word bank above ^
int length; // the length of the answer word
char letter; // the letter user guesses
int dying = 0; // how dead your are (once it reaches max number, you lose)
int playing = 1;
int win = 0; // goes up to letter count (if statement will end the game by setting playing = 0)
char lettersused[26]; // every letter used, regardless of success/failure (to prevent duplicates that mess up the win counter)
// =================================================================================================================================
int main () {
// ~~~~~~ Initialization: Part I ~~~~~~
srand(time(NULL));
initscr(); // creates a 'window' that can be edited. printw(), scanw(), refresh(), etc. are editing this 'window'
printw("Welcome to Hangman! To play, press [Enter]\n");
noecho(); // the terminal doesn't echo (type) what you enter. kind of like when you input a password
enter = getch(); // get character
while (enter != '\n') // if the key typed is not [enter], do nothing
{
refresh(); // refreshes the window. needed for ncurses function. prints won't appear unless the screen is refreshed
enter = getch();
}
move(0, 0); // move cursor to top left of window (starting point). coordinates are (y, x) instead of (x, y)
clrtoeol(); // clear the line (The welcome to Hangman! blah blah blah)
refresh();
// ~~~~~~ Initialization: Part 2 ~~~~~~
mvprintw(1, 27, "==========================="); // mvprintw prints a line at specific coordinates
mvprintw(2, 27, " !! HANGMAN !! ");
mvprintw(3, 27, "===========================");
dyingimages(); // function that displays the hangman images (separated to reduce clutter)
mvprintw(14, 0, "================================================================================");
mvprintw(16, 0, "Attempted Letters: "); // the area where your failed letters appear
refresh();
randdict = rand() % 10; // random #
strcpy(word, words[randdict]); // copy random word from dictionary to word. limit to first run through
// mvprintw(35, 0, "%s\n\n", word); // prints the chosen word (testing purposes only)
refresh();
length = strlen(word); // find length of word
char reveal[length]; // create an array of the size of the length of the word
for (int i = 0; i < length; i++) { // set the # of blanks for the word
reveal[i] = '_';
}
reveal[length] = '\0'; // terminating character (if not for this, the blanks would be inaccurate)
mvprintw(18, 0, "I'm thinking of a word: "); // prints the '_' string that was set up just before
// note to me: if necessary, use a similar for loop to put spaces between the reveal (_ _ _ _ _) above to make it more legible
for (int i = 0; i < length; ++i) {
printw("%c ", reveal[i]);
}
// ~~~~~~ Game Starts ~~~~~~
while (playing == 1) {
move(19,0);
clrtoeol();
mvprintw(19, 0, "Guess a letter: ");
echo(); // reenables echo (disabled in the first initialization)
refresh();
scanw("%1c", &letter); // the letter you choose
letter = tolower(letter); // decapitalize the letter ('a' != 'A')
refresh();
noecho();
int yes = 0; // do letters match? 0 = false 1 = true
for (int i = 0; i < length; i++) { // compares letter guessed to every character within the random word
if (letter == word[i] && lettersused[i] != letter) {
// if one or more of the letters match, reveal the letter, set yes = 1, and win++
reveal[i] = letter;
lettersused[i] = letter; // this is to prevent the person from entering the same character again
// otherwise, it messes with the win counter
move(18, 24);
for (int i = 0; i < length; ++i) {
printw("%c ", reveal[i]); // prints the new reveal array with the added character and spaces
}
yes = 1;
win++;
refresh();
}
}
char aletters[6];
if (yes != 1){ // if letters do not match, then print attempted letter
aletters[dying] = letter; // if dying is 0, the letter will be put in the 1st index of the attempt array
// dying determines index
aletters[dying+1] = '\0'; // terminates the string so that the weird null characters don't show up
mvprintw(16, 0, "Attempted Letters: ");
// note to me: if necessary, use a similar for loop to put spaces between the reveal to make it more legible
for (int i = 0; i < 7; ++i) {
printw("%c ", aletters[i]);
}
dying++; // dying counter goes up
dyingimages(); // the image displayed is based on the dying counter
// 0 = hanger only; 1 = head; 2 = head and neck, etc.
}
refresh();
// if the dying counter is equal to 7, you lose
// if the win counter is equal to the word's length, you win (this exits the overarching while loop)
if (dying == 7 || win == length) {
playing = 0;
}
}
// end of the while (it will keep repeating 'til the win/lose if statements inside are satisfied)
if (win == length) {
mvprintw(21, 0, "You win!\n");
terminate();
}
else if (dying == 7) {
mvprintw(21, 0, "You let the poor man die! Shame on you.");
mvprintw(22, 0, "The word you were looking for was: %s.", word);
terminate();
}
else {
mvprintw(21, 0, "Gah. You broke the game. Say sorry!\n");
terminate();
}
return 0;
}
// =================================================================================================================================
int terminate () {
mvprintw(24, 0, "Press [Q] to Quit\n");
leave = getch();
leave = tolower(leave);
refresh();
while (leave != 'q') {
leave = getch();
leave = tolower(leave);
}
endwin();
return 0;
}
// =================================================================================================================================
int dyingimages () {
if (dying == 0) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] ");
mvprintw(8 ,31, " [][] ");
mvprintw(9 ,31, " [][] ");
mvprintw(10,31, " [][] ");
mvprintw(11,31, " [][] ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else if (dying == 1) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] ");
mvprintw(10,31, " [][] ");
mvprintw(11,31, " [][] ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
// if it was just your head hanging, wouldn't you be deader than if your full body was hanging? #logic
}
else if (dying == 2) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] | ");
mvprintw(10,31, " [][] ");
mvprintw(11,31, " [][] ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else if (dying == 3) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] \\| ");
mvprintw(10,31, " [][] ");
mvprintw(11,31, " [][] ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else if (dying == 4) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] \\|/ ");
mvprintw(10,31, " [][] ");
mvprintw(11,31, " [][] ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else if (dying == 5) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] \\|/ ");
mvprintw(10,31, " [][] | ");
mvprintw(11,31, " [][] ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else if (dying == 6) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] \\|/ ");
mvprintw(10,31, " [][] | ");
mvprintw(11,31, " [][] / ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else if (dying == 7) {
mvprintw(5 ,31, " [][][][][][][] ");
mvprintw(6 ,31, " [][][][][][][] ");
mvprintw(7 ,31, " [][] | ");
mvprintw(8 ,31, " [][] 0 ");
mvprintw(9 ,31, " [][] \\|/ ");
mvprintw(10,31, " [][] | ");
mvprintw(11,31, " [][] / \\ ");
mvprintw(12,31, " [][] ");
mvprintw(13,31, "[][][][][][][][][]");
}
else {
mvprintw(13, 31, "You broke the game. Bugs suck :(");
}
return 0;
}