CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
gui_sudoku.c-Dateireferenz
#include "camera_info.h"
#include "keyboard.h"
#include "lang.h"
#include "conf.h"
#include "gui.h"
#include "gui_draw.h"
#include "gui_lang.h"
#include "gui_batt.h"
#include "gui_mbox.h"
#include "modes.h"
#include "fileutil.h"
#include "time.h"
#include "module_def.h"
#include "simple_module.h"
+ Include-Abhängigkeitsdiagramm für gui_sudoku.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define SUDOKU_BG_COLOR   COLOR_WHITE
 
#define MARKER_COLOR   COLOR_GREEN
 
#define TEXT_COLOR   MAKE_COLOR(SUDOKU_BG_COLOR, COLOR_BLACK)
 
#define MARKER_TEXT_COLOR   MAKE_COLOR(MARKER_COLOR, COLOR_WHITE)
 
#define MODE_VIEW   1
 
#define MODE_EDIT   2
 
#define MODE_MENU   4
 
#define BG   1
 
#define FIELD   2
 
#define MENU   4
 
#define PAD   8
 
#define START_NUMBERS   25
 
#define MAX_START_NUMBERS   32
 
#define MENU_ELEMENTS   8
 

Funktionen

void gui_module_menu_kbd_process ()
 
int gui_sudoku_kbd_process ()
 
void gui_sudoku_draw ()
 
void exit_sudoku ()
 
int get_dec_num (int number)
 
int one_plus_nums (int number)
 
int is_one_num (int number)
 
void del_numpad ()
 
void draw_numpad ()
 
int get_pad_num ()
 
void set_pad_num (int number)
 
void draw_menu ()
 
void draw_field ()
 
void redraw ()
 
int sudoku_finished (int *pointer)
 
int sudoku_follows_rules (int *pointer)
 
int sudoku_follows_rules_xy (int x, int y, int number)
 
int get_missing_nums_line (int lineNum)
 
int get_missing_nums_column (int columnNumber)
 
int get_missing_nums_square (int squareX, int squareY)
 
int sudoku_search_candidates ()
 
int sudoku_insert_lonely_numbers ()
 
int sudoku_solve (int *pointer)
 
void exchange_row (int r1, int r2)
 
void exchange_column (int c1, int c2)
 
void exchangeSquareRow (int sr1, int sr2)
 
void exchange_square_column (int sc1, int sc2)
 
int remove_nums (int count)
 
int sudoku_new (void)
 
void sudoku_menu_execute ()
 
int gui_sudoku_init ()
 
void exit_sudoku (int save)
 
int _run ()
 
int _module_can_unload ()
 
int _module_exit_alt ()
 

Variablen

gui_handler GUI_MODE_SUDOKU
 
static int running = 0
 
int flag [10] ={0x0, 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100}
 
int xPos
 
int yPos
 
int xMenuPos
 
int xPosOld
 
int yPosOld
 
int fieldLineDistance
 
int fieldLineLength
 
int mode
 
int xFieldBorder
 
int yFieldBorder
 
int menuPos
 
int draw
 
int xPadStart
 
int yPadStart
 
int padLineDistance
 
int xPosPad
 
int yPosPad
 
int field [9][9]
 
int user [9][9]
 
int mess [9][9]
 
libsimple_sym _librun
 
ModuleInfo _module_info
 

Makro-Dokumentation

#define BG   1

Definiert in Zeile 47 der Datei gui_sudoku.c.

#define FIELD   2

Definiert in Zeile 48 der Datei gui_sudoku.c.

#define MARKER_COLOR   COLOR_GREEN

Definiert in Zeile 38 der Datei gui_sudoku.c.

#define MARKER_TEXT_COLOR   MAKE_COLOR(MARKER_COLOR, COLOR_WHITE)

Definiert in Zeile 40 der Datei gui_sudoku.c.

#define MAX_START_NUMBERS   32

Definiert in Zeile 53 der Datei gui_sudoku.c.

#define MENU   4

Definiert in Zeile 49 der Datei gui_sudoku.c.

#define MENU_ELEMENTS   8

Definiert in Zeile 54 der Datei gui_sudoku.c.

#define MODE_EDIT   2

Definiert in Zeile 43 der Datei gui_sudoku.c.

#define MODE_MENU   4

Definiert in Zeile 44 der Datei gui_sudoku.c.

#define MODE_VIEW   1

Definiert in Zeile 42 der Datei gui_sudoku.c.

#define PAD   8

Definiert in Zeile 50 der Datei gui_sudoku.c.

#define START_NUMBERS   25

Definiert in Zeile 52 der Datei gui_sudoku.c.

#define SUDOKU_BG_COLOR   COLOR_WHITE

Definiert in Zeile 37 der Datei gui_sudoku.c.

#define TEXT_COLOR   MAKE_COLOR(SUDOKU_BG_COLOR, COLOR_BLACK)

