Advertisement
thecplusplusguy

Sudoku solver with GTK+

Dec 2nd, 2011
2,347
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.90 KB | None | 0 0
  1. //http://www.youtube.com/user/thecplusplusguy
  2. #include <iostream>
  3. #include <fstream>
  4. #include <cmath>
  5. #include <gtk/gtk.h>
  6. #include <cstdlib>
  7. #include <cstring>
  8. using namespace std;
  9. void initGUI(int*,char***);
  10. bool sor(int s,int o,int n);
  11. bool oszlop(int s,int o,int n);
  12. bool negyzet(int s,int o,int n);
  13. void solve();
  14. static int a[9][9];
  15. static GtkWidget* wid[9][9],*window;
  16. void open_dialog();
  17. static void menu_event(GtkWidget*,gpointer);
  18.  
  19. struct mypair{
  20.     mypair(int i,int j) : x(i),y(j){};
  21.     int x,y;
  22. };
  23.  
  24.  
  25. void check_number(GtkWidget* entry,mypair* data);
  26.  
  27.  
  28.  
  29. int main(int argc,char* argv[])
  30. {
  31.     for(int i=0;i<9;i++)
  32.         for(int j=0;j<9;j++)
  33.             a[i][j]=0;
  34.     initGUI(&argc,&argv);
  35.     return 0;
  36. }
  37.  
  38. bool sor(int s,int o,int n)
  39. {
  40.     for(int g=0;g<9;g++)
  41.     {
  42.  
  43.         if(a[s][g]==n)
  44.         {
  45.             return 0;
  46.         }  
  47.     }
  48.     return 1;
  49. }
  50. bool oszlop(int s,int o,int n)
  51. {
  52.     for(int g=0;g<9;g++)
  53.     {
  54.         if(a[g][o]==n)
  55.             return 0;
  56.     }
  57.     return 1;
  58. }
  59. bool negyzet(int s,int o,int n)
  60. {
  61.     int sor=ceil((s+1)/3.);
  62.     int oszlop=ceil((o+1)/3.);
  63.     for(int g=(sor-1)*3;g<((sor-1)*3+3);g++)
  64.         for(int h=(oszlop-1)*3;h<((oszlop-1)*3+3);h++)
  65.         {
  66.             if(a[g][h]==n)
  67.                 return 0;
  68.         }
  69.     return 1;
  70. }
  71.  
  72.  
  73.  
  74.  
  75. static void get_elements(GtkWidget* widget,gpointer data)
  76. {
  77.     for(int i=0;i<9;i++)
  78.     {
  79.         for(int j=0;j<9;j++)
  80.         {
  81.             a[i][j]=atoi(gtk_entry_get_text(GTK_ENTRY(wid[i][j])));
  82.         }
  83.     cout << endl;
  84.     }
  85.     solve();
  86. }
  87.  
  88.  
  89.  
  90.  
  91.  
  92. void initGUI(int* argc,char*** argv)
  93. {
  94.     const char* file[] = {"New","Open","Check","Exit"};
  95.     const char* help[] = {"About"};
  96.     gtk_init(argc,argv);
  97.     GtkWidget *vbox,*hbox,*separator,*button,*menu,*file_menu,*help_menu,*menu_bar;
  98.     vbox=gtk_vbox_new(0,0);
  99.     window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  100.     menu=gtk_menu_new();
  101.     menu_bar=gtk_menu_bar_new();
  102.     file_menu=gtk_menu_item_new_with_label("File");
  103.     help_menu=gtk_menu_item_new_with_label("Help");
  104.     for(int i=0;i<4;i++)
  105.     {
  106.         GtkWidget* menu_item=gtk_menu_item_new_with_label(file[i]);
  107.         gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
  108.         g_signal_connect(menu_item,"activate",G_CALLBACK(menu_event),window);
  109.     }
  110.     gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menu),menu);
  111.     gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),file_menu);
  112.     menu=gtk_menu_new();
  113.     for(int i=0;i<1;i++)
  114.     {
  115.         GtkWidget* menu_item=gtk_menu_item_new_with_label(help[i]);
  116.         gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
  117.         g_signal_connect(menu_item,"activate",G_CALLBACK(menu_event),window);
  118.     }
  119.     gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_menu),menu);
  120.     gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar),help_menu);
  121.     gtk_box_pack_start(GTK_BOX(vbox),menu_bar,0,0,0);
  122.     for(int i=0;i<9;i++)
  123.     {
  124.         hbox=gtk_hbox_new(0,0);
  125.         for(int j=0;j<9;j++)
  126.         {
  127.             wid[i][j]=gtk_entry_new();
  128.             g_signal_connect(wid[i][j],"activate",G_CALLBACK(check_number),NULL);
  129. //          gtk_entry_set_width_chars(GTK_ENTRY(wid[i][j]),1);
  130.             gtk_entry_set_max_length(GTK_ENTRY(wid[i][j]),1);
  131.             gtk_widget_set_size_request(wid[i][j],20,20);
  132.             gtk_box_pack_start(GTK_BOX(hbox),wid[i][j],0,0,0);
  133.             if((j+1)%3==0)
  134.             {
  135.                 separator=gtk_vseparator_new();
  136.                 gtk_box_pack_start(GTK_BOX(hbox),separator,0,0,0);
  137.             }
  138.         }
  139.         gtk_box_pack_start(GTK_BOX(vbox),hbox,0,0,0);
  140.         if((i+1)%3==0)
  141.         {
  142.             separator=gtk_hseparator_new();
  143.             gtk_box_pack_start(GTK_BOX(vbox),separator,0,0,0);
  144.         }
  145.     }
  146.     button=gtk_button_new_with_label("Solve the sudoku");
  147.     g_signal_connect(button,"clicked",G_CALLBACK(get_elements),NULL);
  148.     gtk_box_pack_start(GTK_BOX(vbox),button,0,0,0);
  149.     g_signal_connect(window,"delete-event",G_CALLBACK(gtk_main_quit),NULL);
  150.     gtk_container_add(GTK_CONTAINER(window),vbox);
  151.     gtk_widget_show_all(window);
  152.     gtk_main();
  153. }
  154.  
  155.  
  156. void solve()
  157. {
  158.     int un=0,s,o,tmp;
  159.     bool b=1;
  160.     char c[20];
  161.             for(int i=0;i<9;i++)
  162.                 for(int j=0;j<9;j++)
  163.                     if(!a[i][j])
  164.                         un++;
  165.     while(un && b)
  166.     {
  167.         b=0;
  168.         for(int i=0;i<9;i++)
  169.         {
  170.             for(int j=0;j<9;j++)
  171.             {
  172.                 if(a[i][j]!=0)
  173.                     continue;
  174.                 tmp=0;
  175.                 for(int x=1;x<10;x++)
  176.                 {
  177.                     if(sor(i,j,x) && oszlop(i,j,x) && negyzet(i,j,x))
  178.                     {
  179.                         if(tmp==0)
  180.                             tmp=x;
  181.                         else{
  182.                             tmp=0;
  183.                             break;
  184.                         }
  185.                     }  
  186.                 }
  187.             if(tmp!=0)
  188.             {
  189.                 a[i][j]=tmp;
  190.                 b=1;
  191.                 un--;
  192.             }
  193.         }
  194.     }
  195.     }
  196.     if(!b)
  197.         open_dialog();
  198.     else if(!un)
  199.         for(int i=0;i<9;i++)
  200.         {
  201.             for(int j=0;j<9;j++)
  202.             {
  203.                 char c[2];
  204.                 sprintf(c,"%d",a[i][j]);
  205.                 gtk_entry_set_text(GTK_ENTRY(wid[i][j]),c);
  206.             }
  207.         }
  208. }
  209.  
  210.  
  211. void open_dialog()
  212. {
  213.     GtkWidget* dialog,*label;
  214.     dialog=gtk_dialog_new_with_buttons("Error",GTK_WINDOW(window),GTK_DIALOG_MODAL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
  215.     label=gtk_label_new("I cannot solve the sudoku.\nYou may entered wrong numbers or the sudoku has no solution.\nIt is a passibility, that this sudoku has more possible solution, in case like that\nthis program will not work.");
  216.     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),label,0,0,0);
  217.     gtk_widget_show_all(dialog);
  218.     gtk_dialog_run(GTK_DIALOG(dialog));
  219.     gtk_widget_destroy(dialog);
  220. }
  221.  
  222.  
  223. void check_number(GtkWidget* entry,mypair* data)
  224. {
  225.     const gchar* c=gtk_entry_get_text(GTK_ENTRY(entry));
  226.     if(!isdigit(c[0]))
  227.     {
  228.                 GtkWidget* dialog,*label;
  229.                 dialog=gtk_dialog_new_with_buttons("Error",GTK_WINDOW(window),GTK_DIALOG_MODAL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
  230.                 label=gtk_label_new("This is not a number!");
  231.                 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),label,0,0,0);
  232.                 gtk_widget_show_all(dialog);
  233.                 gtk_dialog_run(GTK_DIALOG(dialog));
  234.                 gtk_widget_destroy(dialog);
  235.     }
  236. }
  237.  
  238. bool bad_number(int i)
  239. {
  240.     if(!(i>=0 && i<10))
  241.     {
  242.                 GtkWidget* dialog,*label;
  243.                 dialog=gtk_dialog_new_with_buttons("Error",GTK_WINDOW(window),GTK_DIALOG_MODAL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
  244.                 label=gtk_label_new("This number is bigger than 9 or less than 0\nOr maybe not event a number");
  245.                 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),label,0,0,0);
  246.                 gtk_widget_show_all(dialog);
  247.                 gtk_dialog_run(GTK_DIALOG(dialog));
  248.                 gtk_widget_destroy(dialog);
  249.                 return 1;
  250.     }
  251.     return 0;
  252. }
  253.  
  254.  
  255. static void menu_event(GtkWidget* menu_item,gpointer data)
  256. {
  257.     if(strcmp(gtk_menu_item_get_label(GTK_MENU_ITEM(menu_item)),"New")==0)
  258.     {
  259.         for(int i=0;i<9;i++)
  260.             for(int j=0;j<9;j++)
  261.             {
  262.                 a[i][j]=0;
  263.                 gtk_entry_set_text(GTK_ENTRY(wid[i][j]),"0");
  264.             }
  265.     }else if(strcmp(gtk_menu_item_get_label(GTK_MENU_ITEM(menu_item)),"Open")==0)
  266.     {
  267.         GtkWidget *dialog;
  268.         dialog=gtk_file_chooser_dialog_new("Choose the sudoku file",GTK_WINDOW(data),GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_OK,GTK_RESPONSE_OK,
  269.                                                                                                                                                                                                     GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,NULL);
  270.         gtk_widget_show_all(dialog);
  271.         gint resp=gtk_dialog_run(GTK_DIALOG(dialog));
  272.         if(resp==GTK_RESPONSE_OK)
  273.         {
  274.             ifstream in(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
  275.             for(int i=0;i<9;i++)
  276.             {
  277.                 for(int j=0;j<9;j++)
  278.                 {
  279.                     if(in.eof())
  280.                         break;
  281.                     in >> a[i][j];
  282.                     if(bad_number(a[i][j]))
  283.                         break;
  284.                     char c[2];
  285.                     sprintf(c,"%d",a[i][j]);
  286.                     gtk_entry_set_text(GTK_ENTRY(wid[i][j]),c);
  287.                 }
  288.             }
  289.             in.close();
  290.         }
  291.         gtk_widget_destroy(dialog);
  292.         solve();
  293.     }else if(strcmp(gtk_menu_item_get_label(GTK_MENU_ITEM(menu_item)),"Check")==0)
  294.     {
  295.         bool b=0;
  296.         for(int i=0;i<9;i++)
  297.             for(int j=0;j<9;j++)
  298.                 if(!(a[i][j]>=0 && a[i][j]<10 && sor(i,j,a[i][j]) && oszlop(i,j,a[i][j]) && negyzet(i,j,a[i][j])))
  299.                     b=1;
  300.         if(b)
  301.         {
  302.             GtkWidget* dialog,*label;
  303.             dialog=gtk_dialog_new_with_buttons("Error",GTK_WINDOW(window),GTK_DIALOG_MODAL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
  304.             label=gtk_label_new("The sudoku is not good.\nThere is the same numer in a row\ncoloumn or square or it's not a number");
  305.             gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),label,0,0,0);
  306.             gtk_widget_show_all(dialog);
  307.             gtk_dialog_run(GTK_DIALOG(dialog));
  308.             gtk_widget_destroy(dialog);
  309.         }
  310.     }else if(strcmp(gtk_menu_item_get_label(GTK_MENU_ITEM(menu_item)),"Exit")==0)
  311.     {
  312.         gtk_main_quit();
  313.     }
  314. }
  315.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement