Sudoku Solver using C/C++

Hey guys, today I am posting the code of one of my favorite project which I did when I was in first year of engineering. Hope you guys like it.





Here's the code, enjoy coding.

/*
Project: Sudoku Solver using C/C++
Programmer: Ashok Kumar Shrestha
*/
#include<graphics.h>
#include<conio.h>
#include<dos.h>
#include<process.h>
#include<iostream.h>
#include<stdio.h>
int mat1[9][9];  //for printing given problem

//////////////////graphics initialization///////////////////////////
union REGS i, o;
struct SREGS s;
int initmouse()
{
   i.x.ax = 0;
   int86(0X33,&i,&o);
   return ( o.x.ax );
}

void showmouseptr()
{
   i.x.ax = 1;
   int86(0X33,&i,&o);
}

void getmousepos(int *button, int *x, int *y)
{
   i.x.ax = 3;
   int86(0X33,&i,&o);

   *button = o.x.bx;
   *x = o.x.cx;
   *y = o.x.dx;
}
void hidemouseptr()
{
i.x.ax=2;
int86(0x33,&i,&o);
}
restrictmouseptr(int x1,int y1,int x2,int y2)
{
i.x.ax=7;
i.x.cx=x1;
i.x.dx=x2;
int86(0x33,&i,&o);
i.x.ax=8;
i.x.cx=y1;
i.x.dx=y2;
int86(0x33,&i,&o);
return 0;
}

//////////////////subroutines////////////////////////////////////////
void display(int mat[10][9][9]);
void add_num(int mat[10][9][9],int x,int y);
void process_data(int dat_mat[10][9][9]);
void pair_checked1(int dat_mat[10][9][9]);
void get_mat();
void grid();
int check_num(int mat[10][9][9]);

int mat[9][9]={{0,0,0,0,0,0,2,0,9}, //pro
      {0,0,0,0,2,0,0,3,0},
      {8,4,0,0,0,1,0,0,0},
      {2,0,0,0,0,9,0,8,6},
      {0,0,5,8,0,0,0,0,0},
      {6,0,0,0,0,7,9,4,0},
      {0,0,0,0,0,0,6,0,8},
      {0,2,0,0,0,0,0,7,0},
      {1,0,0,0,3,5,0,0,0}};

int check_num(int mat[10][9][9])  ////check if wrong no is placed
{
int i,j;
for(i=0;i<9;i++)
{
int ck_num[9]={0};
for(j=0;j<9;j++)
{ if(mat[0][i][j])
{
ck_num[mat[0][i][j]-1]++;
if(ck_num[mat[0][i][j]-1]>1)
{ return 0;}
}
}
}

for(i=0;i<9;i++)
{
int ck_num[9]={0};
for(j=0;j<9;j++)
{ if(mat[0][j][i])
{
ck_num[mat[0][j][i]-1]++;
if(ck_num[mat[0][j][i]-1]>1)
{ return 0;}
}
}
}

for(i=0;i<9;i++)
{
int ck_num[9]={0};
int x1=(i/3)*3,y1=(i%3)*3,x,y;
for(x=x1;x<x1+3;x++)
{
  for(y=y1;y<y1+3;y++)
  {
if(mat[0][x][y])
{
ck_num[mat[0][x][y]-1]++;
if(ck_num[mat[0][x][y]-1]>1)
{ return 0;}
}
  }
}
}
return 1;
}
void find(int mat[10][9][9]) ////find if we got solution
{
int i,j,k=0;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{ if(mat[0][i][j]) k++; }
if(check_num(mat)&&k==81)
{ cleardevice();
grid();
get_mat();
}
}


int c1(int mat[10][9][9])      ////count no. in dat_mat[0][i][j]
{
int i,j,co=0;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{     if(mat[0][i][j]) co++;   }
if(co==81) return 1;
return 0;
}

