Tein sudokuja ratkovan ohjelman, joka toistaiseksi vain poissulkee mahdottomat numerot mitä yksinkertaisimmalla algoritmilla; päädyin jonkinlaiseen keko-virheeseen. Kun kopioin sudokun toiseen ja deletoin sen, poistuvat ilmeisesti molemmat sudokut, vaikka koodissa mielestäni teen uudelle sudokulle uuden taulukon.
Tuntuu hieman tyhmältä lähettää tänne kokonainen ohjelma, mutta jos lähetän vain osan, saattaa yleiskuvan hankkiminen olla vaikeaa.
Jos haluatte, saatte paljastaa mikä tuossa on vikana. Ongelma on käsittääkseni sudoku::solvestep-funktiossa.
#include <iostream.h> // for output, in case you wanna see what this program actually did
#include <stdlib.h>
#include <time.h>
#include <math.h>
class sdf // stores which numbers the square could hold in the sudoku
{
private:
bool * data; // swntschits
int howmany; // how many numbers in use
public:
sdf()
{
data=new bool[0]; // initialize as empty
howmany=0; // size zero
}
void makemysize(int gs)
{
howmany=gs; // make "this"'s size gs
delete [] data;
data=new bool[howmany];
for (int i=0;i<howmany;i++)
data[i]=false;
}
int iam()
{
int count=0;
int whichone=-1;
for(int i=0;i<howmany;i++)
if (data[i])
{
count++;
whichone=i;
}
if (count==1)
return whichone;
else
return -1;
}
void deletenumber(int i)
{
if (this->iam()==-1&&i>=0)
data[i]=false;
}
void deletenumbers(sdf * id)
{
if (id->howmany!=this->howmany) return;
if (this->iam()>=0) return;
for(int i=0;i<id->howmany;i++)
if (id->data[i]) this->data[i]=false;
}
void putnumber(int i)
{
if (i>=0) data[i]=true;
}
signed char operator=(signed char n)
{
for(int i=0;i<howmany;i++)
data[i]=(n>=0?false:true);
if (n>=0) data[n]=true;
return n;
}
sdf operator=(sdf s)
{
delete [] data;
howmany=s.howmany;
data=new bool[howmany];
for(int i=0;i<howmany;i++)
data[i]=s.data[i];
return sdf();
}
friend bool compare(sdf s1, sdf s2);
~sdf()
{
delete [] data;
}
};
class sudoku
{
private:
sdf * data; // currently known stuff in the sudoku
int xsize; // size of the whole sudoku
int ysize;
int xframe; // size of one frame in this sudoku
int yframe;
int hmnumbers; // how many numbers are there in the sudoku (like 0-8 or 0-100...)
public:
sudoku(signed char * gdata,int gxs,int gys,int gxf,int gyf,int ghmn)
{
xsize=gxs,ysize=gys,xframe=gxf,yframe=gyf,hmnumbers=ghmn; // set values
data=new sdf [xsize*ysize]; // initialize "data"
// make all sdf:s the right size
for(int ix=0;ix<xsize;ix++)
for(int iy=0;iy<ysize;iy++)
{
data[ix+iy*xsize].makemysize(ghmn);
}
// put the right data in "data"
for(ix=0;ix<xsize;ix++)
for(int iy=0;iy<ysize;iy++)
{
data[ix+iy*xsize]=gdata[ix+iy*xsize];
}
}
sudoku(sudoku * other)
{
xsize=other->xsize,ysize=other->ysize,xframe=other->xframe,
yframe=other->yframe,hmnumbers=other->hmnumbers; // set values
data=new sdf [xsize*ysize]; // initialize "data"
// make all sdf:s the right size
for(int ix=0;ix<xsize;ix++)
for(int iy=0;iy<ysize;iy++)
{
data[ix+iy*xsize].makemysize(hmnumbers);
}
// put the right data in "data"
for(ix=0;ix<xsize;ix++)
for(int iy=0;iy<ysize;iy++)
{
data[ix+iy*xsize]=other->data[ix+iy*xsize];
}
}
bool operator==(sudoku * other)
{
if (xsize==other->xsize&&ysize==other->ysize&&
xframe==other->xframe&&yframe==other->yframe&&
hmnumbers==other->hmnumbers)
{
bool right=true;
for (int ix=0;ix<this->xsize;ix++)
for (int iy=0;iy<this->ysize;iy++)
if (compare(this->data[ix+iy*this->xsize],
other->data[ix+iy*this->xsize]))
right=false;
return right;
}
else
return false;
}
void solve()
{
//while (!solvestep());
for (int i=50;i<1;i++)
solvestep();
}
bool solvestep()
{
//kun old luodaan usemman kerran, kaatuu ja antaa jonkinlaisen
//kekovirheen, ilmeisesti vika on alustuksessa
sudoku old=sudoku(this);
for(int i=0;i<xsize;i++)
solvecolumn(i);
for(i=0;i<ysize;i++)
solverow(i);
for(int ix=0;ix<xsize/xframe;ix++)
for(int iy=0;iy<ysize/yframe;iy++)
solveframe(ix,iy);
return true;
}
void solvecolumn(int which)
{
sdf already;
already.makemysize(hmnumbers);
for(int i=0;i<ysize;i++)
already.putnumber(data[which+i*xsize].iam());
for(i=0;i<ysize;i++)
data[which+i*xsize].deletenumbers(&already);
}
void solverow(int which)
{
sdf already;
already.makemysize(hmnumbers);
for(int i=0;i<xsize;i++)
already.putnumber(data[i+which*xsize].iam());
for(i=0;i<xsize;i++)
data[i+which*xsize].deletenumbers(&already);
}
void solveframe(int whichx,int whichy)
{
sdf already;
already.makemysize(hmnumbers);
for(int ix=0;ix<xframe;ix++)
for(int iy=0;iy<yframe;iy++)
{
int x=(ix+whichx*xframe);
int y=(iy+whichy*yframe);
already.putnumber(data[x+y*xsize].iam());
}
for(ix=0;ix<xframe;ix++)
for(int iy=0;iy<yframe;iy++)
{
int x=(ix+whichx*xframe);
int y=(iy+whichy*yframe);
data[x+y*xsize].deletenumbers(&already);
}
}
friend void sudoprint(sudoku * s);
~sudoku()
{
delete [] data;
}
};
void sudoprint(sudoku * s)
{
for(int ix=0;ix<s->xsize;ix++)
{
for(int iy=0;iy<s->ysize;iy++)
{
int molokki=s->data[ix*(s->ysize)+iy].iam();
if (molokki>=0)
cout<<molokki;
else if (molokki==-1)
cout<<'-';
}
cout<<"\n";
}
}
bool compare(sdf s1, sdf s2)
{
if (s1.howmany!=s2.howmany) return false;
for(int i=0;i<s1.howmany;i++)
if (s1.data[i]!=s2.data[i]) return false;
return true;
}
void main()
{
srand(time(NULL));
cout<<"\nNot Properly Working Sudoku Solver 1.1\n";
int number=0;
do
{
cout<<"Set width and height. ";
cin>>number;
cout<<"\n";
} while (number<=0);
int number2=0;
do
{
cout<<"Set the squareroot of the amount of the frames lol! ";
cin>>number2;
cout<<"\n";
} while (number2<=0);
cout<<"Tell it.\n";
signed char * test=new signed char[number*number];
char * row=new char[number+1];
for (int i=0;i<number;i++)
{
cin>>row;
for (int ii=0;ii<number;ii++)
{
if (row[ii]>=49&&row[ii]<=57)
test[ii+i*number]=row[ii]-49;
else if (row[ii]>=65&&row[ii]<=90)
test[ii+i*number]=row[ii]-55;
else if (row[ii]>=97&&row[ii]<=122)
test[ii+i*number]=row[ii]-61;
else
test[ii+i*number]=-1;
}
}
delete [] row;
for (i=0;i<number*number;i++)
if (test[i]>=number||test[i]<0) test[i]=-1;
sudoku stest(test,number,number,number2,number2,number);
sudoprint(&stest);
cout<<"\n";
delete [] test;
stest.solve();
sudoprint(&stest);
}
}Toi sdf näyttää vähän oudolta. Onko oikein tehdä
data=new bool[0]; // initialize as empty
...ja sitten jatkossa deletoida se ja luoda yksi isompi? Tuossa pitäisi varmaan käyttää jotain stl-juttuja. Vaikka vector.
Ei kai tämä ole edes oikein:
sudoku old=sudoku(this);
Eikös se näin olisi:
sudoku old(this);
Jutti huomautti myös oikein. Deleteä voi kyllä käyttää NULL-pointteriinkin, sitä ei tarvitse pelätä. Vector voisi kuitenkin olla paras ratkaisu.
Aihe on jo aika vanha, joten et voi enää vastata siihen.