diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/minesweeper.c | 299 |
1 files changed, 223 insertions, 76 deletions
diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c index 23d6e07157..663d5c45ec 100644 --- a/apps/plugins/minesweeper.c +++ b/apps/plugins/minesweeper.c | |||
@@ -19,12 +19,6 @@ | |||
19 | 19 | ||
20 | /***************************************************************************** | 20 | /***************************************************************************** |
21 | Mine Sweeper by dionoea | 21 | Mine Sweeper by dionoea |
22 | |||
23 | use arrow keys to move cursor | ||
24 | use ON or F2 to clear a tile | ||
25 | use PLAY or F1 to put a flag on a tile | ||
26 | use F3 to see how many mines are left (supposing all your flags are correct) | ||
27 | |||
28 | *****************************************************************************/ | 22 | *****************************************************************************/ |
29 | 23 | ||
30 | #include "plugin.h" | 24 | #include "plugin.h" |
@@ -50,6 +44,8 @@ PLUGIN_HEADER | |||
50 | #define MINESWP_DISCOVER BUTTON_ON | 44 | #define MINESWP_DISCOVER BUTTON_ON |
51 | #define MINESWP_DISCOVER2 BUTTON_F2 | 45 | #define MINESWP_DISCOVER2 BUTTON_F2 |
52 | #define MINESWP_INFO BUTTON_F3 | 46 | #define MINESWP_INFO BUTTON_F3 |
47 | #define MINESWP_RIGHT (BUTTON_F1 | BUTTON_RIGHT) | ||
48 | #define MINESWP_LEFT (BUTTON_F1 | BUTTON_LEFT) | ||
53 | 49 | ||
54 | #elif CONFIG_KEYPAD == ONDIO_PAD | 50 | #elif CONFIG_KEYPAD == ONDIO_PAD |
55 | #define MINESWP_UP BUTTON_UP | 51 | #define MINESWP_UP BUTTON_UP |
@@ -60,6 +56,8 @@ PLUGIN_HEADER | |||
60 | #define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL) | 56 | #define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL) |
61 | #define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT) | 57 | #define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT) |
62 | #define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF) | 58 | #define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF) |
59 | #define MINESWP_RIGHT (BUTTON_MENU | BUTTON_RIGHT) | ||
60 | #define MINESWP_LEFT (BUTTON_MENU | BUTTON_LEFT) | ||
63 | 61 | ||
64 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | 62 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ |
65 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | 63 | (CONFIG_KEYPAD == IRIVER_H300_PAD) |
@@ -67,9 +65,11 @@ PLUGIN_HEADER | |||
67 | #define MINESWP_DOWN BUTTON_DOWN | 65 | #define MINESWP_DOWN BUTTON_DOWN |
68 | #define MINESWP_QUIT BUTTON_OFF | 66 | #define MINESWP_QUIT BUTTON_OFF |
69 | #define MINESWP_START BUTTON_SELECT | 67 | #define MINESWP_START BUTTON_SELECT |
70 | #define MINESWP_TOGGLE BUTTON_SELECT | 68 | #define MINESWP_TOGGLE BUTTON_ON |
71 | #define MINESWP_DISCOVER BUTTON_ON | 69 | #define MINESWP_DISCOVER BUTTON_SELECT |
72 | #define MINESWP_INFO BUTTON_MODE | 70 | #define MINESWP_INFO BUTTON_MODE |
71 | #define MINESWP_RIGHT (BUTTON_ON | BUTTON_RIGHT) | ||
72 | #define MINESWP_LEFT (BUTTON_ON | BUTTON_LEFT) | ||
73 | 73 | ||
74 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | 74 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
75 | (CONFIG_KEYPAD == IPOD_3G_PAD) | 75 | (CONFIG_KEYPAD == IPOD_3G_PAD) |
@@ -80,6 +80,8 @@ PLUGIN_HEADER | |||
80 | #define MINESWP_TOGGLE BUTTON_PLAY | 80 | #define MINESWP_TOGGLE BUTTON_PLAY |
81 | #define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_PLAY) | 81 | #define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_PLAY) |
82 | #define MINESWP_INFO (BUTTON_SELECT | BUTTON_MENU) | 82 | #define MINESWP_INFO (BUTTON_SELECT | BUTTON_MENU) |
83 | #define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT) | ||
84 | #define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT) | ||
83 | 85 | ||
84 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) | 86 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) |
85 | #define MINESWP_UP BUTTON_UP | 87 | #define MINESWP_UP BUTTON_UP |
@@ -89,15 +91,19 @@ PLUGIN_HEADER | |||
89 | #define MINESWP_TOGGLE BUTTON_PLAY | 91 | #define MINESWP_TOGGLE BUTTON_PLAY |
90 | #define MINESWP_DISCOVER BUTTON_SELECT | 92 | #define MINESWP_DISCOVER BUTTON_SELECT |
91 | #define MINESWP_INFO (BUTTON_REC | BUTTON_PLAY) | 93 | #define MINESWP_INFO (BUTTON_REC | BUTTON_PLAY) |
94 | #define MINESWP_RIGHT (BUTTON_PLAY | BUTTON_RIGHT) | ||
95 | #define MINESWP_LEFT (BUTTON_PLAY | BUTTON_LEFT) | ||
92 | 96 | ||
93 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) | 97 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) |
94 | #define MINESWP_UP BUTTON_UP | 98 | #define MINESWP_UP BUTTON_UP |
95 | #define MINESWP_DOWN BUTTON_DOWN | 99 | #define MINESWP_DOWN BUTTON_DOWN |
96 | #define MINESWP_QUIT BUTTON_A | 100 | #define MINESWP_QUIT BUTTON_A |
97 | #define MINESWP_START BUTTON_SELECT | 101 | #define MINESWP_START BUTTON_SELECT |
98 | #define MINESWP_TOGGLE BUTTON_SELECT | 102 | #define MINESWP_TOGGLE BUTTON_POWER |
99 | #define MINESWP_DISCOVER BUTTON_POWER | 103 | #define MINESWP_DISCOVER BUTTON_SELECT |
100 | #define MINESWP_INFO BUTTON_MENU | 104 | #define MINESWP_INFO BUTTON_MENU |
105 | #define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT) | ||
106 | #define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT) | ||
101 | 107 | ||
102 | #endif | 108 | #endif |
103 | 109 | ||
@@ -109,7 +115,7 @@ static struct plugin_api* rb; | |||
109 | 115 | ||
110 | /* define how numbers are displayed (that way we don't have to */ | 116 | /* define how numbers are displayed (that way we don't have to */ |
111 | /* worry about fonts) */ | 117 | /* worry about fonts) */ |
112 | static unsigned char num[9][8] = { | 118 | static unsigned char num[10][8] = { |
113 | /*reading the sprites: | 119 | /*reading the sprites: |
114 | on screen f123 | 120 | on screen f123 |
115 | 4567 | 121 | 4567 |
@@ -203,6 +209,16 @@ static unsigned char num[9][8] = { | |||
203 | 0x28, /* ..O..O.. */ | 209 | 0x28, /* ..O..O.. */ |
204 | 0x00, /* ...OO... */ | 210 | 0x00, /* ...OO... */ |
205 | 0x00},/* ........ */ | 211 | 0x00},/* ........ */ |
212 | /* mine */ | ||
213 | {0x00, /* ........ */ | ||
214 | 0x00, /* ........ */ | ||
215 | 0x18, /* ...OO... */ | ||
216 | 0x3c, /* ..OOOO.. */ | ||
217 | 0x3c, /* ..OOOO.. */ | ||
218 | 0x18, /* ...OO... */ | ||
219 | 0x00, /* ........ */ | ||
220 | 0x00},/* ........ */ | ||
221 | |||
206 | }; | 222 | }; |
207 | 223 | ||
208 | /* the tile struct | 224 | /* the tile struct |
@@ -222,49 +238,109 @@ typedef struct tile { | |||
222 | int height = LCD_HEIGHT/8; | 238 | int height = LCD_HEIGHT/8; |
223 | int width = LCD_WIDTH/8; | 239 | int width = LCD_WIDTH/8; |
224 | 240 | ||
225 | /* the minefield */ | 241 | /* The Minefield. Caution it is defined as Y, X! Not the opposite. */ |
226 | tile minefield[LCD_HEIGHT/8][LCD_WIDTH/8]; | 242 | tile minefield[LCD_HEIGHT/8][LCD_WIDTH/8]; |
227 | 243 | ||
228 | /* total number of mines on the game */ | 244 | /* total number of mines on the game */ |
229 | int mine_num = 0; | 245 | int mine_num = 0; |
230 | 246 | ||
231 | /* discovers the tile when player clears one of them */ | 247 | /* percentage of mines on minefield used durring generation */ |
232 | /* a chain reaction (of discovery) occurs if tile has no mines */ | 248 | int p=16; |
233 | /* as neighbors */ | ||
234 | void discover(int, int); | ||
235 | void discover(int x, int y){ | ||
236 | 249 | ||
237 | if(x<0) return; | 250 | /* number of tiles left on the game */ |
238 | if(y<0) return; | 251 | int tiles_left; |
239 | if(x>width-1) return; | ||
240 | if(y>height-1) return; | ||
241 | if(minefield[y][x].known) return; | ||
242 | 252 | ||
243 | minefield[y][x].known = 1; | 253 | /* Because mines are set after the first move... */ |
244 | if(minefield[y][x].neighbors == 0){ | 254 | bool no_mines = true; |
245 | discover(x-1,y-1); | 255 | |
246 | discover(x,y-1); | 256 | /* We need a stack (created on discover()) for the cascade algorithm. */ |
247 | discover(x+1,y-1); | 257 | int stack_pos = 0; |
248 | discover(x+1,y); | 258 | |
249 | discover(x+1,y+1); | 259 | /* Functions to center the board on screen. */ |
250 | discover(x,y+1); | 260 | int c_height(void){ |
251 | discover(x-1,y+1); | 261 | return LCD_HEIGHT/16 - height/2; |
252 | discover(x-1,y); | 262 | } |
263 | |||
264 | int c_width(void){ | ||
265 | return LCD_WIDTH/16 - width/2; | ||
266 | } | ||
267 | |||
268 | void push (int *stack, int y, int x){ | ||
269 | |||
270 | if(stack_pos <= height*width){ | ||
271 | stack_pos++; | ||
272 | stack[stack_pos] = y; | ||
273 | stack_pos++; | ||
274 | stack[stack_pos] = x; | ||
253 | } | 275 | } |
254 | return; | ||
255 | } | 276 | } |
256 | 277 | ||
278 | /* Unveil tiles and push them to stack if they are empty. */ | ||
279 | void unveil(int *stack, int y, int x){ | ||
280 | |||
281 | if(x < c_width() || y < c_height() || x > c_width() + width-1 | ||
282 | || y > c_height() + height-1 || minefield[y][x].known | ||
283 | || minefield[y][x].mine || minefield[y][x].flag) return; | ||
284 | |||
285 | if(minefield[y][x].neighbors == 0){ | ||
286 | minefield[y][x].known = 1; | ||
287 | push(stack, y, x); | ||
288 | } else | ||
289 | minefield[y][x].known = 1; | ||
290 | } | ||
291 | |||
292 | void discover(int y, int x){ | ||
293 | |||
294 | int stack[height*width]; | ||
295 | |||
296 | /* Selected tile. */ | ||
297 | if(x < c_width() || y < c_height() || x > c_width() + width-1 | ||
298 | || y > c_height() + height-1 || minefield[y][x].known | ||
299 | || minefield[y][x].mine || minefield[y][x].flag) return; | ||
300 | |||
301 | minefield[y][x].known = 1; | ||
302 | /* Exit if the tile is not empty. (no mines nearby) */ | ||
303 | if(minefield[y][x].neighbors) return; | ||
304 | |||
305 | push(stack, y, x); | ||
306 | |||
307 | /* Scan all nearby tiles. If we meet a tile with a number we just unveil | ||
308 | it. If we meet an empty tile, we push the location in stack. For each | ||
309 | location in stack we do the same thing. (scan again all nearby tiles) */ | ||
310 | while(stack_pos){ | ||
311 | /* Retrieve x, y from stack. */ | ||
312 | x = stack[stack_pos]; | ||
313 | y = stack[stack_pos-1]; | ||
314 | |||
315 | /* Pop. */ | ||
316 | if(stack_pos > 0) stack_pos -= 2; | ||
317 | else rb->splash(HZ,true,"ERROR"); | ||
318 | |||
319 | unveil(stack, y-1, x-1); | ||
320 | unveil(stack, y-1, x); | ||
321 | unveil(stack, y-1, x+1); | ||
322 | unveil(stack, y, x+1); | ||
323 | unveil(stack, y+1, x+1); | ||
324 | unveil(stack, y+1, x); | ||
325 | unveil(stack, y+1, x-1); | ||
326 | unveil(stack, y, x-1); | ||
327 | } | ||
328 | } | ||
257 | 329 | ||
258 | /* init not mine related elements of the mine field */ | 330 | /* Reset the whole board for a new game. */ |
259 | void minesweeper_init(void){ | 331 | void minesweeper_init(void){ |
260 | int i,j; | 332 | int i,j; |
261 | 333 | ||
262 | for(i=0;i<height;i++){ | 334 | for(i=0;i<LCD_HEIGHT/8;i++){ |
263 | for(j=0;j<width;j++){ | 335 | for(j=0;j<LCD_WIDTH/8;j++){ |
264 | minefield[i][j].known = 0; | 336 | minefield[i][j].known = 0; |
265 | minefield[i][j].flag = 0; | 337 | minefield[i][j].flag = 0; |
338 | minefield[i][j].mine = 0; | ||
339 | minefield[i][j].neighbors = 0; | ||
266 | } | 340 | } |
267 | } | 341 | } |
342 | no_mines = true; | ||
343 | tiles_left = width*height; | ||
268 | } | 344 | } |
269 | 345 | ||
270 | 346 | ||
@@ -275,8 +351,8 @@ void minesweeper_putmines(int p, int x, int y){ | |||
275 | int i,j; | 351 | int i,j; |
276 | 352 | ||
277 | mine_num = 0; | 353 | mine_num = 0; |
278 | for(i=0;i<height;i++){ | 354 | for(i=c_height();i<c_height() + height;i++){ |
279 | for(j=0;j<width;j++){ | 355 | for(j=c_width();j<c_width() + width;j++){ |
280 | if(rb->rand()%100<p && !(y==i && x==j)){ | 356 | if(rb->rand()%100<p && !(y==i && x==j)){ |
281 | minefield[i][j].mine = 1; | 357 | minefield[i][j].mine = 1; |
282 | mine_num++; | 358 | mine_num++; |
@@ -286,47 +362,83 @@ void minesweeper_putmines(int p, int x, int y){ | |||
286 | minefield[i][j].neighbors = 0; | 362 | minefield[i][j].neighbors = 0; |
287 | } | 363 | } |
288 | } | 364 | } |
289 | 365 | ||
290 | /* we need to compute the neighbor element for each tile */ | 366 | /* we need to compute the neighbor element for each tile */ |
291 | for(i=0;i<height;i++){ | 367 | for(i=c_height();i<c_height() + height;i++){ |
292 | for(j=0;j<width;j++){ | 368 | for(j=c_width();j<c_width() + width;j++){ |
293 | if(i>0){ | 369 | if(i>0){ |
294 | if(j>0) | 370 | if(j>0) |
295 | minefield[i][j].neighbors += minefield[i-1][j-1].mine; | 371 | minefield[i][j].neighbors += minefield[i-1][j-1].mine; |
296 | minefield[i][j].neighbors += minefield[i-1][j].mine; | 372 | minefield[i][j].neighbors += minefield[i-1][j].mine; |
297 | if(j<width-1) | 373 | if(j<c_width() + width-1) |
298 | minefield[i][j].neighbors += minefield[i-1][j+1].mine; | 374 | minefield[i][j].neighbors += minefield[i-1][j+1].mine; |
299 | } | 375 | } |
300 | if(j>0) | 376 | if(j>0) |
301 | minefield[i][j].neighbors += minefield[i][j-1].mine; | 377 | minefield[i][j].neighbors += minefield[i][j-1].mine; |
302 | if(j<width-1) | 378 | if(j<c_width() + width-1) |
303 | minefield[i][j].neighbors += minefield[i][j+1].mine; | 379 | minefield[i][j].neighbors += minefield[i][j+1].mine; |
304 | if(i<height-1){ | 380 | if(i<c_height() + height-1){ |
305 | if(j>0) | 381 | if(j>0) |
306 | minefield[i][j].neighbors += minefield[i+1][j-1].mine; | 382 | minefield[i][j].neighbors += minefield[i+1][j-1].mine; |
307 | minefield[i][j].neighbors += minefield[i+1][j].mine; | 383 | minefield[i][j].neighbors += minefield[i+1][j].mine; |
308 | if(j<width-1) | 384 | if(j<c_width() + width-1) |
309 | minefield[i][j].neighbors += minefield[i+1][j+1].mine; | 385 | minefield[i][j].neighbors += minefield[i+1][j+1].mine; |
310 | } | 386 | } |
311 | } | 387 | } |
312 | } | 388 | } |
389 | |||
390 | no_mines = false; | ||
391 | /* In case the user is lucky and there are no mines positioned. */ | ||
392 | if(!mine_num && height*width != 1) minesweeper_putmines(p, x, y); | ||
313 | } | 393 | } |
314 | 394 | ||
395 | /* A function that will uncover all the board, when the user wins or loses. | ||
396 | can easily be expanded, (just a call assigned to a button) as a solver. */ | ||
397 | void mine_show(void){ | ||
398 | int i, j, button; | ||
399 | |||
400 | for(i=c_height();i<c_height() + height;i++){ | ||
401 | for(j=c_width();j<c_width() + width;j++){ | ||
402 | #if LCD_DEPTH > 1 | ||
403 | rb->lcd_set_foreground(LCD_DARKGRAY); | ||
404 | rb->lcd_drawrect(j*8,i*8,8,8); | ||
405 | rb->lcd_set_foreground(LCD_BLACK); | ||
406 | #else | ||
407 | rb->lcd_drawrect(j*8,i*8,8,8); | ||
408 | #endif | ||
409 | if(!minefield[i][j].known){ | ||
410 | if(minefield[i][j].mine){ | ||
411 | rb->lcd_set_drawmode(DRMODE_FG); | ||
412 | rb->lcd_mono_bitmap(num[9], j*8,i*8,8,8); | ||
413 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
414 | } else if(minefield[i][j].neighbors){ | ||
415 | rb->lcd_set_drawmode(DRMODE_FG); | ||
416 | rb->lcd_mono_bitmap(num[minefield[i][j].neighbors], | ||
417 | j*8,i*8,8,8); | ||
418 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | rb->lcd_update(); | ||
424 | |||
425 | bool k = true; | ||
426 | while(k){ | ||
427 | button = rb->button_get_w_tmo(HZ/10); | ||
428 | if(button != BUTTON_NONE && !(button & BUTTON_REL)) k = false; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | |||
315 | /* the big and ugly function that is the game */ | 433 | /* the big and ugly function that is the game */ |
316 | int minesweeper(void) | 434 | int minesweeper(void) |
317 | { | 435 | { |
318 | int i,j; | 436 | int i,j; |
319 | int button; | 437 | int button; |
320 | int lastbutton = BUTTON_NONE; | 438 | int lastbutton = BUTTON_NONE; |
321 | 439 | ||
322 | /* the cursor coordinates */ | 440 | /* the cursor coordinates */ |
323 | int x=0,y=0; | 441 | int x=0, y=0; |
324 | |||
325 | /* number of tiles left on the game */ | ||
326 | int tiles_left=width*height; | ||
327 | |||
328 | /* percentage of mines on minefield used durring generation */ | ||
329 | int p=16; | ||
330 | 442 | ||
331 | /* a usefull string for snprintf */ | 443 | /* a usefull string for snprintf */ |
332 | char str[30]; | 444 | char str[30]; |
@@ -351,27 +463,47 @@ int minesweeper(void) | |||
351 | #elif CONFIG_KEYPAD == IRIVER_H100_PAD | 463 | #elif CONFIG_KEYPAD == IRIVER_H100_PAD |
352 | rb->lcd_puts(0,6,"SELECT to start"); | 464 | rb->lcd_puts(0,6,"SELECT to start"); |
353 | #endif | 465 | #endif |
354 | |||
355 | rb->lcd_update(); | 466 | rb->lcd_update(); |
356 | 467 | ||
357 | |||
358 | button = rb->button_get(true); | 468 | button = rb->button_get(true); |
359 | switch(button){ | 469 | switch(button){ |
360 | case MINESWP_DOWN: | 470 | case MINESWP_DOWN: |
471 | case (MINESWP_DOWN | BUTTON_REPEAT): | ||
361 | p = (p + 98)%100; | 472 | p = (p + 98)%100; |
473 | /* Don't let the user play without mines. */ | ||
474 | if(!p) p = 98; | ||
362 | break; | 475 | break; |
363 | 476 | ||
364 | case MINESWP_UP: | 477 | case MINESWP_UP: |
478 | case (MINESWP_UP | BUTTON_REPEAT): | ||
365 | p = (p + 2)%100; | 479 | p = (p + 2)%100; |
480 | /* Don't let the user play without mines. */ | ||
481 | if(!p) p = 2; | ||
366 | break; | 482 | break; |
367 | 483 | ||
368 | case BUTTON_RIGHT: | 484 | case BUTTON_RIGHT: |
485 | case (BUTTON_RIGHT | BUTTON_REPEAT): | ||
369 | height = height%(LCD_HEIGHT/8)+1; | 486 | height = height%(LCD_HEIGHT/8)+1; |
370 | break; | 487 | break; |
371 | 488 | ||
372 | case BUTTON_LEFT: | 489 | case BUTTON_LEFT: |
490 | case (BUTTON_LEFT | BUTTON_REPEAT): | ||
373 | width = width%(LCD_WIDTH/8)+1; | 491 | width = width%(LCD_WIDTH/8)+1; |
374 | break; | 492 | break; |
493 | |||
494 | case MINESWP_RIGHT: | ||
495 | case (MINESWP_RIGHT | BUTTON_REPEAT): | ||
496 | height--; | ||
497 | if(height < 1) height = LCD_HEIGHT/8; | ||
498 | if(height > LCD_HEIGHT) height = 1; | ||
499 | break; | ||
500 | |||
501 | case MINESWP_LEFT: | ||
502 | case (MINESWP_LEFT | BUTTON_REPEAT): | ||
503 | width--; | ||
504 | if(width < 1) width = LCD_WIDTH/8; | ||
505 | if(width > LCD_WIDTH) width = 1; | ||
506 | break; | ||
375 | 507 | ||
376 | case MINESWP_START:/* start playing */ | 508 | case MINESWP_START:/* start playing */ |
377 | i = 1; | 509 | i = 1; |
@@ -395,6 +527,8 @@ int minesweeper(void) | |||
395 | ********************/ | 527 | ********************/ |
396 | 528 | ||
397 | minesweeper_init(); | 529 | minesweeper_init(); |
530 | x = c_width(); | ||
531 | y = c_height(); | ||
398 | 532 | ||
399 | /********************** | 533 | /********************** |
400 | * play * | 534 | * play * |
@@ -406,8 +540,8 @@ int minesweeper(void) | |||
406 | rb->lcd_clear_display(); | 540 | rb->lcd_clear_display(); |
407 | 541 | ||
408 | /*display the mine field */ | 542 | /*display the mine field */ |
409 | for(i=0;i<height;i++){ | 543 | for(i=c_height();i<c_height() + height;i++){ |
410 | for(j=0;j<width;j++){ | 544 | for(j=c_width();j<c_width() + width;j++){ |
411 | #if LCD_DEPTH > 1 | 545 | #if LCD_DEPTH > 1 |
412 | rb->lcd_set_foreground(LCD_DARKGRAY); | 546 | rb->lcd_set_foreground(LCD_DARKGRAY); |
413 | rb->lcd_drawrect(j*8,i*8,8,8); | 547 | rb->lcd_drawrect(j*8,i*8,8,8); |
@@ -416,11 +550,10 @@ int minesweeper(void) | |||
416 | rb->lcd_drawrect(j*8,i*8,8,8); | 550 | rb->lcd_drawrect(j*8,i*8,8,8); |
417 | #endif | 551 | #endif |
418 | if(minefield[i][j].known){ | 552 | if(minefield[i][j].known){ |
419 | if(minefield[i][j].mine){ | 553 | if(minefield[i][j].neighbors){ |
420 | rb->lcd_putsxy(j*8+1,i*8+1,"b"); | ||
421 | } else if(minefield[i][j].neighbors){ | ||
422 | rb->lcd_set_drawmode(DRMODE_FG); | 554 | rb->lcd_set_drawmode(DRMODE_FG); |
423 | rb->lcd_mono_bitmap(num[minefield[i][j].neighbors],j*8,i*8,8,8); | 555 | rb->lcd_mono_bitmap(num[minefield[i][j].neighbors], |
556 | j*8,i*8,8,8); | ||
424 | rb->lcd_set_drawmode(DRMODE_SOLID); | 557 | rb->lcd_set_drawmode(DRMODE_SOLID); |
425 | } | 558 | } |
426 | } else if(minefield[i][j].flag) { | 559 | } else if(minefield[i][j].flag) { |
@@ -451,29 +584,33 @@ int minesweeper(void) | |||
451 | /* quit minesweeper (you really shouldn't use this button ...) */ | 584 | /* quit minesweeper (you really shouldn't use this button ...) */ |
452 | case MINESWP_QUIT: | 585 | case MINESWP_QUIT: |
453 | return MINESWEEPER_QUIT; | 586 | return MINESWEEPER_QUIT; |
454 | 587 | ||
455 | /* move cursor left */ | 588 | /* move cursor left */ |
456 | case BUTTON_LEFT: | 589 | case BUTTON_LEFT: |
457 | case (BUTTON_LEFT | BUTTON_REPEAT): | 590 | case (BUTTON_LEFT | BUTTON_REPEAT): |
458 | x = (x + width - 1)%width; | 591 | if(x<=c_width()) x = width + c_width(); |
592 | x = x-1; | ||
459 | break; | 593 | break; |
460 | 594 | ||
461 | /* move cursor right */ | 595 | /* move cursor right */ |
462 | case BUTTON_RIGHT: | 596 | case BUTTON_RIGHT: |
463 | case (BUTTON_RIGHT | BUTTON_REPEAT): | 597 | case (BUTTON_RIGHT | BUTTON_REPEAT): |
464 | x = (x + 1)%width; | 598 | if(x>=width + c_width() - 1) x = c_width() - 1; |
599 | x = x+1; | ||
465 | break; | 600 | break; |
466 | 601 | ||
467 | /* move cursor down */ | 602 | /* move cursor down */ |
468 | case MINESWP_DOWN: | 603 | case MINESWP_DOWN: |
469 | case (MINESWP_DOWN | BUTTON_REPEAT): | 604 | case (MINESWP_DOWN | BUTTON_REPEAT): |
470 | y = (y + 1)%height; | 605 | if(y>=height + c_height() - 1) y = c_height() - 1; |
606 | y = y+1; | ||
471 | break; | 607 | break; |
472 | 608 | ||
473 | /* move cursor up */ | 609 | /* move cursor up */ |
474 | case MINESWP_UP: | 610 | case MINESWP_UP: |
475 | case (MINESWP_UP | BUTTON_REPEAT): | 611 | case (MINESWP_UP | BUTTON_REPEAT): |
476 | y = (y + height - 1)%height; | 612 | if(y<=c_height()) y = height + c_height(); |
613 | y = y-1; | ||
477 | break; | 614 | break; |
478 | 615 | ||
479 | /* discover a tile (and it's neighbors if .neighbors == 0) */ | 616 | /* discover a tile (and it's neighbors if .neighbors == 0) */ |
@@ -484,14 +621,17 @@ int minesweeper(void) | |||
484 | if(minefield[y][x].flag) break; | 621 | if(minefield[y][x].flag) break; |
485 | /* we put the mines on the first "click" so that you don't */ | 622 | /* we put the mines on the first "click" so that you don't */ |
486 | /* lose on the first "click" */ | 623 | /* lose on the first "click" */ |
487 | if(tiles_left == width*height) minesweeper_putmines(p,x,y); | 624 | if(tiles_left == width*height && no_mines) |
488 | discover(x,y); | 625 | minesweeper_putmines(p,x,y); |
626 | |||
627 | discover(y, x); | ||
628 | |||
489 | if(minefield[y][x].mine){ | 629 | if(minefield[y][x].mine){ |
490 | return MINESWEEPER_LOSE; | 630 | return MINESWEEPER_LOSE; |
491 | } | 631 | } |
492 | tiles_left = 0; | 632 | tiles_left = 0; |
493 | for(i=0;i<height;i++){ | 633 | for(i=c_height();i<c_height() + height;i++){ |
494 | for(j=0;j<width;j++){ | 634 | for(j=c_width();j<c_width() + width;j++){ |
495 | if(minefield[i][j].known == 0) tiles_left++; | 635 | if(minefield[i][j].known == 0) tiles_left++; |
496 | } | 636 | } |
497 | } | 637 | } |
@@ -515,13 +655,16 @@ int minesweeper(void) | |||
515 | /* show how many mines you think you have found and how many */ | 655 | /* show how many mines you think you have found and how many */ |
516 | /* there really are on the game */ | 656 | /* there really are on the game */ |
517 | case MINESWP_INFO: | 657 | case MINESWP_INFO: |
658 | if(no_mines) break; | ||
518 | tiles_left = 0; | 659 | tiles_left = 0; |
519 | for(i=0;i<height;i++){ | 660 | for(i=c_height();i<c_height() + height;i++){ |
520 | for(j=0;j<width;j++){ | 661 | for(j=c_width();j<c_width() + width;j++){ |
521 | if(minefield[i][j].flag) tiles_left++; | 662 | if(minefield[i][j].flag && !minefield[i][j].known) |
663 | tiles_left++; | ||
522 | } | 664 | } |
523 | } | 665 | } |
524 | rb->splash(HZ*2, true, "You found %d mines out of %d", tiles_left, mine_num); | 666 | rb->splash(HZ*2, true, "You found %d mines out of %d", |
667 | tiles_left, mine_num); | ||
525 | break; | 668 | break; |
526 | 669 | ||
527 | default: | 670 | default: |
@@ -547,11 +690,15 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
547 | while(!exit) { | 690 | while(!exit) { |
548 | switch(minesweeper()){ | 691 | switch(minesweeper()){ |
549 | case MINESWEEPER_WIN: | 692 | case MINESWEEPER_WIN: |
550 | rb->splash(HZ*2, true, "You Win :)"); | 693 | rb->splash(HZ*2, true, "You Won! Press a key"); |
694 | rb->lcd_clear_display(); | ||
695 | mine_show(); | ||
551 | break; | 696 | break; |
552 | 697 | ||
553 | case MINESWEEPER_LOSE: | 698 | case MINESWEEPER_LOSE: |
554 | rb->splash(HZ*2, true, "You Lose :("); | 699 | rb->splash(HZ*2, true, "You Lost! Press a key"); |
700 | rb->lcd_clear_display(); | ||
701 | mine_show(); | ||
555 | break; | 702 | break; |
556 | 703 | ||
557 | case MINESWEEPER_USB: | 704 | case MINESWEEPER_USB: |