Diffstat (limited to 'noncore/games/zsame/StoneField.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/zsame/StoneField.cpp | 4 |
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 | |||
163 | StoneField::mark(int index,unsigned char color) { | 163 | StoneField::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 | ||
186 | void | 186 | void |
187 | StoneField::unmark() { | 187 | StoneField::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 | ||
198 | int | 198 | int |
199 | StoneField::remove(int x,int y,bool force) { | 199 | StoneField::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 | ||
296 | bool StoneField::undoPossible() const { | 296 | bool StoneField::undoPossible() const { |
297 | return !(!undolist||undolist->isEmpty()); | 297 | return !(!undolist||undolist->isEmpty()); |
298 | } | 298 | } |
299 | 299 | ||
300 | int | 300 | int |
301 | StoneField::undo(int count) { | 301 | StoneField::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 | ||
321 | bool | 321 | bool |
322 | StoneField::isGameover() const { | 322 | StoneField::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 | ||
351 | bool StoneField::gotBonus() const { | 351 | bool StoneField::gotBonus() const { |
352 | return m_gotBonus; | 352 | return m_gotBonus; |
353 | } | 353 | } |
354 | 354 | ||
355 | void StoneField::clearBonus() { | ||
356 | m_gotBonus = false; | ||
357 | } | ||
358 | |||
355 | int | 359 | int |
356 | StoneField::getBoard() const { | 360 | StoneField::getBoard() const { |
357 | return board; | 361 | return board; |
358 | } | 362 | } |
359 | 363 | ||
360 | int | 364 | int |
361 | StoneField::getScore() const { | 365 | StoneField::getScore() const { |
362 | return score; | 366 | return score; |
363 | } | 367 | } |
364 | 368 | ||
365 | int | 369 | int |
366 | StoneField::getColors() const { | 370 | StoneField::getColors() const { |
367 | return colors; | 371 | return colors; |
368 | } | 372 | } |
369 | 373 | ||
370 | int | 374 | int |
371 | StoneField::getMarked() const { | 375 | StoneField::getMarked() const { |
372 | return marked; | 376 | return marked; |
373 | } | 377 | } |
374 | 378 | ||
375 | int | 379 | int |
376 | StoneField::getFieldSize() const { | 380 | StoneField::getFieldSize() const { |
377 | return maxstone; | 381 | return maxstone; |
378 | } | 382 | } |
379 | 383 | ||
380 | struct Stone * | 384 | struct Stone * |
381 | StoneField::getField() const { | 385 | StoneField::getField() const { |
382 | return field; | 386 | return field; |
383 | } | 387 | } |
384 | 388 | ||
385 | 389 | ||
386 | 390 | ||
387 | 391 | ||
388 | 392 | ||
389 | 393 | ||
390 | 394 | ||