Kill mega-sena.sh
[lcapit-junk-code.git] / games / hangman / game.c
blobbddef97bdac2ca3ae50cd2c249bc2c465a6c9148
1 /*
2 * This file is licensed under the GPLv2 license
3 *
4 * Luiz Fernando N. Capitulino
5 * <lcapitulino@gmail.com>
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
12 #include "game.h"
13 #include "misc.h"
15 #define ALPHABET_SIZE 26
17 struct player_game {
18 const char *orig_word;
19 const char *tip;
20 char *word;
21 size_t len;
22 int hits;
23 int errors;
24 char alphabet[ALPHABET_SIZE];
27 enum game_result {
28 WIN = 1,
29 LOST,
32 int game_debug;
33 static int max_times = 6;
35 static int player_game_init(struct player_game *p,
36 const char *word,
37 const char *tip)
39 int i;
41 p->len = strlen(word);
43 if ((int) p->len >= max_times)
44 max_times += 2;
46 p->word = malloc(p->len);
47 if (!p->word)
48 return -1;
49 memset(p->word, '-', p->len);
50 p->word[p->len] = '\0';
52 p->orig_word = word;
53 p->tip = tip;
54 p->hits = p->errors = 0;
56 for (i = 'a'; i <= 'z'; i++)
57 p->alphabet[i - 'a'] = i;
59 return 0;
62 static void player_destroy(const struct player_game *p)
64 free(p->word);
67 static void player_show_status(const struct player_game *p)
69 int i;
71 clear_screen();
73 printf("Palavra: ");
74 for (i = 0; i < (int) p->len; i++)
75 printf("%c", p->word[i]);
77 if (game_debug)
78 printf(" (%s)", p->orig_word);
80 printf("\n\n");
82 printf("Letras disponiveis: ");
83 for (i = 0; i < ALPHABET_SIZE; i++)
84 printf("%c", p->alphabet[i]);
85 printf("\n\n");
87 printf("Falhas disponiveis: %d\n\n", max_times - p->errors);
89 if (p->errors == max_times - 1)
90 printf("Dica: %s\n\n", p->tip);
93 static int count_letter(const char *word, char c)
95 int count, i;
97 count = 0;
99 for (i = 0; word[i] != '\0'; i++)
100 if (word[i] == c)
101 count++;
103 return count;
106 static enum game_result end_of_game(const struct player_game *p)
108 if (p->hits == (int) p->len)
109 return WIN;
111 if (p->errors == max_times)
112 return LOST;
114 return 0;
117 static void show_final_stats(const struct player_game *p,
118 enum game_result result)
120 switch (result) {
121 case WIN:
122 printf("Parabens! Acertou ");
123 break;
124 case LOST:
125 printf("Azar! Perdeu ");
126 break;
129 printf("usando %d letras (%d erros)\n", p->hits + p->errors,p->errors);
130 if (result == LOST)
131 printf("\nA palavra era: %s\n", p->orig_word);
132 mprint("");
135 static void player_turn(struct player_game *p)
137 char c;
138 size_t i;
140 printf("-> Digite uma letra e pressione enter: ");
141 scanf("%c", &c);
142 c = tolower(c);
143 flush_all();
145 if (c < 'a' || c > 'z') {
146 mprint("Apenas sao permitidas letras de a-z\n");
147 return;
150 if (p->alphabet[c - 'a'] == '-') {
151 mprint("Letra ja escolhida antes\n");
152 return;
155 for (i = 0; i < p->len; i++) {
156 if (p->orig_word[i] == c && p->word[i] == '-') {
157 p->word[i] = c;
158 p->hits++;
159 break;
163 if (count_letter(p->orig_word, c) == count_letter(p->word, c))
164 p->alphabet[c - 'a'] = '-';
166 if (p->word[i] != c) {
167 mprint("Errou!\n");
168 p->errors++;
172 void run_game(const char *word, const char *tip)
174 struct player_game player;
176 player_game_init(&player, word, tip);
178 for (;;) {
179 enum game_result res;
181 player_show_status(&player);
182 player_turn(&player);
183 res = end_of_game(&player);
184 if (res) {
185 player_show_status(&player);
186 show_final_stats(&player, res);
187 break;
191 player_destroy(&player);