Definiert in Zeile 39 der Datei gui_sudoku.c.

Dokumentation der Funktionen

int _module_can_unload ( )

Definiert in Zeile 1076 der Datei gui_sudoku.c.

1077 {
1078  return running == 0;
1079 }
int _module_exit_alt ( )

Definiert in Zeile 1081 der Datei gui_sudoku.c.

1082 {
1083  running = 0;
1084  return 0;
1085 }
int _run ( )

Definiert in Zeile 1061 der Datei gui_sudoku.c.

1062 {
1064  {
1066  }
1067  else
1068  {
1069  running = 1;
1070  gui_sudoku_init();
1071  }
1072 
1073  return 0;
1074 }
void draw_field ( )

Definiert in Zeile 198 der Datei gui_sudoku.c.

199 {
200  int i, x, y;
201  static char str[16];
202 
203  //redraw last field to remove the marker
205  xPosOld=xPos;
206  yPosOld=yPos;
207 
208  //Lines
209  for (i=0; i<10; ++i){
210  //vertical lines
211  draw_line(xFieldBorder+fieldLineDistance*i, yFieldBorder, xFieldBorder+fieldLineDistance*i, yFieldBorder+fieldLineLength, COLOR_BLACK);
212  //horizontal lines
213  draw_line(xFieldBorder, yFieldBorder+fieldLineDistance*i, xFieldBorder+fieldLineLength, yFieldBorder+fieldLineDistance*i, COLOR_BLACK);
214  }
215  //draw thick vertical lines
216  draw_line(xFieldBorder+fieldLineDistance*3-1, yFieldBorder, xFieldBorder+fieldLineDistance*3-1, yFieldBorder+fieldLineLength, COLOR_BLACK);
217  draw_line(xFieldBorder+fieldLineDistance*3+1, yFieldBorder, xFieldBorder+fieldLineDistance*3+1, yFieldBorder+fieldLineLength, COLOR_BLACK);
218 
219  draw_line(xFieldBorder+fieldLineDistance*6-1, yFieldBorder, xFieldBorder+fieldLineDistance*6-1, yFieldBorder+fieldLineLength, COLOR_BLACK);
220  draw_line(xFieldBorder+fieldLineDistance*6+1, yFieldBorder, xFieldBorder+fieldLineDistance*6+1, yFieldBorder+fieldLineLength, COLOR_BLACK);
221 
222  //draw thick horizontal lines
223  draw_line(xFieldBorder, yFieldBorder+fieldLineDistance*3-1, xFieldBorder+fieldLineLength, yFieldBorder+fieldLineDistance*3-1, COLOR_BLACK);
224  draw_line(xFieldBorder, yFieldBorder+fieldLineDistance*3+1, xFieldBorder+fieldLineLength, yFieldBorder+fieldLineDistance*3+1, COLOR_BLACK);
225 
226  draw_line(xFieldBorder, yFieldBorder+fieldLineDistance*6-1, xFieldBorder+fieldLineLength, yFieldBorder+fieldLineDistance*6-1, COLOR_BLACK);
227  draw_line(xFieldBorder, yFieldBorder+fieldLineDistance*6+1, xFieldBorder+fieldLineLength, yFieldBorder+fieldLineDistance*6+1, COLOR_BLACK);
228 
229  //cursor
230  if (mode==MODE_VIEW){
231  draw_rectangle(xFieldBorder+xPos*fieldLineDistance, yFieldBorder+yPos*fieldLineDistance,
232  xFieldBorder+(xPos+1)*fieldLineDistance, yFieldBorder+(yPos+1)*fieldLineDistance, MAKE_COLOR(MARKER_COLOR,MARKER_COLOR), RECT_BORDER1);
233  draw_rectangle(xFieldBorder+xPos*fieldLineDistance+1, yFieldBorder+yPos*fieldLineDistance+1,
234  xFieldBorder+(xPos+1)*fieldLineDistance-1, yFieldBorder+(yPos+1)*fieldLineDistance-1, MAKE_COLOR(MARKER_COLOR,MARKER_COLOR), RECT_BORDER1);
235  draw_rectangle(xFieldBorder+xPos*fieldLineDistance+2, yFieldBorder+yPos*fieldLineDistance+2,
236  xFieldBorder+(xPos+1)*fieldLineDistance-2, yFieldBorder+(yPos+1)*fieldLineDistance-2, MAKE_COLOR(MARKER_COLOR,MARKER_COLOR), RECT_BORDER1);
237  }
238  if (mode==MODE_EDIT){
239  draw_ellipse(xFieldBorder+(xPos+1)*fieldLineDistance-fieldLineDistance/2, yFieldBorder+(yPos+1)*fieldLineDistance-fieldLineDistance/2, fieldLineDistance/2-3, fieldLineDistance/2-1, MARKER_COLOR, DRAW_FILLED);
240  sprintf(str, "%i", get_dec_num(user[yPos][xPos]));
241  draw_string(xFieldBorder+fieldLineDistance*xPos+(fieldLineDistance-FONT_WIDTH)/2, yFieldBorder+fieldLineDistance*yPos+(fieldLineDistance-FONT_HEIGHT)/2, str, MAKE_COLOR(MARKER_COLOR, COLOR_WHITE));
242  }
243 
244  //Numbers
245  for (y=0; y<9; y++){
246  for (x=0; x<9; x++){
247  /*im editmode wird an der cursorposition keine Zahl angezeigt, 0 wird auch nicht angezeigt*/
248  if (user[y][x]==0) continue;
249  if (mode==MODE_EDIT && x==xPos && y==yPos) continue;
250  sprintf(str, "%i", get_dec_num(user[y][x]));
251  if (field[y][x]!=0)
252  draw_string(xFieldBorder+fieldLineDistance*x+(fieldLineDistance-FONT_WIDTH)/2, yFieldBorder+fieldLineDistance*y+(fieldLineDistance-FONT_HEIGHT)/2, str, MAKE_COLOR(SUDOKU_BG_COLOR, COLOR_BLACK));
253  else draw_string(xFieldBorder+fieldLineDistance*x+(fieldLineDistance-FONT_WIDTH)/2, yFieldBorder+fieldLineDistance*y+(fieldLineDistance-FONT_HEIGHT)/2, str, MAKE_COLOR(SUDOKU_BG_COLOR, MARKER_COLOR));
254  }
255  }
256 }
void draw_menu ( )