void guess1(int dat_mat[10][9][9])   //guess the remaining number.
{
if(!check_num(dat_mat))
return;

int i,j,k,x,y,x1,y1;
int dat[10][9][9]={0};
for(i=0;i<10;i++)
for(j=0;j<9;j++)
for(k=0;k<9;k++)
dat[i][j][k]=dat_mat[i][j][k];

for(i=1;i<10;i++)
{
for(j=0;j<9;j++)
{
x1=(j/3)*3; y1=(j%3)*3;
int count=0,ges[9]={0};
for(x=x1;x<x1+3;x++)
for(y=y1;y<y1+3;y++)
if(!dat_mat[i][x][y])
{ ges[count++]=x*10+y;}
if(count==2)
{
for(k=0;k<count;k++)
{     dat_mat[i][ges[k]/10][ges[k]%10]=1;
dat_mat[0][ges[k]/10][ges[k]%10]=i;
process_data(dat_mat);
find(dat_mat);
for(int z=0;z<9;z++)
pair_checked1(dat_mat);
process_data(dat_mat);
find(dat_mat);
pair_checked1(dat_mat);
process_data(dat_mat);
find(dat_mat);
if(!c1(dat_mat))
{ guess1(dat_mat);
}
else
{
dat[i][ges[k]/10][ges[k]%10]=0;
}
for(int i1=0;i1<10;i1++)
for(int j1=0;j1<9;j1++)
{
   for(int k1=0;k1<9;k1++)
dat_mat[i1][j1][k1]=dat[i1][j1][k1];
}
   }
}

}
}
}


void pair_checked1(int dat_mat[10][9][9])
{
//ckecking for pairs

int i,j,k,adx,ady,p,nums,count,n,cnt;

  for(i=0;i<9;i++)
  {
  {
   cnt=0;
   int x1=(i/3)*3, y1=(i%3)*3;
//finding remaining elements in box
int rbox[9]={0};
for(int x=x1;x<x1+3;x++)
for(int y=y1;y<y1+3;y++)
if(dat_mat[0][x][y])
{       int val=dat_mat[0][x][y]  ;
rbox[val-1]=val; //elements present in box are filled with 2
}
//assining remaininig element of box to grp[1][]
int grp[3][9]={0},count=0;
for(j=0;j<9;j++)
if(!rbox[j])
{ grp[1][cnt++]=j+1;    }
   for(j=0;j<cnt-1;j++)
   {
    if(!grp[2][j])
    {
     nums=1;
     for(k=j+1;k<cnt;k++)
     {
       count=0;
       n=0;
       if(!grp[2][k])
       {
       for(n=0;n<9;n++)
       {
adx=i/3*3+(n/3);
ady=i%3*3+(n%3);
if(dat_mat[grp[1][j]][adx][ady]!=dat_mat[grp[1][k]][adx][ady])
break;
if(!dat_mat[grp[1][j]][adx][ady])
{
grp[0][count]=adx*10+ady;
count++;
}
       }
       if(n>8)
       {
grp[2][k]=j+1;
nums++;
if(nums==count)
{
grp[2][j]=j+1;
for(p=0;p<cnt;p++)
{
 if(grp[2][p]-j-1)
   for(n=0;n<count;n++)
dat_mat[grp[1][p]][grp[0][n]/10][grp[0][n]%10]=1;

}
}
       }
      }
     }
     grp[2][j]=j+1;
    }
   }
  }
 }
 process_data(dat_mat);
 find(dat_mat);
}

void solve()
{
int dat_mat[10][9][9]={0};
int x,y,i,j,k,l,val,c2=0,c1=0;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{ if(mat[i][j])
{ mat1[i][j]=mat[i][j];
c2++;
}
}
}
//this initializes 3d mat ie. 0 floor contains mat value n remaining floor pos where val can be.
for(x=0;x<9;x++)
{
for(y=0;y<9;y++)
{
if(mat[x][y])
{
val=mat[x][y];
dat_mat[0][x][y]=val;//dat_mat[0][x][y] represents at 0 floor at x,y postion value is stored.
for(k=0;k<9;k++)//this is to initialize all top floor(1 to 9),row n col of particular val(floor) to not possible.
{
dat_mat[k+1][x][y]=1; //here 1 represents that position can not be filled with any number.
dat_mat[val][x][k]=1;//col to np
dat_mat[val][k][y]=1;//row to np
}
int i1=(x/3)*3, j1=(y/3)*3;
for(i=i1;i<i1+3;i++)
for(j=j1;j<j1+3;j++)
{ dat_mat[val][i][j]=1;}//box to np
dat_mat[val][x][y]=2;//in this position one value is filled.
}
}
}

do                   //loop to continues if process is generating new no.
{       c1=c2;
c2=0;
process_data(dat_mat);   //calls to process data.
for(i=0;i<9;i++)
pair_checked1(dat_mat);
process_data(dat_mat);
find(dat_mat);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{ if(mat[i][j]) c2++; }


}while(c1<c2);
guess1(dat_mat);
display(dat_mat);
}

//add the number to 3d array after calculation at pos x,y
void add_num(int dat_mat[10][9][9],int x,int y)
{
if(mat[x][y])
{
int val=mat[x][y];

for(int k=0;k<9;k++)//this is to initialize all top floor(1 to 9),row n col of particular val(floor) to not possible.
{
dat_mat[k+1][x][y]=1; //here 1 represents that position can not be filled with any number.
dat_mat[val][x][k]=1;//col to np
dat_mat[val][k][y]=1;//row to np
}
int i1=(x/3)*3, j1=(y/3)*3;
for(int i=i1;i<i1+3;i++)
for(int j=j1;j<j1+3;j++)
{ dat_mat[val][i][j]=1;}//box to np
dat_mat[0][x][y]=val;//dat_mat[0][x][y] represents at 0 floor at x,y postion value is stored.
dat_mat[val][x][y]=2;//in this position one value is filled.
}
}
//display content of 3d array
void display(int dat_mat[10][9][9])
{
int i,j,k;
for(i=0;i<10;i++)
{
clrscr();
int cnt=0;
cout<<"floor no. :  "<<i<<"\n\n";
for(j=0;j<9;j++)
{       if(j%3==0) cout<<"\n";
for(k=0;k<9;k++)
{       if(k%3==0) cout<<"   ";
cout<<"   "<<dat_mat[i][j][k];
if(dat_mat[i][j][k]) cnt++;
}
cout<<"\n\n";
}
cout<<cnt;
      if(getch()=='d') exit(0);
}
}
void process_data(int dat_mat[10][9][9])
{
int i,j,x,y;
//process the data, checks for single pos in row,col n box.

int numc,numr;
for(i=1;i<10;i++)
{
for(x=0;x<9;x++)
{
int countc=0;//countr=0;
for(y=0;y<9;y++)
{
if(!dat_mat[i][x][y])//checks single col
{
countc++;
numc=y;
}
}
if(countc==1)
{
mat[x][numc]=i;
add_num(dat_mat,x,numc);
}

}
}

//checks single box

for(i=1;i<10;i++)
{
for(j=0;j<9;j++)
{

int countb=0,numb;
int x1=(j/3)*3, y1=(j%3)*3;
for(x=x1;x<x1+3;x++)
{
for(y=y1;y<y1+3;y++)
{
if(dat_mat[i][x][y]==2||countb>1)
break;
if(!dat_mat[i][x][y])
{
countb++;
numb=x*10+y;
}

}
}
if(countb==1)
{
mat[numb/10][numb%10]=i;
add_num(dat_mat,numb/10,numb%10);
}

}
}
}
int getkey()
{
union REGS i,o;
while(!kbhit())
;
i.h.ah=0;
int86(22,&i,&o);
return(o.h.ah);
}

void grid()
{
int cl=9,cg=15,i,j;//cl-line color,cg-background color
cleardevice();
int cx,cy,box_siz=40;

cx=getmaxx()/2;
cy=getmaxy()/2;
int x1,y1;
y1=cy-(9*box_siz)/2;
x1=cx-(9*box_siz)/2;

setfillstyle(1,cl);//outermost rect.
bar(x1-5,y1-40,x1+9*box_siz+5,y1+9*box_siz+50);

setfillstyle(1,cg);//square
bar(x1,y1,x1+9*box_siz,y1+9*box_siz);

setfillstyle(1,3);//option box
bar(x1,y1+9*box_siz+15,x1+9*box_siz,y1+9*box_siz+45);

setcolor(10);  //option box highlighter
line(x1,y1+9*box_siz+15,x1+9*box_siz,y1+9*box_siz+15);
line(x1,y1+9*box_siz+15,x1,y1+9*box_siz+45);
line(x1+3*box_siz+6,y1+9*box_siz+15,x1+3*box_siz+6,y1+9*box_siz+45);
line(x1+6*box_siz+6,y1+9*box_siz+15,x1+6*box_siz+6,y1+9*box_siz+45);

setfillstyle(1,cl);//separates boxes
bar(x1+3*box_siz,y1,x1+3*box_siz+5,y1+9*box_siz+50);
bar(x1+6*box_siz,y1,x1+6*box_siz+5,y1+9*box_siz+50);
bar(x1,y1+3*box_siz,x1+9*box_siz,y1+3*box_siz+5);
bar(x1,y1+6*box_siz,x1+9*box_siz,y1+6*box_siz+5);

setcolor(cl);
for(i=1;i<9;i++)
{
line(x1+i*40,y1,x1+i*40,y1+9*box_siz);
line(x1,y1+i*40,x1+9*box_siz,y1+i*40);
}
setcolor(0);
line(x1-5,y1+9*box_siz+8,x1+9*box_siz+5,y1+9*box_siz+8);

setcolor(14);
settextstyle(4,0,4);
outtextxy(x1+15,y1-40,"S U D O K U  Solver");

setcolor(14);
settextstyle(2,0,8);
outtextxy(x1+20,y1+9*box_siz+15,"Solve");
outtextxy(x1+160,y1+9*box_siz+15,"New");
outtextxy(x1+280,y1+9*box_siz+15,"Quit");

for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{       if(mat[j][i])
{
int x2=x1+i*box_siz+15;
int y2=y1+j*box_siz ;
char array[40];
if(!mat1[j][i])
setcolor(2);
else
setcolor(1);
settextstyle(3,0,4);
hidemouseptr();
moveto(x2,y2);

sprintf(array,"%d",mat[j][i]);
outtext(array);
showmouseptr();
}
}
}
}
void main()
{
int gd = DETECT, gm;
initgraph(&gd,&gm,"..\\BGI");
get_mat();
}
void get_mat()   //gets value of mat[9][9] through mouse n keyboard
{
int  button=-1, x=0, y=0;
int box_siz=40;
char array[40];
settextstyle(GOTHIC_FONT,0,2);
int i,j,k,l;
grid();
int cx,cy;

cx=getmaxx()/2;
cy=getmaxy()/2;
int x1,y1;
y1=cy-(9*box_siz)/2;
x1=cx-(9*box_siz)/2;
while(1)
{
restrictmouseptr(136,60,500,460);
showmouseptr();
getmousepos(&button,&x,&y);
gotoxy(1,10);
printf("x%3d, y%3d",x,y);
int row,col,opt_box;
if(button==1)
{
if(y<(y1+9*box_siz))
{
col=(x-x1)/box_siz;
row=(y-y1)/box_siz;
setcolor(1);
settextstyle(3,0,4);
int x2=x1+col*box_siz+15;
int y2=y1+row*box_siz ;
gotoxy(1,15);
printf("r%3d, c%3d",row,col);
int val=getkey()-1;
hidemouseptr();
if(mat[row][col])
{
setfillstyle(1,15);
bar(x1+col*box_siz+5,y1+row*box_siz+5,x1+(col+1)*box_siz-5,y1+(row+1)*box_siz-5);
}

if(val&&val<10)
{ mat[row][col]=val;
moveto(x2,y2);
sprintf(array,"%d",val);
outtext(array);
}
showmouseptr();
}
else
{
opt_box=(x-x1)/(3*box_siz)+1;
gotoxy(1,20);
printf("box=%2d",opt_box);
switch(opt_box)
{
case 1:
gotoxy(1,1);
for(i=0;i<9;i++)
{ for(j=0;j<9;j++)
{ printf("%d",mat[i][j]); }
printf("\n");
}
solve();

break;
case 2:
for(i=0;i<9;i++)
{ for(j=0;j<9;j++)
{ mat[i][j]=0;
mat1[i][j]=0;
}
}
grid();
break;
case 3:
delay(126);
exit(0);
}
}
button=-1;
}
else if(button==2)
{
button=-1;
delay(200);
exit(1);
}
else
button=-1;
}
}




























Comments

Popular posts from this blog

Wizard Quiz: Privacy Policy

Sorting Hat: Privacy Policy

mTranslator