d840b6d40b2f10fa54e6ff2648e0d5a9e49e51f4
[wordblah.git] / wordblox.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <stdbool.h>
5 #include <string.h>
6 #include <ctype.h>
7
8 #include "wordblox.h"
9 #include "constantstrings.h"
10
11 /* export the clues to a text file */
12 void do_export_clues (Puzzle *p)
13 {
14 if (p->grid_frozen == false)
15 {
16 printf (UNFROZEN_GRID);
17 char ch = getchar ();
18 return;
19 }
20 char fname[256];
21 printf (INPUT_FILE);
22 fgets (fname, 256, stdin);
23 if (strlen(fname) == 1)
24 return;
25 char *filename = strtok (fname, "\n");
26
27 export_clues (p, filename);
28 printf (FILE_SAVED);
29 char ch = getchar ();
30 }
31
32 /* export the puzzle to a png file */
33 void do_export_puzzle (Puzzle *p)
34 {
35 if (p->grid_frozen == false)
36 {
37 printf (UNFROZEN_GRID);
38 char ch = getchar ();
39 return;
40 }
41 char fname[256];
42 printf (INPUT_FILE);
43 fgets (fname, 256, stdin);
44 if (strlen (fname) == 1)
45 return;
46 char* filename = strtok (fname, "\n");
47
48 printf (INPUT_EXPORT_ANSWERS);
49 char ans[3];
50 fgets (ans, 3, stdin);
51 bool solution;
52 solution = (toupper (ans[0]) == 'Y') ? true : false;
53
54 export_grid_image (p, filename, solution);
55 printf (FILE_SAVED);
56 char ch = getchar ();
57 }
58
59 /* reset the grid */
60 void do_reset_puzzle (Puzzle *p)
61 {
62 int grid_size = p->grid_size;
63 printf (INPUT_CONFIRM_RESET);
64 char conf[3];
65 fgets (conf, 3, stdin);
66 if (toupper (conf[0]) == 'Y')
67 init_puzzle (p, grid_size);
68 }
69
70 /* set clue for a word - only for frozen grid */
71 void do_set_clue_word (Puzzle *p, enum ORIENTATION orient)
72 {
73 print_puzzle (p);
74 if (p->grid_frozen == false)
75 {
76 printf (UNFROZEN_GRID);
77 char ch = getchar ();
78 return;
79 }
80 int index;
81 String clue;
82 printf (INPUT_INDEX);
83 index = get_num ();
84 printf (INPUT_CLUE);
85 fgets (clue, MAX_CLUE_LENGTH, stdin);
86 char* cl = strtok (clue, "\n");
87
88 bool res;
89 res = set_clue (p, cl, index, orient);
90
91 if (res == false)
92 {
93 printf (NO_WORD_INDEX);
94 char ch = getchar ();
95 }
96 }
97
98 /* clear a cell in the grid */
99 void do_clear_cell (Puzzle *p)
100 {
101 print_puzzle (p);
102 if (p->grid_frozen == true)
103 {
104 printf (FROZEN_GRID);
105 char ch = getchar ();
106 return;
107 }
108 int row, col;
109 printf (INPUT_ROW);
110 row = get_num ();
111 printf (INPUT_COL);
112 col = get_num ();
113 if (row >= p->grid_size || col >= p->grid_size)
114 {
115 printf (EXCEED_GRID_SIZE);
116 char ch = getchar ();
117 return;
118 }
119 p->chars[row][col] = ' ';
120 print_puzzle (p);
121
122 char ch = getchar ();
123 }
124
125 /* add a down word to the grid */
126 void do_add_down_word (Puzzle *p)
127 {
128 print_puzzle (p);
129 if (p->grid_frozen == true)
130 {
131 printf (FROZEN_GRID);
132 char ch = getchar ();
133 return;
134 }
135 char wd[MAX_PUZZLE_SIZE];
136 int row, col;
137 printf (INPUT_WORD);
138 fgets (wd, MAX_PUZZLE_SIZE, stdin);
139 char *word = is_valid_word (wd);
140 if (word == NULL)
141 {
142 printf (INVALID_WORD);
143 char ch = getchar ();
144 return;
145 }
146 printf (INPUT_ROW);
147 row = get_num ();
148 printf (INPUT_COL);
149 col = get_num ();
150 if (row >= p->grid_size || col >= p->grid_size)
151 {
152 printf (EXCEED_GRID_SIZE);
153 char ch = getchar ();
154 return;
155 }
156 if (strlen (word) > (p->grid_size - row))
157 {
158 printf (WORD_TOO_LONG);
159 char ch = getchar ();
160 return;
161 }
162
163 for (int i = row; i < row + strlen(word); i ++)
164 p->chars[i][col] = toupper(word[i - row]);
165
166 print_puzzle (p);
167 char ch = getchar ();
168 }
169
170 /* add an across word to the grid */
171 void do_add_across_word (Puzzle *p)
172 {
173 print_puzzle (p);
174 if (p->grid_frozen == true)
175 {
176 printf (FROZEN_GRID);
177 char ch = getchar ();
178 return;
179 }
180 char wd[MAX_PUZZLE_SIZE];
181 int row, col;
182 printf (INPUT_WORD);
183 fgets (wd, MAX_PUZZLE_SIZE, stdin);
184 char *word = is_valid_word (wd);
185 if (word == NULL)
186 {
187 printf (INVALID_WORD);
188 char ch = getchar ();
189 return;
190 }
191 printf (INPUT_ROW);
192 row = get_num ();
193 printf (INPUT_COL);
194 col = get_num ();
195 if (row >= p->grid_size || col >= p->grid_size)
196 {
197 printf (EXCEED_GRID_SIZE);
198 char ch = getchar ();
199 return;
200 }
201
202 if (strlen (word) > (p->grid_size - col))
203 {
204 printf (WORD_TOO_LONG);
205 char ch = getchar ();
206 return;
207 }
208
209 for (int i = col; i < col+strlen (word); i ++)
210 p->chars[row][i] = toupper(word[i - col]);
211
212 print_puzzle (p);
213 char ch = getchar ();
214 }
215 /* confirm exit */
216 bool do_confirm_exit ()
217 {
218 printf (INPUT_CONFIRM_EXIT);
219 char res[3];
220 fgets (res, 3, stdin);
221 if (toupper(res[0]) == 'Y')
222 return true;
223 else
224 return false;
225 }
226
227 /* main loop for the puzzle editor */
228 void puzzle_editor_loop (Puzzle *p, const char *filename)
229 {
230 bool loop = true;
231 while (loop)
232 {
233 print_menu (WHITE, BLUE, PUZZLE_MENU_TITLE, PUZZLE_EDIT_MENU, 13, 50);
234 printf (INPUT_CHOICE);
235 int ch = get_num ();
236 switch (ch)
237 {
238 case 1: print_puzzle (p);
239 char ch = getchar ();
240 break;
241 case 2: do_add_across_word (p);
242 break;
243 case 3: do_add_down_word (p);
244 break;
245 case 4: do_clear_cell (p);
246 break;
247 case 5: freeze_puzzle (p);
248 print_puzzle (p);
249 ch = getchar ();
250 break;
251 case 6: unfreeze_puzzle (p);
252 print_puzzle (p);
253 ch = getchar ();
254 break;
255 case 7: do_set_clue_word (p, ACROSS);
256 break;
257 case 8: do_set_clue_word (p, DOWN);
258 break;
259 case 9: save_puzzle (p, filename);
260 printf ("%s\n",FILE_SAVED);
261 ch = getchar ();
262 break;
263 case 10: do_reset_puzzle (p);
264 print_puzzle (p);
265 ch = getchar ();
266 break;
267 case 11: do_export_puzzle (p);
268 break;
269 case 12: do_export_clues (p);
270 break;
271 case 13: loop = ! do_confirm_exit ();
272 break;
273 }
274 }
275 }
276
277 /* open an existing puzzle */
278 void do_open_puzzle ()
279 {
280 Puzzle p;
281 printf (INPUT_FILE);
282 char fname[256];
283 fgets(fname, 256, stdin);
284 if (strlen (fname) == 1)
285 return;
286 char* filename = strtok (fname, "\n");
287 p = load_puzzle (filename);
288 puzzle_editor_loop (&p, filename);
289 }
290
291 /* create a new blank puzzle */
292 void do_new_puzzle ()
293 {
294 Puzzle p;
295 printf (INPUT_FILE);
296 char fname[256];
297 fgets (fname, 256, stdin);
298 if (strlen (fname) == 1)
299 return;
300 char* filename = strtok (fname, "\n");
301 printf (INPUT_GRID_SIZE);
302 int size;
303 size = get_num ();
304 if (size > MAX_PUZZLE_SIZE)
305 {
306 printf (EXCEED_MAX_GRID_SIZE);
307 char c = getchar ();
308 }
309 else
310 {
311 init_puzzle (&p, size);
312 puzzle_editor_loop (&p, filename);
313 }
314 }
315
316 /* The main loop of the program */
317 int main_loop ()
318 {
319 /* Print the main menu */
320 while (1)
321 {
322 print_menu (WHITE, BLUE, MAIN_MENU_TITLE, MAIN_MENU, 3, 50);
323 printf (INPUT_CHOICE);
324 int ch = get_num ();
325 switch (ch)
326 {
327 case 1: do_new_puzzle ();
328 break;
329 case 2: do_open_puzzle ();
330 break;
331 case 3: exit (0);
332 }
333 }
334 }
335
336 int main (int argc, char* argv[])
337 {
338 if (argc >= 2)
339 {
340 Puzzle p;
341 switch (argc)
342 {
343 case 2 : p = load_puzzle (argv[1]);
344 puzzle_editor_loop (&p, argv[1]);
345 break;
346 case 4 : if (strcmp (argv[2], "new") == 0)
347 {
348 int grid_size = atoi (argv[3]);
349 init_puzzle (&p, grid_size);
350 puzzle_editor_loop (&p, argv[1]);
351 break;
352 }
353 default: fprintf (stderr, USAGE_LINE_1, argv[0]);
354 fprintf (stderr, USAGE_LINE_2);
355 fprintf (stderr, USAGE_LINE_3);
356 exit (3);
357 }
358 }
359 return (main_loop ());
360 }