Definiert in Zeile 188 der Datei gui_sudoku.c.

189 {
190  int i;
191 
192  for (i=0; i<MENU_ELEMENTS; i++)
193  {
195  }
196 }
void draw_numpad ( )

Definiert in Zeile 136 der Datei gui_sudoku.c.

137 {
138  int i, y, x;
139  static char str[16];
140  del_numpad();
141 
142  //horizontal
145 
146  //vertical
151 
152  //numbers
153  i=0;
154  for (y=0; y<3; y++)for (x=0; x<3; x++)
155  {
156  i++;
157  sprintf(str, "%i", i);
159  }
160  sprintf(str, "%i", 0);
162 
163  //marker
165  xPadStart+(xPosPad+1)*padLineDistance, yPadStart+(yPosPad+1)*padLineDistance, MAKE_COLOR(MARKER_COLOR,MARKER_COLOR), RECT_BORDER1);
166  draw_rectangle(xPadStart+xPosPad*padLineDistance+1, yPadStart+yPosPad*padLineDistance+1,
167  xPadStart+(xPosPad+1)*padLineDistance-1, yPadStart+(yPosPad+1)*padLineDistance-1, MAKE_COLOR(MARKER_COLOR,MARKER_COLOR), RECT_BORDER1);
168  draw_rectangle(xPadStart+xPosPad*padLineDistance+2, yPadStart+yPosPad*padLineDistance+2,
169  xPadStart+(xPosPad+1)*padLineDistance-2, yPadStart+(yPosPad+1)*padLineDistance-2, MAKE_COLOR(MARKER_COLOR,MARKER_COLOR), RECT_BORDER1);
170 }
void exchange_column ( int  c1,
int  c2 
)

Definiert in Zeile 631 der Datei gui_sudoku.c.

632 {
633  int temp, i;
634  for (i=0; i<9; i++)
635  {
636  temp=field[i][c1];
637  field[i][c1]=field[i][c2];
638  field[i][c2]=temp;
639  }
640 }
void exchange_row ( int  r1,
int  r2 
)

Definiert in Zeile 620 der Datei gui_sudoku.c.

621 {
622  int temp, i;
623  for (i=0; i<9; i++)
624  {
625  temp=field[r1][i];
626  field[r1][i]=field[r2][i];
627  field[r2][i]=temp;
628  }
629 }
void exchange_square_column ( int  sc1,
int  sc2 
)

Definiert in Zeile 648 der Datei gui_sudoku.c.

649 {
650  int i;
651  for (i=0; i<3; i++)exchange_column(sc1*3+i, sc2*3+i);
652 }
void exchangeSquareRow ( int  sr1,
int  sr2 
)

Definiert in Zeile 642 der Datei gui_sudoku.c.

643 {
644  int i;
645  for (i=0; i<3; i++)exchange_row(sr1*3+i, sr2*3+i);
646 }
void exit_sudoku ( )
void exit_sudoku ( int  save)

Definiert in Zeile 1039 der Datei gui_sudoku.c.

1040 {
1041  if (save!=0)
1042  {
1043  save = open("A/CHDK/GAMES/SUDOKU.SAV", O_WRONLY|O_CREAT|O_TRUNC, 0777);
1044  if (save>=0)
1045  {
1046  write(save, user, sizeof(user));
1047  write(save, field, sizeof(field));
1048  close(save);
1049  }
1050  }
1051  running = 0;
1053 }
int get_dec_num ( int  number)

