Source Code (Use browser search to find items of interest.)
Class Index
ksame'StoneField (./kdegames/ksame/StoneField.h:54)
class StoneField {
friend StoneFieldState;
friend StoneWidget;
private:
int sizex;
int sizey;
int maxstone;
struct Stone *field;
int colors;
unsigned int board;
unsigned int score;
int gameover;
int marked;
KRandomSequence random;
QList<StoneFieldState> *undolist;
public:
StoneField(int width=15,int height=10,
int colors=3,unsigned int board=0,
bool undoenabled=true);
~StoneField();
int width();
int height();
void newGame(unsigned int board,int colors);
void reset();
int mark(int x,int y,bool force=false);
void unmark();
int remove(int x,int y,bool force=false);
int undo(int count=1);
bool isGameover();
int getBoard();
int getScore();
int getColors();
int getMarked();
protected:
int getFieldSize();
struct Stone *getField();
int map(int x,int y);
void mark(int index,unsigned char color);
};
ksame'StoneField::StoneField() (./kdegames/ksame/StoneField.cpp:55)
StoneField::StoneField(int width, int height,
int colors,unsigned int board,
bool undoenabled) {
ASSERT(width>0);
ASSERT(height>0);
if (undoenabled) undolist=new QList<StoneFieldState>;
else undolist=0;
sizex=width;
sizey=height;
maxstone=sizex*sizey;
field=new Stone[maxstone];
newGame(board,colors);
}
ksame'StoneField::~StoneField() (./kdegames/ksame/StoneField.cpp:71)
StoneField::~StoneField() {
delete[] field;
if (undolist) delete undolist;
debug("~StoneField\n");
}
int
ksame'StoneField::width() (./kdegames/ksame/StoneField.cpp:78)
StoneField::width() {
return sizex;
}
int
ksame'StoneField::height() (./kdegames/ksame/StoneField.cpp:83)
StoneField::height() {
return sizey;
}
void
ksame'StoneField::newGame() (./kdegames/ksame/StoneField.cpp:88)
StoneField::newGame(unsigned int board,int colors) {
debug("StoneField::newgame board %i colors %i",board,colors);
if (colors<1) colors=3;
if (colors>7) colors=7;
this->colors=colors;
this->board=board;
reset();
}
void
ksame'StoneField::reset() (./kdegames/ksame/StoneField.cpp:98)
StoneField::reset() {
random.setSeed(board);
Stone *stone=field;
for (int i=0;i<maxstone;i++,stone++) {
stone->color=1+random.getLong(colors);
stone->marked=false;
stone->changed=true;
}
gameover=-1;
score=0;
marked=0;
if (undolist) {
undolist->setAutoDelete(true);
undolist->clear();
}
int c[7];
int j;
for (j=0;j<7;j++) c[j]=0;
for (j=0,stone=field;j<maxstone;j++,stone++) {
c[stone->color]++;
}
debug("red %i",c[1]);
debug("blue %i",c[2]);
debug("yellow %i",c[3]);
debug("green %i",c[4]);
}
int
ksame'StoneField::map() (./kdegames/ksame/StoneField.cpp:133)
StoneField::map(int x,int y) {
if (x<0||y<0||x>=sizex||y>=sizey)
return -1;
return x+y*sizex;
}
int
ksame'StoneField::mark() (./kdegames/ksame/StoneField.cpp:140)
StoneField::mark(int x,int y,bool force) {
int index=map(x,y);
if (index<0) {
unmark();
return 0;
}
if (field[index].marked) return -1;
unmark();
mark(index,field[index].color);
if (marked==1&&!force) {
field[index].marked=false;
marked=0;
}
return marked;
}
void
ksame'StoneField::mark() (./kdegames/ksame/StoneField.cpp:161)
StoneField::mark(int index,unsigned char color) {
if ( index<0 || index>=maxstone ) return;
Stone &stone=field[index];
if (stone.marked) return;
if (!stone.color || stone.color!=color) return;
stone.changed=true;
stone.marked=true;
marked++;
// mark left
if ((index%sizex)!=0) mark(index-1,color);
// mark right
if (((index+1)%sizex)!=0) mark(index+1,color);
// mark upward
if (index>=sizex) mark(index-sizex,color);
// mark downward
if (index<(sizex-1)*sizey) mark(index+sizex,color);
}
void
ksame'StoneField::unmark() (./kdegames/ksame/StoneField.cpp:185)
StoneField::unmark() {
if (!marked) return;
Stone *stone=field;
for (int i=0;i<maxstone;i++,stone++) {
stone->marked=false;
stone->changed=true;
}
marked=0;
}
int
ksame'StoneField::remove() (./kdegames/ksame/StoneField.cpp:197)
StoneField::remove(int x,int y,bool force) {
int index=map(x,y);
if (index<0) return 0;
if (!field[index].marked) {
mark(x,y,force);
}
if (!marked) return 0;
// remove a single stone??
if (marked==1&&!force) return 0;
// add current field to undolist
if (undolist)
undolist->append(new StoneFieldState(*this));
// increase score
if (marked>2)
score+=(marked-2)*(marked-2);
// remove marked stones
Stone *stone=field;
for (int i=0;i<maxstone;i++,stone++) {
if (stone->marked) {
stone->color=0;
stone->changed=true;
stone->marked=false;
}
}
int removed=marked;
marked=0;
// collapse field
int col,j,i1,i2;
for (col=0;col<sizex;col++) {
i1=col+maxstone-sizex;
while ( i1>=0 && field[i1].color ) i1-=sizex;
i2=i1;
while (i2>=0) {
while ( i2>=0 && !field[i2].color ) i2-=sizex;
while ( i2>=0 && field[i2].color ) {
field[i1].color=field[i2].color;
field[i1].changed=true;
field[i2].color=0;
field[i2].changed=true;
i1-=sizex;
i2-=sizex;
}
}
}
for (col=0;col<sizex;col++) {
i1=col+maxstone-sizex;
while ( i1< maxstone && field[i1].color ) i1++;
i2=i1;
while (i2<maxstone) {
while ( i2<maxstone && !field[i2].color) i2++;
while ( i2<maxstone && field[i2].color ) {
for (j=0;j<maxstone;j+=sizex) {
field[i1-j].color=field[i2-j].color;
field[i1-j].changed=true;
field[i2-j].color=0;
field[i2-j].changed=true;
}
i1++;
i2++;
}
}
}
// add a bonus, if field is empty
if (!field[maxstone-sizex].color) score+=1000;
// gameover is undefined
gameover=-1;
return removed;
}
int
ksame'StoneField::undo() (./kdegames/ksame/StoneField.cpp:279)
StoneField::undo(int count) {
if (!undolist||count<=0||undolist->isEmpty()) return 0;
int undocount=1;
StoneFieldState *state=0;
undolist->setAutoDelete(true);
while (--count>0) {
if (undolist->count()==1) break;
undolist->removeLast();
undocount++;
}
state=undolist->getLast();
ASSERT(state);
state->restore();
undolist->removeLast();
return undocount;
}
bool
ksame'StoneField::isGameover() (./kdegames/ksame/StoneField.cpp:297)
StoneField::isGameover() {
register int i=maxstone-1;;
register unsigned char color;
if (gameover>=0) return (bool)gameover;
// debug("-->gameover");
while (i>=0) {
// debug ("%i %i",i,field[i].color);
// ignore empty fields
while ( i>=0 && field[i].color==0 ) i--;
// Wenn Stein gefunden,
// dann die Nachbarn auf gleiche Farbe pruefen.
while ( i>=0 && (color=field[i].color) ) {
// check left
if ( (i%sizex)!=0 && field[i-1].color==color)
goto check_gameover;
// check upward
if ( i>=sizex && field[i-sizex].color==color)
goto check_gameover;
i--;
}
}
check_gameover:
gameover=(i<0);
// debug("<--gameover");
return (bool)gameover;
}
int
ksame'StoneField::getBoard() (./kdegames/ksame/StoneField.cpp:329)
StoneField::getBoard() {
return board;
}
int
ksame'StoneField::getScore() (./kdegames/ksame/StoneField.cpp:334)
StoneField::getScore() {
return score;
}
int
ksame'StoneField::getColors() (./kdegames/ksame/StoneField.cpp:339)
StoneField::getColors() {
return colors;
}
int
ksame'StoneField::getMarked() (./kdegames/ksame/StoneField.cpp:344)
StoneField::getMarked() {
return marked;
}
int
ksame'StoneField::getFieldSize() (./kdegames/ksame/StoneField.cpp:349)
StoneField::getFieldSize() {
return maxstone;
}
struct Stone *
StoneField::getField() {
return field;
}