source: liacs/ai/sudoku/sudoku.cpp@ 16

Last change on this file since 16 was 2, checked in by Rick van der Zwet, 15 years ago

Initial import of data of old repository ('data') worth keeping (e.g. tracking
means of URL access statistics)

File size: 28.2 KB
Line 
1/* file: sudoku.c
2 * author: rick van der Zwet 0433373, 2006
3 * University Leiden, LIACS
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <time.h>
10#include <signal.h>
11
12#define MAX_XYZ 9
13#define EMPTY_SPOT '_'
14
15
16#define bold "[1m"
17#define normal "[0m"
18
19#define DEBUGPLACE stderr
20const char esc = 27; /* escape character */
21
22
23int debug(const int level = 0)
24{
25#if DEBUG
26 if (level <= DEBUG)
27 {
28 return(1);
29 }
30 else
31 {
32 return(0);
33 }
34#else
35 return(0);
36#endif
37}
38
39class Sudoku {
40 public:
41 Sudoku();
42 void printNice(const int boldRow = -1, const int boldCol = -1, const char emptcolSpace = EMPTY_SPOT);
43 void printRaw();
44 void printPossible();
45 void printPossibleAtNumber(const int row, const int col);
46 void reset();
47 int randomNumbers(const double chance);
48 int fromFile(FILE *handle);
49 int insert(const int row, const int col, const int number);
50 int solutionFinder();
51 private:
52 int _sudoku[MAX_XYZ][MAX_XYZ];
53 bool _possible[MAX_XYZ][MAX_XYZ][MAX_XYZ];
54 int _numbersFilled;
55 void _updatePossibleList(const int row, const int col, const int number);
56 bool _solution1(int &row, int &col, int &number);
57 bool _solution2(int &row, int &col, int &number);
58 bool _solution3a(int &row, int &col, int &number);
59 bool _solution3b(int &row, int &col, int &number);
60};
61
62Sudoku::Sudoku()
63{
64 reset();
65}
66
67
68void Sudoku::printRaw()
69{
70 int row,col;
71 for (row = 0; row < MAX_XYZ ; row++)
72 {
73 for (col = 0; col < MAX_XYZ; col++)
74 {
75 printf("%i ", _sudoku[row][col]);
76 }
77 printf("\n");
78 }
79}
80void Sudoku::printNice(const int boldRow, const int boldCol,
81 const char emptcolSpace)
82{
83 int row,col;
84 int tmpRow;
85 const int maxRow = (MAX_XYZ + (MAX_XYZ / 3)) * 2 + 1;
86 for(tmpRow = 0; tmpRow < maxRow; tmpRow++)
87 {
88 if ((tmpRow%8) == 0) { printf("+"); }else {printf("-");}
89 }
90 printf("\n");
91 for (row = 0; row < MAX_XYZ ; row++)
92 {
93 printf("| ");
94 for (col = 0; col < MAX_XYZ; col++)
95 {
96 if ( _sudoku[row][col] == 0)
97 {
98 printf("%c ",emptcolSpace);
99 }
100 else
101 {
102 if (row == boldRow && col == boldCol)
103 {
104 printf("%c%s%i%c%s ",esc, bold, _sudoku[row][col],
105 esc, normal);
106 }
107 else
108 {
109 printf("%i ", _sudoku[row][col]);
110 }
111 }
112 if ( ((col - 2) % 3) == 0 )
113 {
114 printf("| ");
115 }
116 }
117 printf("\n");
118 if ( ((row - 2) % 3) == 0 )
119 {
120 for(tmpRow = 0; tmpRow < maxRow; tmpRow++)
121 {
122 if ((tmpRow%8) == 0)
123 {
124 printf("+");
125 }
126 else
127 {
128 printf("-");
129 }
130 }
131 printf("\n");
132 }
133 }
134 printf("\n\n");
135}
136
137void Sudoku::printPossibleAtNumber(const int row, const int col)
138{
139 if (debug(3))
140 {
141 int tmpPossible;
142 fprintf(DEBUGPLACE, "Possible at [%i,%i]: ", row, col);
143 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
144 {
145 if (_possible[row][col][tmpPossible] == true)
146 {
147 fprintf(DEBUGPLACE,"%i ", tmpPossible + 1);
148 }
149 }
150 fprintf(DEBUGPLACE, "\n");
151 }
152}
153
154void Sudoku::printPossible()
155{
156 int row,col;
157 if (debug(3))
158 {
159 for (row = 0; row < MAX_XYZ ; row++)
160 {
161 for (col = 0; col < MAX_XYZ; col++)
162 {
163 if(_sudoku[row][col] == 0)
164 {
165 printPossibleAtNumber(row,col);
166 }
167 }
168 }
169 }
170}
171
172
173void Sudoku::_updatePossibleList(const int row, const int col, const int number)
174{
175 int tmpRow;
176 int tmpCol;
177 int blockRow;
178 int blockCol;
179 int c;
180
181
182 /* Row and Col and Number own */
183 for (c = 0; c < MAX_XYZ; c++)
184 {
185 _possible[row][col][c] = false;
186 _possible[row][c][number - 1] = false;
187 _possible[c][col][number - 1] = false;
188 }
189
190 /* Block */
191 tmpRow = row - (row % (MAX_XYZ / 3));
192 tmpCol = col - (col % (MAX_XYZ / 3));
193 for (blockRow = tmpRow; blockRow < (tmpRow + 3); blockRow++)
194 {
195 for (blockCol = tmpCol; blockCol < (tmpCol + 3); blockCol++)
196 {
197 _possible[blockRow][blockCol][number - 1] = false;
198 }
199 }
200}
201
202int Sudoku::insert(const int row, const int col, const int number)
203{
204 if (debug(1)) { fprintf(DEBUGPLACE, "Will insert %i at [%i,%i]: %i\n",
205 number, row, col, _possible[row][col][number - 1]); }
206
207 if (_possible[row][col][number - 1] == true)
208 {
209 _updatePossibleList(row, col, number);
210 _sudoku[row][col] = number;
211 _numbersFilled++;
212 return(0);
213 }
214 else
215 {
216 return(1);
217 }
218}
219
220int Sudoku::randomNumbers(const double chance)
221{
222 if (debug(1)) { fprintf(DEBUGPLACE, "Running createsudoku\n"); }
223 int row;
224 int col;
225 int c;
226 int randomnumber;
227 int numberdone[MAX_XYZ];
228 int numbertried;
229
230 srand( (unsigned)time( NULL ) );
231
232 for (row = 0; row < MAX_XYZ; row++)
233 {
234 for (col = 0; col < MAX_XYZ; col++)
235 {
236 if (rand() < (RAND_MAX * (chance / 100)))
237 {
238 numbertried = 0;
239 for (c = 0; c < MAX_XYZ; c++ ) { numberdone[c] = 0; }
240 do
241 {
242 if (numbertried == 9)
243 {
244 return(1);
245 }
246 else
247 {
248 numbertried++;
249 }
250 do
251 {
252 randomnumber = 1 + (int) ( (double)MAX_XYZ * (random() / (RAND_MAX + 1.0)));
253 } while (numberdone[randomnumber - 1] == 1);
254 numberdone[randomnumber - 1] = 1;
255 if (debug(2)) { fprintf(DEBUGPLACE, "Random check number %i at [%i,%i]\n",
256 randomnumber, row,col); }
257 } while ( insert(row, col, randomnumber) == 1);
258 }
259 else
260 {
261 _sudoku[row][col] = 0;
262 }
263 }
264 }
265 return(0);
266}
267
268void Sudoku::reset()
269{
270 //temp counters
271 int row;
272 int col;
273 int z;
274
275 _numbersFilled = 0;
276 for (row = 0; row < MAX_XYZ; row++)
277 {
278 for (col = 0; col < MAX_XYZ; col++)
279 {
280 _sudoku[row][col] = 0;
281 for (z = 0; z < MAX_XYZ; z++)
282 {
283 _possible[row][col][z] = true;
284 }
285 }
286 }
287}
288
289int Sudoku::fromFile(FILE *handle)
290{
291 int row;
292 int col;
293 int tmpInt;
294 for (row = 0; row < MAX_XYZ; row++)
295 {
296 for (col = 0; col < MAX_XYZ; col++)
297 {
298 fscanf(handle, "%1i", &tmpInt);
299 if (tmpInt != 0)
300 {
301 insert(row, col, tmpInt);
302 }
303 }
304 }
305 fclose(handle);
306 return(0);
307}
308
309/* Use Basic technique of finding places with just one number left to place */
310bool Sudoku::_solution1(int &row, int &col, int &number)
311{
312 #define NOTHING_FOUND 0
313 #define ONE_FOUND 1
314 #define MORE_THEN_ONE_FOUND 2
315 int tmpRow;
316 int tmpCol;
317 int tmpPossible;
318 int tmpNumber;
319 int searchState;
320
321 for (tmpRow = 0; tmpRow < MAX_XYZ; tmpRow++)
322 {
323 for (tmpCol = 0; tmpCol < MAX_XYZ; tmpCol++)
324 {
325 if (_sudoku[tmpRow][tmpCol] == 0)
326 {
327 tmpNumber = 0;
328 searchState = NOTHING_FOUND;
329 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
330 {
331 if (_possible[tmpRow][tmpCol][tmpPossible] == true &&
332 searchState == ONE_FOUND)
333 {
334 searchState = MORE_THEN_ONE_FOUND;
335 break;
336 }
337 else if (_possible[tmpRow][tmpCol][tmpPossible] == true &&
338 searchState == NOTHING_FOUND)
339 {
340 tmpNumber = tmpPossible + 1;
341 searchState = ONE_FOUND;
342 }
343 }
344 if (searchState == ONE_FOUND)
345 {
346 row = tmpRow;
347 col = tmpCol;
348 number = tmpNumber;
349 return(true);
350 }
351 }
352 }
353 }
354
355 return(false);
356}
357
358/* Check if number can onlcol be placed somewhere, if not able to place anywhere else */
359/* FIXME: Should be more modular, to reduce line length and readabilitcol */
360/* FIXME: find nice solution for goto's */
361bool Sudoku::_solution2(int &row, int &col, int &number)
362{
363 int tmpRow;
364 int tmpCol;
365 int tmpPossible;
366 int tmpNumber;
367
368 int blockRow;
369 int blockTmpRow;
370 int blockCol;
371 int blockTmpCol;
372 bool result;
373
374 for (tmpRow = 0; tmpRow < MAX_XYZ; tmpRow++)
375 {
376 for (tmpCol = 0; tmpCol < MAX_XYZ; tmpCol++)
377 {
378 if (_sudoku[tmpRow][tmpCol] == 0)
379 {
380 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
381 {
382 if (_possible[tmpRow][tmpCol][tmpPossible] == true)
383 {
384 if (debug(3))
385 {
386 fprintf(DEBUGPLACE,
387 "DEBUG SOL 2: Checking [%i,%i], number: %i...\n",
388 tmpRow,tmpCol,(tmpPossible +1));
389 }
390 /* checkRow */
391 result = true;
392 for (tmpNumber = 0; tmpNumber < MAX_XYZ; tmpNumber++)
393 {
394 if (_possible[tmpNumber][tmpCol][tmpPossible] == true &&
395 tmpRow != tmpNumber)
396 {
397 if (debug(3))
398 {
399 fprintf(DEBUGPLACE,
400 "DEBUG SOL 2: ..failed at Rowcheck bcol [%i,%i]\n",
401 tmpNumber,tmpCol);
402 }
403 result = false;
404 break;
405 }
406 }
407 if (result == true)
408 {
409 if (debug(3)) { fprintf(DEBUGPLACE,"DEBUG SOL 2: ..succesfull at Rowcheck\n"); }
410 goto solutionFound;
411 }
412
413 /* checkCol */
414 result = true;
415 for (tmpNumber = 0; tmpNumber < MAX_XYZ; tmpNumber++)
416 {
417 if (_possible[tmpRow][tmpNumber][tmpPossible] == true &&
418 tmpCol != tmpNumber)
419 {
420 if (debug(3))
421 {
422 fprintf(
423 DEBUGPLACE,
424 "DEBUG SOL 2: ..failed at Cowcheck bcol [%i,%i]\n",
425 tmpRow,tmpNumber);
426 }
427 result = false;
428 break;
429 }
430 }
431 if (result == true)
432 {
433 if (debug(3)) { fprintf(DEBUGPLACE,"DEBUG SOL 2: ..succesfull at Cowcheck\n"); }
434 goto solutionFound;
435 }
436
437 /* checkBlock */
438 result = true;
439 blockTmpRow = tmpRow - (tmpRow % (MAX_XYZ / 3));
440 blockTmpCol = tmpCol - (tmpCol % (MAX_XYZ / 3));
441 for (blockRow = blockTmpRow; blockRow < (blockTmpRow + 3); blockRow++)
442 {
443 for (blockCol = blockTmpCol; blockCol < (blockTmpCol + 3); blockCol++)
444 {
445 if (debug(4))
446 {
447 fprintf(DEBUGPLACE,"DEBUG SOL 2: ..checking [%i,%i]\n",blockRow,blockCol);
448 }
449 if(_possible[blockRow][blockCol][tmpPossible] == true &&
450 (not (tmpRow == blockRow && tmpCol == blockCol)) )
451 {
452 if (debug(4)) { fprintf(DEBUGPLACE,"DEBUG SOL 2: ...will cause failure\n"); }
453 result = false;
454 goto blockCheckFailed;
455 }
456 else
457 {
458 if (debug(4)) { fprintf(DEBUGPLACE,"DEBUG SOL 2: ...will be no harm\n"); }
459 }
460 }
461 }
462blockCheckFailed:
463 if (result == true)
464 {
465 if (debug(3)) { fprintf(DEBUGPLACE,"DEBUG SOL 2: ..succesfull at Blockcheck\n"); }
466 goto solutionFound;
467 }
468 }
469 }
470 }
471 }
472 }
473
474 return(false);
475
476solutionFound:
477 row = tmpRow;
478 col = tmpCol;
479 number = tmpPossible + 1;
480 return(true);
481}
482
483/* available striper, row based */
484/* FIXME: Should be more modular, to reduce line length and readabilitcol */
485bool Sudoku::_solution3a(int &row, int &col, int &number)
486{
487 int tmpRow;
488 int tmpCol;
489 int tmpPossible;
490 int tmpPossible2;
491 int tmpColNumber;
492 int tmpNumber[MAX_XYZ];
493 int tmpAllNumbers;
494 int tmpAllNumbersFound;
495
496 bool result;
497
498 for (tmpRow = 0; tmpRow < MAX_XYZ; tmpRow++)
499 {
500 for (tmpCol = 0; tmpCol < MAX_XYZ; tmpCol++)
501 {
502 if (_sudoku[tmpRow][tmpCol] == 0)
503 {
504 if (debug(3)) { fprintf(DEBUGPLACE,"SOL 3a DEBUG Checking [%i,%i]...\n",tmpRow,tmpCol); }
505 /* Set all numbers */
506 tmpAllNumbers = 0;
507 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
508 {
509 if (_possible[tmpRow][tmpCol][tmpPossible] == true)
510 {
511 tmpNumber[tmpPossible] = 1;
512 tmpAllNumbers++;
513 }
514 else
515 {
516 tmpNumber[tmpPossible] = 0;
517 }
518 }
519 if (debug(3)) { fprintf(DEBUGPLACE,"SOL 3a DEBUG %i\n", tmpAllNumbers); }
520 if (tmpAllNumbers != 0)
521 {
522 for (tmpColNumber = 0; tmpColNumber < MAX_XYZ; tmpColNumber++)
523 {
524 if (_sudoku[tmpRow][tmpColNumber] == 0 && tmpColNumber != tmpCol)
525 {
526 result = true;
527 for (tmpPossible2 = 0; tmpPossible2 < MAX_XYZ; tmpPossible2++)
528 {
529 if ( _possible[tmpRow][tmpColNumber][tmpPossible2] == true &&
530 _possible[tmpRow][tmpCol][tmpPossible2] == false)
531 {
532 if (debug(3))
533 {
534 fprintf(DEBUGPLACE,"SOL 3a DEBUG [%i,%i] failed at %i\n",
535 tmpRow, tmpColNumber,tmpPossible2+1);
536 }
537 result = false;
538 break;
539 }
540 }
541 if (result == true)
542 {
543 if (debug(3))
544 {
545 fprintf(DEBUGPLACE,"SOL 3a DEBUG [%i,%i] will increase\n",
546 tmpRow, tmpColNumber);
547 }
548 for (tmpPossible2 = 0; tmpPossible2 < MAX_XYZ; tmpPossible2++)
549 {
550 if (_possible[tmpRow][tmpColNumber][tmpPossible2] == true)
551 {
552 if (debug(3)) { fprintf(DEBUGPLACE,
553 "SOL 3a DEBUG [%i,%i] will increase possible %i to %i\n",
554 tmpRow, tmpColNumber, tmpPossible2 + 1, tmpNumber[tmpPossible2] + 1);
555 }
556
557 if (tmpNumber[tmpPossible2] == tmpAllNumbers)
558 {
559 goto colCheckFailed;
560 }
561 else
562 {
563 tmpNumber[tmpPossible2]++;
564 }
565 }
566 }
567 }
568 }
569 }
570
571 /* calculate if result found */
572 tmpAllNumbersFound = 1;
573 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
574 {
575 if (tmpNumber[tmpPossible] == tmpAllNumbers)
576 {
577 tmpAllNumbersFound++;
578 if (debug(3))
579 {
580 fprintf(DEBUGPLACE,
581 "SOL 3b DEBUG %i reduced tmpAllNumbers to %i\n",
582 tmpPossible + 1, tmpAllNumbers);
583 }
584 }
585 }
586
587 if (tmpAllNumbersFound == tmpAllNumbers)
588 {
589 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
590 {
591 if (tmpNumber[tmpPossible] == 1)
592 {
593 row = tmpRow;
594 col = tmpCol;
595 number = tmpPossible + 1;
596 return(true);
597 }
598 }
599 }
600 }
601 } //end if
602colCheckFailed:
603 if (debug(3)) { fprintf(DEBUGPLACE,"SOL 3c DEBUG no failed solution found\n"); }
604 }
605 }
606 return(false);
607}
608
609/* available striper, col based, note row number will change ;-) */
610/* FIXME: Should be more modular, to reduce line length and readabilitcol */
611bool Sudoku::_solution3b(int &row, int &col, int &number)
612{
613 int tmpRow;
614 int tmpCol;
615 int tmpPossible;
616 int tmpPossible2;
617 int tmpRowNumber;
618 int tmpNumber[MAX_XYZ];
619 int tmpAllNumbers;
620 int tmpAllNumbersFound;
621
622 bool result;
623
624 for (tmpRow = 0; tmpRow < MAX_XYZ; tmpRow++)
625 {
626 for (tmpCol = 0; tmpCol < MAX_XYZ; tmpCol++)
627 {
628 if (_sudoku[tmpRow][tmpCol] == 0)
629 {
630 if (debug(3)) { fprintf(DEBUGPLACE,"SOL 3b DEBUG Checking [%i,%i]...\n",tmpRow,tmpCol); }
631 /* Set all numbers */
632 tmpAllNumbers = 0;
633 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
634 {
635 if (_possible[tmpRow][tmpCol][tmpPossible] == true)
636 {
637 tmpNumber[tmpPossible] = 1;
638 tmpAllNumbers++;
639 }
640 else
641 {
642 tmpNumber[tmpPossible] = 0;
643 }
644 }
645 if (debug(3)) { fprintf(DEBUGPLACE,"SOL 3b DEBUG %i\n", tmpAllNumbers); }
646 if (tmpAllNumbers != 0)
647 {
648 for (tmpRowNumber = 0; tmpRowNumber < MAX_XYZ; tmpRowNumber++)
649 {
650 if (_sudoku[tmpRowNumber][tmpCol] == 0 && tmpRowNumber != tmpRow)
651 {
652 result = true;
653 for (tmpPossible2 = 0; tmpPossible2 < MAX_XYZ; tmpPossible2++)
654 {
655 if ( _possible[tmpRowNumber][tmpCol][tmpPossible2] == true &&
656 _possible[tmpRow][tmpCol][tmpPossible2] == false)
657 {
658 if (debug(3))
659 {
660 fprintf(DEBUGPLACE,
661 "SOL 3b DEBUG [%i,%i] failed at %i\n",
662 tmpRowNumber, tmpCol,tmpPossible2+1);
663 }
664 result = false;
665 break;
666 }
667 }
668 if (result == true)
669 {
670 if (debug(3)) { fprintf(DEBUGPLACE,
671 "SOL 3b DEBUG [%i,%i] will increase\n",
672 tmpRowNumber, tmpCol);
673 }
674 for (tmpPossible2 = 0; tmpPossible2 < MAX_XYZ; tmpPossible2++)
675 {
676 if (_possible[tmpRowNumber][tmpCol][tmpPossible2] == true)
677 {
678 if (debug(3))
679 {
680 fprintf(DEBUGPLACE,
681 "SOL 3b DEBUG [%i,%i] will increase possible %i to %i\n",
682 tmpRowNumber, tmpCol, tmpPossible2 + 1,
683 tmpNumber[tmpPossible2] + 1);
684 }
685
686 if (tmpNumber[tmpPossible2] == tmpAllNumbers)
687 {
688 goto rowCheckFailed;
689 }
690 else
691 {
692 tmpNumber[tmpPossible2]++;
693 }
694 }
695 }
696 }
697 }
698 }
699
700 /* calculate if result found */
701 tmpAllNumbersFound = 1;
702 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
703 {
704 if (tmpNumber[tmpPossible] == tmpAllNumbers)
705 {
706 tmpAllNumbersFound++;
707 if (debug(3))
708 {
709 fprintf(DEBUGPLACE,
710 "SOL 3b DEBUG %i reduced tmpAllNumbers to %i\n",
711 tmpPossible + 1, tmpAllNumbers);
712 }
713 }
714 }
715
716 if (tmpAllNumbersFound == tmpAllNumbers)
717 {
718 for (tmpPossible = 0; tmpPossible < MAX_XYZ; tmpPossible++)
719 {
720 if (tmpNumber[tmpPossible] == 1)
721 {
722 row = tmpRow;
723 col = tmpCol;
724 number = tmpPossible + 1;
725 return(true);
726 }
727 }
728 }
729 }
730 } //end if
731rowCheckFailed:
732 if (debug(3)) { fprintf(DEBUGPLACE,"SOL 3b DEBUG no failed solution found\n"); }
733 }
734 }
735 return(false);
736}
737int Sudoku::solutionFinder()
738{
739 #define NO_SOLUTION 0
740 #define SOLUTION_1 1
741 #define SOLUTION_2 2
742 #define SOLUTION_3a 3
743 #define SOLUTION_3b 4
744 #define SOLUTION_3c 5
745 int row;
746 int col;
747 int number;
748
749 bool gameAnalcolzed;
750 int returnCode;
751 int solutionNumber;
752
753 gameAnalcolzed = false;
754
755 while( gameAnalcolzed == false )
756 {
757 solutionNumber = NO_SOLUTION;
758 if (_numbersFilled == MAX_XYZ * MAX_XYZ)
759 {
760 gameAnalcolzed = true;
761 returnCode = 0;
762 }
763 else
764 {
765 if (_solution1(row, col, number) == true)
766 {
767 solutionNumber = SOLUTION_1;
768 }
769 else if(_solution2(row, col, number) == true)
770 {
771 solutionNumber = SOLUTION_2;
772 }
773 else if(_solution3a(row, col, number) == true)
774 {
775 solutionNumber = SOLUTION_3a;
776 }
777 else if(_solution3b(row, col, number) == true)
778 {
779 solutionNumber = SOLUTION_3b;
780 }
781 else
782 {
783 gameAnalcolzed = true;
784 returnCode = 1;
785 }
786 }
787
788 if (solutionNumber != NO_SOLUTION)
789 {
790 insert(row, col, number);
791 printf("Filled in %i at [%i,%i] found with finder %i\n", number, row, col, solutionNumber);
792 printf("Total Numbers filled %i\n", _numbersFilled);
793 printNice(row, col);
794 getchar();
795 }
796
797 }
798 return(returnCode);
799}
800
801int main(int argc, char *argv[])
802{
803 Sudoku puzzel;
804 int timesFailed;
805 int returnCode;
806
807 returnCode = 0;
808
809 if (argc == 3 && strcmp(argv[1], "-f") == 0)
810 {
811 if (strcmp(argv[2], "-") == 0)
812 {
813 if (debug(1)) { fprintf(DEBUGPLACE, "Reading from 'stdin'\n"); }
814 puzzel.fromFile(stdin);
815 }
816 else
817 {
818 if (debug(1)) { fprintf(DEBUGPLACE, "Reading from %s\n",argv[2]); }
819 puzzel.fromFile(fopen(argv[2], "r"));
820 }
821 printf("I have read this puzzle\n");
822 puzzel.printNice();
823 returnCode = puzzel.solutionFinder();
824 if (returnCode == 0)
825 {
826 printf("I Guess this will be the final solution\n");
827 puzzel.printNice();
828 }
829 else
830 {
831 printf("Finding Solution failed, error code: %i\n", returnCode);
832 printf("Failed at puzzle\n");
833 puzzel.printNice();
834 puzzel.printPossible();
835 }
836 }
837 else if (argc == 3 && strcmp(argv[1], "-c") == 0)
838 {
839 fprintf(DEBUGPLACE,"Please wait will generating puzzle");
840 timesFailed = 0;
841 while (puzzel.randomNumbers(strtod(argv[2], NULL)) == 1 )
842 {
843 timesFailed++;
844 if (debug(1))
845 {
846 fprintf(DEBUGPLACE, "Failed to created the puzzel at the %i round\n", timesFailed);
847 }
848 else
849 {
850 fprintf(DEBUGPLACE,".");
851 }
852 puzzel.reset();
853 }
854 fprintf(DEBUGPLACE, "\nResult, (NOTE(!): puzzle might not be solveble)\n");
855 puzzel.printRaw();
856 }
857 else
858 {
859 printf("Usage %s -f <filename>\n",argv[0]);
860 printf("NOTE 1: No error checking done, valid input puzzel will be ");
861 printf("generated the -c flags\n");
862 printf("NOTE 2: if <filename> = -, stdin will be used as input");
863 printf("Usage %s -c <percent filled> To create a new puzzle\n",argv[0]);
864 printf("NOTE 1: Above 60%% it will be a bit hard to create ");
865 printf("a puzzle\n");
866 printf("NOTE 2: Puzzle generated will not always be solveble\n");
867 returnCode = 128;
868 }
869 return(returnCode);
870}
871
872
Note: See TracBrowser for help on using the repository browser.