Definiert in Zeile 84 der Datei gui_sudoku.c.

85 {
86  int i;
87  for (i=1; i<10; i++)
88  {
89  if (number&flag[i])return i;
90  }
91  return 0;
92 }
int get_missing_nums_column ( int  columnNumber)

Definiert in Zeile 393 der Datei gui_sudoku.c.

394 {
395  int returnnum=0;
396  int y;
397  for (y=0; y<9; y++)
398  {
399  if (is_one_num(mess[y][columnNumber]))returnnum |= mess[y][columnNumber];
400  }
401  return ~returnnum;
402 }
int get_missing_nums_line ( int  lineNum)

Definiert in Zeile 382 der Datei gui_sudoku.c.

383 {
384  int returnnum=0;
385  int x;
386  for (x=0; x<9; x++)
387  {
388  if (is_one_num(mess[lineNum][x]))returnnum |= mess[lineNum][x];
389  }
390  return ~returnnum;
391 }
int get_missing_nums_square ( int  squareX,
int  squareY 
)

Definiert in Zeile 404 der Datei gui_sudoku.c.

405 {
406  int returnnum=0;
407  int y, x;
408  for (y=squareY*3; y<squareY*3+3; y++)
409  {
410  for (x=squareX*3; x<squareX*3+3; x++)
411  {
412  if (is_one_num(mess[y][x]))returnnum |= mess[y][x];
413  }
414  }
415  return ~returnnum;
416 }
int get_pad_num ( )

Definiert in Zeile 172 der Datei gui_sudoku.c.

173 {
174  if (xPosPad==1 && yPosPad==-1)return 0;
175  else return flag[xPosPad+yPosPad*3+1];
176 }
void gui_module_menu_kbd_process ( )

Definiert in Zeile 463 der Datei gui_sokoban.c.

464 {
465  running = 0;
467 }
void gui_sudoku_draw ( )

Definiert in Zeile 267 der Datei gui_sudoku.c.

268 {
269  //battery and watch?
270  if (draw&BG)redraw();
271  else
272  {
273  if (draw&FIELD)draw_field();
274  if (draw&MENU)draw_menu();
275  if (draw&PAD)draw_numpad();
276  }
277  draw=0;
278 }
int gui_sudoku_init ( )

Definiert in Zeile 984 der Datei gui_sudoku.c.

985 {
986  int x, y;
988  yFieldBorder = 12;
990  xPos=4;
991  yPos=4;
993  {
995  }
996  else
997  {
999  }
1001  mode=MODE_VIEW;
1002  menuPos=0;
1004  xPadStart = xMenuPos;
1005  yPadStart = padLineDistance*6 + 20;
1006  xPosPad=1;
1007  yPosPad=1;
1008  for (x = 0; x < 9; x++) for (y = 0; y < 9; y++)
1009  {
1010  field[y][x] = 0;
1011  user[y][x]=0;
1012  }
1013  draw|=BG;
1014  gui_sudoku_draw(0);
1015 
1016  char *buf = load_file("A/CHDK/GAMES/SUDOKU.SAV", 0, 0);
1017  if (buf) { //load last sudoku
1018  memcpy(user, buf, sizeof(user));
1019  memcpy(field, buf+sizeof(user), sizeof(field));
1020  free(buf);
1021  } else {
1022  sudoku_new();
1023  memcpy(user, field, sizeof(user)); //copies field[][] in user[][]
1024  }
1026  draw|=FIELD;
1027  gui_sudoku_draw(0);
1029  return 1;
1030 }
int gui_sudoku_kbd_process ( )

Definiert in Zeile 857 der Datei gui_sudoku.c.

