summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/minesweeper.c299
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/*****************************************************************************
21Mine Sweeper by dionoea 21Mine Sweeper by dionoea
22
23use arrow keys to move cursor
24use ON or F2 to clear a tile
25use PLAY or F1 to put a flag on a tile
26use 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) */
112static unsigned char num[9][8] = { 118static 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 {
222int height = LCD_HEIGHT/8; 238int height = LCD_HEIGHT/8;
223int width = LCD_WIDTH/8; 239int width = LCD_WIDTH/8;
224 240
225/* the minefield */ 241/* The Minefield. Caution it is defined as Y, X! Not the opposite. */
226tile minefield[LCD_HEIGHT/8][LCD_WIDTH/8]; 242tile 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 */
229int mine_num = 0; 245int 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 */ 248int p=16;
233/* as neighbors */
234void discover(int, int);
235void 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; 251int 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){ 254bool 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); 257int 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); 260int c_height(void){
251 discover(x-1,y+1); 261 return LCD_HEIGHT/16 - height/2;
252 discover(x-1,y); 262}
263
264int c_width(void){
265 return LCD_WIDTH/16 - width/2;
266}
267
268void 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. */
279void 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
292void 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. */
259void minesweeper_init(void){ 331void 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. */
397void 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 */
316int minesweeper(void) 434int 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: