summaryrefslogtreecommitdiff
path: root/noncore/games/zsame/StoneField.cpp
Unidiff
Diffstat (limited to 'noncore/games/zsame/StoneField.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/zsame/StoneField.cpp4
1 files changed, 4 insertions, 0 deletions
diff --git a/noncore/games/zsame/StoneField.cpp b/noncore/games/zsame/StoneField.cpp
index 49d8eca..56e9dc5 100644
--- a/noncore/games/zsame/StoneField.cpp
+++ b/noncore/games/zsame/StoneField.cpp
@@ -163,228 +163,232 @@ void
163StoneField::mark(int index,unsigned char color) { 163StoneField::mark(int index,unsigned char color) {
164 if ( index<0 || index>=maxstone ) return; 164 if ( index<0 || index>=maxstone ) return;
165 165
166 Stone &stone=field[index]; 166 Stone &stone=field[index];
167 167
168 if (stone.marked) return; 168 if (stone.marked) return;
169 169
170 if (!stone.color || stone.color!=color) return; 170 if (!stone.color || stone.color!=color) return;
171 171
172 stone.changed=true; 172 stone.changed=true;
173 stone.marked=true; 173 stone.marked=true;
174 marked++; 174 marked++;
175 175
176 // mark left 176 // mark left
177 if ((index%sizex)!=0) mark(index-1,color); 177 if ((index%sizex)!=0) mark(index-1,color);
178 // mark right 178 // mark right
179 if (((index+1)%sizex)!=0) mark(index+1,color); 179 if (((index+1)%sizex)!=0) mark(index+1,color);
180 // mark upward 180 // mark upward
181 if (index>=sizex) mark(index-sizex,color); 181 if (index>=sizex) mark(index-sizex,color);
182 // mark downward 182 // mark downward
183 if (index<(sizex-1)*sizey) mark(index+sizex,color); 183 if (index<(sizex-1)*sizey) mark(index+sizex,color);
184} 184}
185 185
186void 186void
187StoneField::unmark() { 187StoneField::unmark() {
188 if (!marked) return; 188 if (!marked) return;
189 189
190 Stone *stone=field; 190 Stone *stone=field;
191 for (int i=0;i<maxstone;i++,stone++) { 191 for (int i=0;i<maxstone;i++,stone++) {
192 stone->marked=false; 192 stone->marked=false;
193 stone->changed=true; 193 stone->changed=true;
194 } 194 }
195 marked=0; 195 marked=0;
196} 196}
197 197
198int 198int
199StoneField::remove(int x,int y,bool force) { 199StoneField::remove(int x,int y,bool force) {
200 int index=map(x,y); 200 int index=map(x,y);
201 201
202 if (index<0) return 0; 202 if (index<0) return 0;
203 203
204 if (!field[index].marked) { 204 if (!field[index].marked) {
205 mark(x,y,force); 205 mark(x,y,force);
206 } 206 }
207 207
208 if (!marked) return 0; 208 if (!marked) return 0;
209 209
210 // remove a single stone?? 210 // remove a single stone??
211 if (marked==1&&!force) return 0; 211 if (marked==1&&!force) return 0;
212 212
213 // add current field to undolist 213 // add current field to undolist
214 if (undolist) 214 if (undolist)
215 undolist->append(new StoneFieldState(*this)); 215 undolist->append(new StoneFieldState(*this));
216 216
217 // increase score 217 // increase score
218 if (marked>2) 218 if (marked>2)
219 score+=(marked-2)*(marked-2); 219 score+=(marked-2)*(marked-2);
220 220
221 // remove marked stones 221 // remove marked stones
222 Stone *stone=field; 222 Stone *stone=field;
223 for (int i=0;i<maxstone;i++,stone++) { 223 for (int i=0;i<maxstone;i++,stone++) {
224 if (stone->marked) { 224 if (stone->marked) {
225 stone->color=0; 225 stone->color=0;
226 stone->changed=true; 226 stone->changed=true;
227 stone->marked=false; 227 stone->marked=false;
228 } 228 }
229 } 229 }
230 int removed=marked; 230 int removed=marked;
231 marked=0; 231 marked=0;
232 232
233 for (int col=0;col<sizex;col++) { 233 for (int col=0;col<sizex;col++) {
234 int i1=col+maxstone-sizex; 234 int i1=col+maxstone-sizex;
235 while ( i1>=0 && field[i1].color ) i1-=sizex; 235 while ( i1>=0 && field[i1].color ) i1-=sizex;
236 int i2=i1; 236 int i2=i1;
237 while (i2>=0) { 237 while (i2>=0) {
238 while ( i2>=0 && !field[i2].color ) i2-=sizex; 238 while ( i2>=0 && !field[i2].color ) i2-=sizex;
239 while ( i2>=0 && field[i2].color ) { 239 while ( i2>=0 && field[i2].color ) {
240 field[i1].color=field[i2].color; 240 field[i1].color=field[i2].color;
241 field[i1].changed=true; 241 field[i1].changed=true;
242 field[i2].color=0; 242 field[i2].color=0;
243 field[i2].changed=true; 243 field[i2].changed=true;
244 i1-=sizex; 244 i1-=sizex;
245 i2-=sizex; 245 i2-=sizex;
246 } 246 }
247 } 247 }
248 } 248 }
249 249
250 // find the last column that has something 250 // find the last column that has something
251 int lastcol = sizex; 251 int lastcol = sizex;
252 while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) { 252 while (lastcol > 0 && !field[map(lastcol-1, sizey-1)].color) {
253 lastcol--; 253 lastcol--;
254 } 254 }
255 255
256 for (int col=0;col<lastcol-1;) { 256 for (int col=0;col<lastcol-1;) {
257 bool empty = true; 257 bool empty = true;
258 for (int row = 0; row < sizey; row++) 258 for (int row = 0; row < sizey; row++)
259 if (field[map(col, row)].color) { 259 if (field[map(col, row)].color) {
260 empty = false; 260 empty = false;
261 break; 261 break;
262 } 262 }
263 if (!empty) { 263 if (!empty) {
264 col++; 264 col++;
265 continue; 265 continue;
266 } 266 }
267 int nextfullcol = col + 1; 267 int nextfullcol = col + 1;
268 while (nextfullcol < sizex && 268 while (nextfullcol < sizex &&
269 !field[map(nextfullcol, sizey - 1)].color) 269 !field[map(nextfullcol, sizey - 1)].color)
270 nextfullcol++; 270 nextfullcol++;
271 271
272 if (nextfullcol > sizex - 1) 272 if (nextfullcol > sizex - 1)
273 break; // we're ready 273 break; // we're ready
274 274
275 for (int row=0; row < sizey; row++) { 275 for (int row=0; row < sizey; row++) {
276 int source = map(nextfullcol, row); 276 int source = map(nextfullcol, row);
277 int dest = map(col, row); 277 int dest = map(col, row);
278 field[dest].color=field[source].color; 278 field[dest].color=field[source].color;
279 field[dest].changed=true; 279 field[dest].changed=true;
280 field[source].color=0; 280 field[source].color=0;
281 field[source].changed=true; 281 field[source].changed=true;
282 } 282 }
283 } 283 }
284 284
285 // add a bonus, if field is empty 285 // add a bonus, if field is empty
286 if (!field[map(0, sizey-1)].color) { 286 if (!field[map(0, sizey-1)].color) {
287 score+=1000; 287 score+=1000;
288 m_gotBonus= true; 288 m_gotBonus= true;
289 } 289 }
290 290
291 // gameover is undefined 291 // gameover is undefined
292 gameover=-1; 292 gameover=-1;
293 return removed; 293 return removed;
294} 294}
295 295
296bool StoneField::undoPossible() const { 296bool StoneField::undoPossible() const {
297 return !(!undolist||undolist->isEmpty()); 297 return !(!undolist||undolist->isEmpty());
298} 298}
299 299
300int 300int
301StoneField::undo(int count) { 301StoneField::undo(int count) {
302 if (!undoPossible()) 302 if (!undoPossible())
303 return 0; 303 return 0;
304 if (count <= 0) 304 if (count <= 0)
305 return 0; 305 return 0;
306 int undocount=1; 306 int undocount=1;
307 StoneFieldState *state=0; 307 StoneFieldState *state=0;
308 undolist->setAutoDelete(true); 308 undolist->setAutoDelete(true);
309 while (--count>0) { 309 while (--count>0) {
310 if (undolist->count()==1) break; 310 if (undolist->count()==1) break;
311 undolist->removeLast(); 311 undolist->removeLast();
312 undocount++; 312 undocount++;
313 } 313 }
314 state=undolist->getLast(); 314 state=undolist->getLast();
315// Q_ASSERT(state); 315// Q_ASSERT(state);
316 state->restore(*this); 316 state->restore(*this);
317 undolist->removeLast(); 317 undolist->removeLast();
318 return undocount; 318 return undocount;
319} 319}
320 320
321bool 321bool
322StoneField::isGameover() const { 322StoneField::isGameover() const {
323 register int i=maxstone-1;; 323 register int i=maxstone-1;;
324 register unsigned char color; 324 register unsigned char color;
325 325
326 if (gameover>=0) return (bool)gameover; 326 if (gameover>=0) return (bool)gameover;
327 // kdDebug() << "-->gameover" << endl; 327 // kdDebug() << "-->gameover" << endl;
328 328
329 while (i>=0) { 329 while (i>=0) {
330 // kdDebug() << i << " " << field[i].color << endl; 330 // kdDebug() << i << " " << field[i].color << endl;
331 // ignore empty fields 331 // ignore empty fields
332 while ( i>=0 && field[i].color==0 ) i--; 332 while ( i>=0 && field[i].color==0 ) i--;
333 // Wenn Stein gefunden, 333 // Wenn Stein gefunden,
334 // dann die Nachbarn auf gleiche Farbe pruefen. 334 // dann die Nachbarn auf gleiche Farbe pruefen.
335 while ( i>=0 && (color=field[i].color) ) { 335 while ( i>=0 && (color=field[i].color) ) {
336 // check left 336 // check left
337 if ( (i%sizex)!=0 && field[i-1].color==color) 337 if ( (i%sizex)!=0 && field[i-1].color==color)
338 goto check_gameover; 338 goto check_gameover;
339 // check upward 339 // check upward
340 if ( i>=sizex && field[i-sizex].color==color) 340 if ( i>=sizex && field[i-sizex].color==color)
341 goto check_gameover; 341 goto check_gameover;
342 i--; 342 i--;
343 } 343 }
344 } 344 }
345 check_gameover: 345 check_gameover:
346 gameover=(i<0); 346 gameover=(i<0);
347 // kdDebug() << "<--gameover" << endl; 347 // kdDebug() << "<--gameover" << endl;
348 return (bool)gameover; 348 return (bool)gameover;
349} 349}
350 350
351bool StoneField::gotBonus() const { 351bool StoneField::gotBonus() const {
352 return m_gotBonus; 352 return m_gotBonus;
353} 353}
354 354
355void StoneField::clearBonus() {
356 m_gotBonus = false;
357}
358
355int 359int
356StoneField::getBoard() const { 360StoneField::getBoard() const {
357 return board; 361 return board;
358} 362}
359 363
360int 364int
361StoneField::getScore() const { 365StoneField::getScore() const {
362 return score; 366 return score;
363} 367}
364 368
365int 369int
366StoneField::getColors() const { 370StoneField::getColors() const {
367 return colors; 371 return colors;
368} 372}
369 373
370int 374int
371StoneField::getMarked() const { 375StoneField::getMarked() const {
372 return marked; 376 return marked;
373} 377}
374 378
375int 379int
376StoneField::getFieldSize() const { 380StoneField::getFieldSize() const {
377 return maxstone; 381 return maxstone;
378} 382}
379 383
380struct Stone * 384struct Stone *
381StoneField::getField() const { 385StoneField::getField() const {
382 return field; 386 return field;
383} 387}
384 388
385 389
386 390
387 391
388 392
389 393
390 394