858 {
860 
861  switch (key) {
862  //Keys that are always the same
863  case KEY_ZOOM_IN:
865  else mode=MODE_VIEW;
866  draw|=FIELD|MENU;
867  break;
868  case KEY_ZOOM_OUT:
869  mode=MODE_VIEW;
870  draw|=FIELD|MENU;
871  break;
872  case KEY_ERASE:
873  case KEY_SHOOT_HALF:
874  if (mode & (MODE_VIEW | MODE_EDIT))
875  {
876  if (field[yPos][xPos]==0)user[yPos][xPos]=0;
877  if (mode==MODE_EDIT)
878  {
879  mode=MODE_VIEW;
880  del_numpad();
881  xPosPad=1;
882  yPosPad=1;
883  }
884  draw|=FIELD;
885  }
886  break;
887 
888  case KEY_DISPLAY:
892  draw|=BG;
893  break;
894  }
895  switch (mode)
896  {
897  case MODE_VIEW:
898  if (key & (KEY_UP | KEY_DOWN))
899  {
900  yPosOld=yPos;
901  if (key==KEY_UP)yPos--;
902  if (key==KEY_DOWN)yPos++;
903  yPos=(yPos+9)%9; //so that we don't get beyond the borders
904  draw|=FIELD;
905  }
906  if (key & (KEY_LEFT | KEY_RIGHT))
907  {
908  xPosOld=xPos;
909  if (key==KEY_LEFT)xPos--;
910  if (key==KEY_RIGHT)xPos++;
911  xPos=(xPos+9)%9; //so that we don't get beyond the borders
912  draw|=FIELD;
913  }
914  if (key==KEY_SET && field[yPos][xPos]==0)
915  {
916  mode=MODE_EDIT;
917  if (user[yPos][xPos]==0)user[yPos][xPos]=get_pad_num();
919  draw|=PAD|FIELD;
920  }
921  break;
922 
923  case MODE_EDIT:
924  if (key &(KEY_LEFT | KEY_RIGHT) && yPosPad>=0)
925  {
926  if (key==KEY_LEFT)xPosPad--;
927  if (key==KEY_RIGHT)xPosPad++;
928  xPosPad=(xPosPad+3)%3;
930  draw|=FIELD|PAD;
931  }
932  if (key &(KEY_UP | KEY_DOWN))
933  {
934  if (key==KEY_UP)yPosPad--;
935  if (key==KEY_DOWN)yPosPad++;
936  if (xPosPad==1)yPosPad=((yPosPad+5)%4)-1;
937  else yPosPad=(yPosPad+3)%3;
939  draw|=FIELD|PAD;
940  }
941  if (key==KEY_SET)
942  {
943  mode=MODE_VIEW;
944  draw=FIELD;
945  del_numpad();
946  xPosPad=1;
947  yPosPad=1;
948  if (sudoku_finished(&user[0][0])){
949  if (sudoku_follows_rules(&user[0][0]))
951  else
953  draw|=BG;
954  }
955  }
956  break;
957 
958  case MODE_MENU: //Keys in Menumode
959  key |= get_jogdial_direction();
960  if (key & (KEY_UP | KEY_DOWN | JOGDIAL_LEFT | JOGDIAL_RIGHT))
961  {
962  if (key==KEY_UP || key==JOGDIAL_LEFT)menuPos--;
963  if (key==KEY_DOWN || key==JOGDIAL_RIGHT)menuPos++;
965  draw|=MENU;
966  }
967  switch (key) {
968  case KEY_SET:
970  draw|=BG;
971  break;
972  case KEY_LEFT:
973  case KEY_RIGHT:
974  mode=MODE_VIEW;
975  draw|=FIELD|MENU;
976  break;
977  }
978  break;
979  }
980  return 0;
981 }
int is_one_num ( int  number)

Definiert in Zeile 112 der Datei gui_sudoku.c.

113 {
114  if (number==0)return 0;
115  int counter=0;
116  int i;
117  for (i=1; i<10; i++)
118  {
119  if (number & flag[i])
120  {
121  if (counter==1)return 0;
122  counter++;
123  }
124  }
125  return 1;
126 }
int one_plus_nums ( int  number)

Definiert in Zeile 95 der Datei gui_sudoku.c.

96 {
97  if (number==0)return 0;
98  int counter=0;
99  int i;
100  for (i=1; i<10; i++)
101  {
102  if (number & flag[i])
103  {
104  if (counter==1)return 1;
105  counter++;
106  }
107  }
108  return 0;
109 }
int remove_nums ( int  count)

Definiert in Zeile 658 der Datei gui_sudoku.c.

659 {
660  int ry, rx;
661  int temp;
662  int foundone=0;
663  while (!foundone)
664  {
665  ry=rand()%9;
666  rx=rand()%9;
667  if (field[ry][rx]!=0)
668  {
669  foundone=1;
670  temp=field[ry][rx];
671  field[ry][rx]=0;
672  }
673  }
674  if (count>START_NUMBERS)
675  {
676  if (remove_nums(count-1)==1)return 1;
677  else
678  {
679  field[ry][rx]=temp;
681  else return -1;
682  }
683  }
684  else if (count<=START_NUMBERS)
685  {
686  if (sudoku_solve(*field)==1)return 1;
687  else
688  {
689  field[ry][rx]=temp;
690  return -1;
691  }
692  }
693  //the program shouldn't come to this point, but my compiler is always angry
694  //because there's a missing return value...
695  else return -1;
696 }
void set_pad_num ( int  number)

Definiert in Zeile 178 der Datei gui_sudoku.c.

179 {
180  if (number==0)xPosPad=yPosPad=0;
181  else
182  {
183  xPosPad=(number-1)%3;
184  yPosPad=(number-1)/3;
185  }
186 }
int sudoku_finished ( int *  pointer)

Definiert in Zeile 283 der Datei gui_sudoku.c.

284 { //ist das Sudoku voll?
285  int i;
286  for (i=1; i<=81; i++)
287  {
288  if (*pointer==0 || one_plus_nums(*pointer))
289  return 0;
290  pointer++;
291  }
292  return 1;
293 }
int sudoku_follows_rules ( int *  pointer)

Definiert in Zeile 296 der Datei gui_sudoku.c.

297 {
298  int counter, chkflag, x, y, xs, ys, linenum, columnnum;
299 
300  //lines
301  for (linenum=0; linenum<=8; linenum++)
302  {
303  for (chkflag=1; chkflag<10; chkflag++)
304  {
305  counter=0;
306  for (x=0; x<=8; x++)
307  {
308  if (*(pointer+linenum*9+x)&flag[chkflag])
309  {
310  counter++;
311  if (counter>1) return 0;
312  }
313  }
314  }
315  }
316 
317 
318  //columns
319  for (columnnum=0; columnnum<=8; columnnum++)
320  {
321  for (chkflag=1; chkflag<10; chkflag++)
322  {
323  counter=0;
324  for (y=0; y<=8; y++)
325  {
326  if (*(pointer+y*9+columnnum)&flag[chkflag])
327  {
328  counter++;
329  if (counter>1) return 0;
330  }
331  }
332  }
333  }
334 
335 
336  //squares
337  for (chkflag=1; chkflag<10; chkflag++)
338  {
339  //Select the square
340  for (ys=0; ys<3; ys++)
341  {
342  for (xs=0; xs<3; xs++)
343  {
344  counter=0;
345  //Check each number in that square
346  for (y=ys*3; y<ys*3+3; y++)
347  {
348  for (x=xs*3; x<xs*3+3; x++)
349  {
350  if (*(pointer+y*9+x)&flag[chkflag])
351  {
352  counter++;
353  if (counter>1)return 0;
354  }
355  }
356  }
357  }
358  }
359  }
360 
361  //Sudoku has right syntax when it didn't return before
362  return 1;
363 }
int sudoku_follows_rules_xy ( int  x,
int  y,
int  number 
)

Definiert in Zeile 367 der Datei gui_sudoku.c.

368 {
369  int yc, xc;
370  for (xc=0; xc<9; xc++) if (field[y][xc]&(number)) return 0;
371  for (yc=0; yc<9; yc++) if (field[yc][x]&(number)) return 0;
372 
373  //printf("xq=%d, yq=%d\n", xq, yq);
374  for (yc = y/3 * 3; yc < y/3 * 3 + 3; yc++)
375  for (xc = x/3 * 3; xc < x/3 * 3 + 3; xc++)
376  if (field[yc][xc]& number) return 0;
377  return 1;
378 }
int sudoku_insert_lonely_numbers ( )

Definiert in Zeile 480 der Datei gui_sudoku.c.

481 {
482  int x, y, xs, ys, num, count;
483  int xtemp=0;
484  int ytemp=0;
485  int change=0;
486 
487  //check squares
488  for (ys=0; ys<3; ys++) for (xs=0; xs<3;xs++)for (num=1; num<10; num++)
489  {
490  count=0;
491  for (y=ys*3; y<ys*3+3; y++) for (x=xs*3; x<xs*3+3; x++)
492  {
493  if (field[y][x] > 0 || mess[y][x]==0 || is_one_num(mess[y][x]))
494  continue;
495  else if (mess[y][x] & flag[num])
496  {
497  if (count == 1)
498  goto nextnumS;
499  else
500  {
501  count++;
502  xtemp = x;
503  ytemp = y;
504  }
505  }
506  }
507  if (count==1)
508  {
509  mess[ytemp][xtemp]=flag[num];
510  change=1;
511  }
512  nextnumS:;
513  }
514 
515  //check lines
516  for (y=0; y<9; y++)for (num=1; num<10; num++)
517  {
518  count=0;
519  for (x=0; x<9; x++)
520  {
521  if (field[y][x] > 0 || mess[y][x]==0 || is_one_num(mess[y][x]))
522  continue;
523  else if (mess[y][x] & flag[num])
524  {
525  if (count == 1)
526  goto nextnumL;
527  else
528  {
529  count++;
530  xtemp = x;
531  ytemp = y;
532  }
533  }
534  }
535  if (count==1)
536  {
537  mess[ytemp][xtemp]=flag[num];
538  change=1;
539  }
540  nextnumL:;
541  }
542 
543  //check columns
544  for (x=0; x<9; x++)for (num=1; num<10; num++)
545  {
546  count=0;
547  for (y=0; y<9; y++)
548  {
549  if (field[y][x] > 0 || mess[y][x]==0 || is_one_num(mess[y][x]))
550  continue;
551  else if (mess[y][x] & flag[num])
552  {
553  if (count == 1)
554  goto nextnumC;
555  else
556  {
557  count++;
558  xtemp = x;
559  ytemp = y;
560  }
561  }
562  }
563  if (count==1)
564  {
565  mess[ytemp][xtemp]=flag[num];
566  change=1;
567  }
568  nextnumC:;
569  }
570 
571  return change;
572 }
void sudoku_menu_execute ( )

Definiert in Zeile 798 der Datei gui_sudoku.c.

799 {
800  int y, x;
801  switch (menuPos)
802  {
803  case 0: //check Sudoku
806  break;
807  case 1: //solve Sudoku
808  switch (sudoku_solve(&user[0][0]))
809  {
810  case 1:
812  memcpy(user, mess, sizeof(user)); //copies mess[][] in user[][]
813  break;
814  case 0:
816  //copy only known numbers
817  for (y=0; y<9; y++) for (x=0; x<9; x++) if (is_one_num(mess[y][x]))user[y][x]=mess[y][x];
818  break;
819  case -1:
821  for (y=0; y<9; y++) for (x=0; x<9; x++) if (is_one_num(mess[y][x]))user[y][x]=mess[y][x];
822  break;
823  }
824  break;
825  case 2: //new sudoku
826  //sprintf(str, "%i tries", sudoku_new());
827  //gui_mbox_init((int)"Info", (int)str, MBOX_TEXT_CENTER, NULL);
828  sudoku_new();
829  memcpy(user, field, sizeof(user)); //field in user kopieren
830  break;
831  case 3: //own sudoku
832  for (x = 0; x < 9; x++)for (y = 0; y < 9; y++)
833  {
834  field[y][x] = 0;
835  user[y][x]=0;
836  }
837  break;
838  case 4: //Info
839  gui_mbox_init(LANG_SUDOKU_INFO, (int)("(c)Frank, 2012, V 0.5"), MBOX_TEXT_CENTER, NULL);
840  break;
841  case 5:
842  exit_sudoku(0); //exit without save
843  break;
844  case 6:
845  exit_sudoku(1); //save and exit
846  break;
847  case 7:
848  if (stat("A/CHDK/GAMES/SUDOKU.SAV", 0)==0) {
849  remove("A/CHDK/GAMES/SUDOKU.SAV");
850  }
851  break;
852  }
853  mode=MODE_VIEW;
854 }
int sudoku_new ( void  )

Definiert in Zeile 698 der Datei gui_sudoku.c.

699 {
700  int foundone=0;
701  int x, y, i, j;
702 
703  srand((unsigned)time(NULL));
704  while (!foundone)
705  {
706  //reset field[][] to 0 everywhere
707  for (x = 0; x < 9; x++) for (y = 0; y < 9; y++) field[y][x] = 0;
708 
709  //fill in the first line
710  for (x=0; x<9; x++)field[0][x]=flag[x+1];
711 
712  //shuffling
713  for (i=1; i<=10; i++)
714  {
715  int rdm1=rand()%9+1;
716  int rdm2=rand()%9+1;
717  if (rdm1==rdm2)rdm2=(rdm2+1)%9;
718  rdm1=flag[rdm1];
719  rdm2=flag[rdm2];
720 
721  for (j=0; j<9; j++)
722  {
723  if (field[0][j]==rdm1)field[0][j]=rdm2;
724  else if (field[0][j]==rdm2)field[0][j]=rdm1;
725  }
726  }
727 
728  //now, we have to fill the rest of the cells
729  //by repeating the pattern just created
730  //we start at the second row
731  int xnum=2;
732  for (y=1; y<9; y++)
733  {
734  for (x=0; x<9; x++)
735  {
736  //%9 so it jumps from the end back to the beginning
737  xnum=(xnum+1)%9;
738  field[y][x]=field[0][xnum];
739  }
740  if ((y+1)%3==0)xnum=(xnum+4)%9;
741  else xnum=(xnum+3)%9;
742  }
743 
744  //Okay now, the field is filled with numbers.
745  //Now shuffle them a bit so that it won't get too easy!
746  int rdm1;
747  int rdm2;
748  int rdm3;
749  for (i=1; i<=10; i++)
750  {
751  rdm1=rand()%3;
752  rdm2=rand()%3;
753  if (rdm1==rdm2)rdm2=(rdm2+1)%3;
754  exchangeSquareRow(rdm1, rdm2);
755 
756  rdm1=rand()%3;
757  rdm2=rand()%3;
758  if (rdm1==rdm2)rdm2=(rdm2+1)%3;
759  exchange_square_column(rdm1, rdm2);
760 
761  for (j=1; j<=3; j++)
762  {
763  rdm1=rand()%3;
764  rdm2=rand()%3;
765  //rdm3 defines in which 3 squares we are shuffling
766  rdm3=rand()%3;
767  if (rdm1==rdm2)rdm2=(rdm2+1)%3;
768  exchange_row(rdm3*3+rdm1, rdm3*3+rdm2);
769 
770  rdm1=rand()%3;
771  rdm2=rand()%3;
772  rdm3=rand()%3;
773  if (rdm1==rdm2)rdm2=(rdm2+1)%3;
774  exchange_column(rdm3*3+rdm1, rdm3*3+rdm2);
775  }
776  }
777 
778  //a lot of times, we are not able to find the right numbers to remove,
779  //then we just generate a new fully filled sudoku
780  //74 tries to remove numbers before going to the next sudoku results in the best speed.
781  for (i=1; i<=74; i++)
782  {
783  if (remove_nums(9*9)==1) {
784  foundone=1;
785  break;
786  }
787  }
788 
789  //end while(!foundone)
790  }
791  return 1;
792 }
int sudoku_search_candidates ( )

