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