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;
}