Definiert in Zeile 422 der Datei gui_sudoku.c.

423 {
424  int temp, leftnums;
425  int x, y, xs, ys;
426  int change=0;
427  //columns
428  for (x=0; x<=8; x++)
429  {
430  leftnums=get_missing_nums_column(x);
431  for (y=0; y<=8; y++)
432  {
433  if (one_plus_nums(mess[y][x]))
434  {
435  temp=mess[y][x];
436  mess[y][x]&=leftnums;
437  if (temp !=mess[y][x])
438  change=1;
439  }
440  }
441  }
442 
443  //squares
444  for(xs=0; xs<3; xs++)for(ys=0; ys<3; ys++)
445  {
446  leftnums=get_missing_nums_square(xs, ys);
447  for(x=xs*3; x<xs*3+3; x++)for (y=ys*3; y<ys*3+3; y++)
448  {
449  if (one_plus_nums(mess[y][x]))
450  {
451  temp=mess[y][x];
452  mess[y][x]&=leftnums;
453  if (temp != mess[y][x])
454  change=1;
455  }
456  }
457  }
458 
459  //lines
460  for (y=0; y<9; y++)
461  {
462  leftnums=get_missing_nums_line(y);
463  for (x=0; x<9; x++)
464  {
465  if (one_plus_nums(mess[y][x]))
466  {
467  temp=mess[y][x];
468  mess[y][x]&=leftnums;
469  if (temp != mess[y][x])
470  change=1;
471  }
472  }
473  }
474  return change;
475 }
int sudoku_solve ( int *  pointer)

Definiert in Zeile 580 der Datei gui_sudoku.c.

581 {
582  //copies array from *pointer in mess -> we're solving in mess[][]
583  memcpy(mess, pointer, sizeof(mess));
584  int change=0;
585  int leftnums;
586  int x, y;
587 
588  //fill empty cells
589  for (y=0; y<=8; y++)
590  {
591  leftnums=get_missing_nums_line(y);
592  for (x=0; x<=8; x++)if (mess[y][x]==0)mess[y][x]=leftnums;
593  }
594 
595  //solve!!
596  do
597  {
598  change=sudoku_search_candidates();
599  if (!change)
600  {
601  if (!sudoku_follows_rules(*mess))return -1;
602  else change=sudoku_insert_lonely_numbers();
603  }
604  }while(change);
605 
606  //now the code above has filled in every number it could think about
607  if (sudoku_finished(*mess))
608  {
610  return 1;
611  else return -1;
612  }
613  else return 0;
614 }

Variablen-Dokumentation

libsimple_sym _librun
Initialisierung:

Definiert in Zeile 1091 der Datei gui_sudoku.c.

int draw

Definiert in Zeile 69 der Datei gui_sudoku.c.

int field[9][9]

Definiert in Zeile 73 der Datei gui_sudoku.c.

int fieldLineDistance

Definiert in Zeile 63 der Datei gui_sudoku.c.

int fieldLineLength

Definiert in Zeile 64 der Datei gui_sudoku.c.

int flag[10] ={0x0, 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100}

Definiert in Zeile 59 der Datei gui_sudoku.c.

int menuPos

Definiert in Zeile 68 der Datei gui_sudoku.c.

int mess[9][9]

Definiert in Zeile 79 der Datei gui_sudoku.c.

int mode

Definiert in Zeile 65 der Datei gui_sudoku.c.

int padLineDistance

Definiert in Zeile 70 der Datei gui_sudoku.c.

int running = 0
static

Definiert in Zeile 34 der Datei gui_sudoku.c.

int user[9][9]

Definiert in Zeile 76 der Datei gui_sudoku.c.

int xFieldBorder

Definiert in Zeile 66 der Datei gui_sudoku.c.

int xMenuPos

Definiert in Zeile 61 der Datei gui_sudoku.c.

int xPadStart

Definiert in Zeile 70 der Datei gui_sudoku.c.

int xPos

Definiert in Zeile 61 der Datei gui_sudoku.c.

int xPosOld

Definiert in Zeile 62 der Datei gui_sudoku.c.

int xPosPad

Definiert in Zeile 71 der Datei gui_sudoku.c.

int yFieldBorder

Definiert in Zeile 67 der Datei gui_sudoku.c.

int yPadStart

Definiert in Zeile 70 der Datei gui_sudoku.c.

int yPos

Definiert in Zeile 61 der Datei gui_sudoku.c.

int yPosOld

Definiert in Zeile 62 der Datei gui_sudoku.c.

int yPosPad

Definiert in Zeile 71 der Datei gui_sudoku.c.