forked from len0rd/rockbox
Patch #5384 from Alexander Spyridakis - fixes bug report 4908
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9968 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
217f54bc69
commit
fd18a4e9d3
1 changed files with 224 additions and 77 deletions
|
@ -19,12 +19,6 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
Mine Sweeper by dionoea
|
Mine Sweeper by dionoea
|
||||||
|
|
||||||
use arrow keys to move cursor
|
|
||||||
use ON or F2 to clear a tile
|
|
||||||
use PLAY or F1 to put a flag on a tile
|
|
||||||
use F3 to see how many mines are left (supposing all your flags are correct)
|
|
||||||
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
@ -50,6 +44,8 @@ PLUGIN_HEADER
|
||||||
#define MINESWP_DISCOVER BUTTON_ON
|
#define MINESWP_DISCOVER BUTTON_ON
|
||||||
#define MINESWP_DISCOVER2 BUTTON_F2
|
#define MINESWP_DISCOVER2 BUTTON_F2
|
||||||
#define MINESWP_INFO BUTTON_F3
|
#define MINESWP_INFO BUTTON_F3
|
||||||
|
#define MINESWP_RIGHT (BUTTON_F1 | BUTTON_RIGHT)
|
||||||
|
#define MINESWP_LEFT (BUTTON_F1 | BUTTON_LEFT)
|
||||||
|
|
||||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||||
#define MINESWP_UP BUTTON_UP
|
#define MINESWP_UP BUTTON_UP
|
||||||
|
@ -60,6 +56,8 @@ PLUGIN_HEADER
|
||||||
#define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL)
|
#define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL)
|
||||||
#define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT)
|
#define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT)
|
||||||
#define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF)
|
#define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF)
|
||||||
|
#define MINESWP_RIGHT (BUTTON_MENU | BUTTON_RIGHT)
|
||||||
|
#define MINESWP_LEFT (BUTTON_MENU | BUTTON_LEFT)
|
||||||
|
|
||||||
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
||||||
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
||||||
|
@ -67,9 +65,11 @@ PLUGIN_HEADER
|
||||||
#define MINESWP_DOWN BUTTON_DOWN
|
#define MINESWP_DOWN BUTTON_DOWN
|
||||||
#define MINESWP_QUIT BUTTON_OFF
|
#define MINESWP_QUIT BUTTON_OFF
|
||||||
#define MINESWP_START BUTTON_SELECT
|
#define MINESWP_START BUTTON_SELECT
|
||||||
#define MINESWP_TOGGLE BUTTON_SELECT
|
#define MINESWP_TOGGLE BUTTON_ON
|
||||||
#define MINESWP_DISCOVER BUTTON_ON
|
#define MINESWP_DISCOVER BUTTON_SELECT
|
||||||
#define MINESWP_INFO BUTTON_MODE
|
#define MINESWP_INFO BUTTON_MODE
|
||||||
|
#define MINESWP_RIGHT (BUTTON_ON | BUTTON_RIGHT)
|
||||||
|
#define MINESWP_LEFT (BUTTON_ON | BUTTON_LEFT)
|
||||||
|
|
||||||
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
|
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
|
||||||
(CONFIG_KEYPAD == IPOD_3G_PAD)
|
(CONFIG_KEYPAD == IPOD_3G_PAD)
|
||||||
|
@ -80,6 +80,8 @@ PLUGIN_HEADER
|
||||||
#define MINESWP_TOGGLE BUTTON_PLAY
|
#define MINESWP_TOGGLE BUTTON_PLAY
|
||||||
#define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_PLAY)
|
#define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_PLAY)
|
||||||
#define MINESWP_INFO (BUTTON_SELECT | BUTTON_MENU)
|
#define MINESWP_INFO (BUTTON_SELECT | BUTTON_MENU)
|
||||||
|
#define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT)
|
||||||
|
#define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT)
|
||||||
|
|
||||||
#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
|
#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
|
||||||
#define MINESWP_UP BUTTON_UP
|
#define MINESWP_UP BUTTON_UP
|
||||||
|
@ -89,15 +91,19 @@ PLUGIN_HEADER
|
||||||
#define MINESWP_TOGGLE BUTTON_PLAY
|
#define MINESWP_TOGGLE BUTTON_PLAY
|
||||||
#define MINESWP_DISCOVER BUTTON_SELECT
|
#define MINESWP_DISCOVER BUTTON_SELECT
|
||||||
#define MINESWP_INFO (BUTTON_REC | BUTTON_PLAY)
|
#define MINESWP_INFO (BUTTON_REC | BUTTON_PLAY)
|
||||||
|
#define MINESWP_RIGHT (BUTTON_PLAY | BUTTON_RIGHT)
|
||||||
|
#define MINESWP_LEFT (BUTTON_PLAY | BUTTON_LEFT)
|
||||||
|
|
||||||
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
|
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
|
||||||
#define MINESWP_UP BUTTON_UP
|
#define MINESWP_UP BUTTON_UP
|
||||||
#define MINESWP_DOWN BUTTON_DOWN
|
#define MINESWP_DOWN BUTTON_DOWN
|
||||||
#define MINESWP_QUIT BUTTON_A
|
#define MINESWP_QUIT BUTTON_A
|
||||||
#define MINESWP_START BUTTON_SELECT
|
#define MINESWP_START BUTTON_SELECT
|
||||||
#define MINESWP_TOGGLE BUTTON_SELECT
|
#define MINESWP_TOGGLE BUTTON_POWER
|
||||||
#define MINESWP_DISCOVER BUTTON_POWER
|
#define MINESWP_DISCOVER BUTTON_SELECT
|
||||||
#define MINESWP_INFO BUTTON_MENU
|
#define MINESWP_INFO BUTTON_MENU
|
||||||
|
#define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT)
|
||||||
|
#define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -109,7 +115,7 @@ static struct plugin_api* rb;
|
||||||
|
|
||||||
/* define how numbers are displayed (that way we don't have to */
|
/* define how numbers are displayed (that way we don't have to */
|
||||||
/* worry about fonts) */
|
/* worry about fonts) */
|
||||||
static unsigned char num[9][8] = {
|
static unsigned char num[10][8] = {
|
||||||
/*reading the sprites:
|
/*reading the sprites:
|
||||||
on screen f123
|
on screen f123
|
||||||
4567
|
4567
|
||||||
|
@ -203,6 +209,16 @@ static unsigned char num[9][8] = {
|
||||||
0x28, /* ..O..O.. */
|
0x28, /* ..O..O.. */
|
||||||
0x00, /* ...OO... */
|
0x00, /* ...OO... */
|
||||||
0x00},/* ........ */
|
0x00},/* ........ */
|
||||||
|
/* mine */
|
||||||
|
{0x00, /* ........ */
|
||||||
|
0x00, /* ........ */
|
||||||
|
0x18, /* ...OO... */
|
||||||
|
0x3c, /* ..OOOO.. */
|
||||||
|
0x3c, /* ..OOOO.. */
|
||||||
|
0x18, /* ...OO... */
|
||||||
|
0x00, /* ........ */
|
||||||
|
0x00},/* ........ */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the tile struct
|
/* the tile struct
|
||||||
|
@ -222,49 +238,109 @@ typedef struct tile {
|
||||||
int height = LCD_HEIGHT/8;
|
int height = LCD_HEIGHT/8;
|
||||||
int width = LCD_WIDTH/8;
|
int width = LCD_WIDTH/8;
|
||||||
|
|
||||||
/* the minefield */
|
/* The Minefield. Caution it is defined as Y, X! Not the opposite. */
|
||||||
tile minefield[LCD_HEIGHT/8][LCD_WIDTH/8];
|
tile minefield[LCD_HEIGHT/8][LCD_WIDTH/8];
|
||||||
|
|
||||||
/* total number of mines on the game */
|
/* total number of mines on the game */
|
||||||
int mine_num = 0;
|
int mine_num = 0;
|
||||||
|
|
||||||
/* discovers the tile when player clears one of them */
|
/* percentage of mines on minefield used durring generation */
|
||||||
/* a chain reaction (of discovery) occurs if tile has no mines */
|
int p=16;
|
||||||
/* as neighbors */
|
|
||||||
void discover(int, int);
|
|
||||||
void discover(int x, int y){
|
|
||||||
|
|
||||||
if(x<0) return;
|
/* number of tiles left on the game */
|
||||||
if(y<0) return;
|
int tiles_left;
|
||||||
if(x>width-1) return;
|
|
||||||
if(y>height-1) return;
|
|
||||||
if(minefield[y][x].known) return;
|
|
||||||
|
|
||||||
minefield[y][x].known = 1;
|
/* Because mines are set after the first move... */
|
||||||
if(minefield[y][x].neighbors == 0){
|
bool no_mines = true;
|
||||||
discover(x-1,y-1);
|
|
||||||
discover(x,y-1);
|
/* We need a stack (created on discover()) for the cascade algorithm. */
|
||||||
discover(x+1,y-1);
|
int stack_pos = 0;
|
||||||
discover(x+1,y);
|
|
||||||
discover(x+1,y+1);
|
/* Functions to center the board on screen. */
|
||||||
discover(x,y+1);
|
int c_height(void){
|
||||||
discover(x-1,y+1);
|
return LCD_HEIGHT/16 - height/2;
|
||||||
discover(x-1,y);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int c_width(void){
|
||||||
|
return LCD_WIDTH/16 - width/2;
|
||||||
|
}
|
||||||
|
|
||||||
/* init not mine related elements of the mine field */
|
void push (int *stack, int y, int x){
|
||||||
|
|
||||||
|
if(stack_pos <= height*width){
|
||||||
|
stack_pos++;
|
||||||
|
stack[stack_pos] = y;
|
||||||
|
stack_pos++;
|
||||||
|
stack[stack_pos] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unveil tiles and push them to stack if they are empty. */
|
||||||
|
void unveil(int *stack, int y, int x){
|
||||||
|
|
||||||
|
if(x < c_width() || y < c_height() || x > c_width() + width-1
|
||||||
|
|| y > c_height() + height-1 || minefield[y][x].known
|
||||||
|
|| minefield[y][x].mine || minefield[y][x].flag) return;
|
||||||
|
|
||||||
|
if(minefield[y][x].neighbors == 0){
|
||||||
|
minefield[y][x].known = 1;
|
||||||
|
push(stack, y, x);
|
||||||
|
} else
|
||||||
|
minefield[y][x].known = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void discover(int y, int x){
|
||||||
|
|
||||||
|
int stack[height*width];
|
||||||
|
|
||||||
|
/* Selected tile. */
|
||||||
|
if(x < c_width() || y < c_height() || x > c_width() + width-1
|
||||||
|
|| y > c_height() + height-1 || minefield[y][x].known
|
||||||
|
|| minefield[y][x].mine || minefield[y][x].flag) return;
|
||||||
|
|
||||||
|
minefield[y][x].known = 1;
|
||||||
|
/* Exit if the tile is not empty. (no mines nearby) */
|
||||||
|
if(minefield[y][x].neighbors) return;
|
||||||
|
|
||||||
|
push(stack, y, x);
|
||||||
|
|
||||||
|
/* Scan all nearby tiles. If we meet a tile with a number we just unveil
|
||||||
|
it. If we meet an empty tile, we push the location in stack. For each
|
||||||
|
location in stack we do the same thing. (scan again all nearby tiles) */
|
||||||
|
while(stack_pos){
|
||||||
|
/* Retrieve x, y from stack. */
|
||||||
|
x = stack[stack_pos];
|
||||||
|
y = stack[stack_pos-1];
|
||||||
|
|
||||||
|
/* Pop. */
|
||||||
|
if(stack_pos > 0) stack_pos -= 2;
|
||||||
|
else rb->splash(HZ,true,"ERROR");
|
||||||
|
|
||||||
|
unveil(stack, y-1, x-1);
|
||||||
|
unveil(stack, y-1, x);
|
||||||
|
unveil(stack, y-1, x+1);
|
||||||
|
unveil(stack, y, x+1);
|
||||||
|
unveil(stack, y+1, x+1);
|
||||||
|
unveil(stack, y+1, x);
|
||||||
|
unveil(stack, y+1, x-1);
|
||||||
|
unveil(stack, y, x-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the whole board for a new game. */
|
||||||
void minesweeper_init(void){
|
void minesweeper_init(void){
|
||||||
int i,j;
|
int i,j;
|
||||||
|
|
||||||
for(i=0;i<height;i++){
|
for(i=0;i<LCD_HEIGHT/8;i++){
|
||||||
for(j=0;j<width;j++){
|
for(j=0;j<LCD_WIDTH/8;j++){
|
||||||
minefield[i][j].known = 0;
|
minefield[i][j].known = 0;
|
||||||
minefield[i][j].flag = 0;
|
minefield[i][j].flag = 0;
|
||||||
|
minefield[i][j].mine = 0;
|
||||||
|
minefield[i][j].neighbors = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
no_mines = true;
|
||||||
|
tiles_left = width*height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -275,8 +351,8 @@ void minesweeper_putmines(int p, int x, int y){
|
||||||
int i,j;
|
int i,j;
|
||||||
|
|
||||||
mine_num = 0;
|
mine_num = 0;
|
||||||
for(i=0;i<height;i++){
|
for(i=c_height();i<c_height() + height;i++){
|
||||||
for(j=0;j<width;j++){
|
for(j=c_width();j<c_width() + width;j++){
|
||||||
if(rb->rand()%100<p && !(y==i && x==j)){
|
if(rb->rand()%100<p && !(y==i && x==j)){
|
||||||
minefield[i][j].mine = 1;
|
minefield[i][j].mine = 1;
|
||||||
mine_num++;
|
mine_num++;
|
||||||
|
@ -286,47 +362,83 @@ void minesweeper_putmines(int p, int x, int y){
|
||||||
minefield[i][j].neighbors = 0;
|
minefield[i][j].neighbors = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need to compute the neighbor element for each tile */
|
/* we need to compute the neighbor element for each tile */
|
||||||
for(i=0;i<height;i++){
|
for(i=c_height();i<c_height() + height;i++){
|
||||||
for(j=0;j<width;j++){
|
for(j=c_width();j<c_width() + width;j++){
|
||||||
if(i>0){
|
if(i>0){
|
||||||
if(j>0)
|
if(j>0)
|
||||||
minefield[i][j].neighbors += minefield[i-1][j-1].mine;
|
minefield[i][j].neighbors += minefield[i-1][j-1].mine;
|
||||||
minefield[i][j].neighbors += minefield[i-1][j].mine;
|
minefield[i][j].neighbors += minefield[i-1][j].mine;
|
||||||
if(j<width-1)
|
if(j<c_width() + width-1)
|
||||||
minefield[i][j].neighbors += minefield[i-1][j+1].mine;
|
minefield[i][j].neighbors += minefield[i-1][j+1].mine;
|
||||||
}
|
}
|
||||||
if(j>0)
|
if(j>0)
|
||||||
minefield[i][j].neighbors += minefield[i][j-1].mine;
|
minefield[i][j].neighbors += minefield[i][j-1].mine;
|
||||||
if(j<width-1)
|
if(j<c_width() + width-1)
|
||||||
minefield[i][j].neighbors += minefield[i][j+1].mine;
|
minefield[i][j].neighbors += minefield[i][j+1].mine;
|
||||||
if(i<height-1){
|
if(i<c_height() + height-1){
|
||||||
if(j>0)
|
if(j>0)
|
||||||
minefield[i][j].neighbors += minefield[i+1][j-1].mine;
|
minefield[i][j].neighbors += minefield[i+1][j-1].mine;
|
||||||
minefield[i][j].neighbors += minefield[i+1][j].mine;
|
minefield[i][j].neighbors += minefield[i+1][j].mine;
|
||||||
if(j<width-1)
|
if(j<c_width() + width-1)
|
||||||
minefield[i][j].neighbors += minefield[i+1][j+1].mine;
|
minefield[i][j].neighbors += minefield[i+1][j+1].mine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_mines = false;
|
||||||
|
/* In case the user is lucky and there are no mines positioned. */
|
||||||
|
if(!mine_num && height*width != 1) minesweeper_putmines(p, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A function that will uncover all the board, when the user wins or loses.
|
||||||
|
can easily be expanded, (just a call assigned to a button) as a solver. */
|
||||||
|
void mine_show(void){
|
||||||
|
int i, j, button;
|
||||||
|
|
||||||
|
for(i=c_height();i<c_height() + height;i++){
|
||||||
|
for(j=c_width();j<c_width() + width;j++){
|
||||||
|
#if LCD_DEPTH > 1
|
||||||
|
rb->lcd_set_foreground(LCD_DARKGRAY);
|
||||||
|
rb->lcd_drawrect(j*8,i*8,8,8);
|
||||||
|
rb->lcd_set_foreground(LCD_BLACK);
|
||||||
|
#else
|
||||||
|
rb->lcd_drawrect(j*8,i*8,8,8);
|
||||||
|
#endif
|
||||||
|
if(!minefield[i][j].known){
|
||||||
|
if(minefield[i][j].mine){
|
||||||
|
rb->lcd_set_drawmode(DRMODE_FG);
|
||||||
|
rb->lcd_mono_bitmap(num[9], j*8,i*8,8,8);
|
||||||
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
||||||
|
} else if(minefield[i][j].neighbors){
|
||||||
|
rb->lcd_set_drawmode(DRMODE_FG);
|
||||||
|
rb->lcd_mono_bitmap(num[minefield[i][j].neighbors],
|
||||||
|
j*8,i*8,8,8);
|
||||||
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rb->lcd_update();
|
||||||
|
|
||||||
|
bool k = true;
|
||||||
|
while(k){
|
||||||
|
button = rb->button_get_w_tmo(HZ/10);
|
||||||
|
if(button != BUTTON_NONE && !(button & BUTTON_REL)) k = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* the big and ugly function that is the game */
|
/* the big and ugly function that is the game */
|
||||||
int minesweeper(void)
|
int minesweeper(void)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
int button;
|
int button;
|
||||||
int lastbutton = BUTTON_NONE;
|
int lastbutton = BUTTON_NONE;
|
||||||
|
|
||||||
/* the cursor coordinates */
|
/* the cursor coordinates */
|
||||||
int x=0,y=0;
|
int x=0, y=0;
|
||||||
|
|
||||||
/* number of tiles left on the game */
|
|
||||||
int tiles_left=width*height;
|
|
||||||
|
|
||||||
/* percentage of mines on minefield used durring generation */
|
|
||||||
int p=16;
|
|
||||||
|
|
||||||
/* a usefull string for snprintf */
|
/* a usefull string for snprintf */
|
||||||
char str[30];
|
char str[30];
|
||||||
|
@ -351,27 +463,47 @@ int minesweeper(void)
|
||||||
#elif CONFIG_KEYPAD == IRIVER_H100_PAD
|
#elif CONFIG_KEYPAD == IRIVER_H100_PAD
|
||||||
rb->lcd_puts(0,6,"SELECT to start");
|
rb->lcd_puts(0,6,"SELECT to start");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rb->lcd_update();
|
rb->lcd_update();
|
||||||
|
|
||||||
|
|
||||||
button = rb->button_get(true);
|
button = rb->button_get(true);
|
||||||
switch(button){
|
switch(button){
|
||||||
case MINESWP_DOWN:
|
case MINESWP_DOWN:
|
||||||
|
case (MINESWP_DOWN | BUTTON_REPEAT):
|
||||||
p = (p + 98)%100;
|
p = (p + 98)%100;
|
||||||
|
/* Don't let the user play without mines. */
|
||||||
|
if(!p) p = 98;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MINESWP_UP:
|
case MINESWP_UP:
|
||||||
|
case (MINESWP_UP | BUTTON_REPEAT):
|
||||||
p = (p + 2)%100;
|
p = (p + 2)%100;
|
||||||
|
/* Don't let the user play without mines. */
|
||||||
|
if(!p) p = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_RIGHT:
|
case BUTTON_RIGHT:
|
||||||
|
case (BUTTON_RIGHT | BUTTON_REPEAT):
|
||||||
height = height%(LCD_HEIGHT/8)+1;
|
height = height%(LCD_HEIGHT/8)+1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_LEFT:
|
case BUTTON_LEFT:
|
||||||
|
case (BUTTON_LEFT | BUTTON_REPEAT):
|
||||||
width = width%(LCD_WIDTH/8)+1;
|
width = width%(LCD_WIDTH/8)+1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MINESWP_RIGHT:
|
||||||
|
case (MINESWP_RIGHT | BUTTON_REPEAT):
|
||||||
|
height--;
|
||||||
|
if(height < 1) height = LCD_HEIGHT/8;
|
||||||
|
if(height > LCD_HEIGHT) height = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MINESWP_LEFT:
|
||||||
|
case (MINESWP_LEFT | BUTTON_REPEAT):
|
||||||
|
width--;
|
||||||
|
if(width < 1) width = LCD_WIDTH/8;
|
||||||
|
if(width > LCD_WIDTH) width = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case MINESWP_START:/* start playing */
|
case MINESWP_START:/* start playing */
|
||||||
i = 1;
|
i = 1;
|
||||||
|
@ -395,6 +527,8 @@ int minesweeper(void)
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
minesweeper_init();
|
minesweeper_init();
|
||||||
|
x = c_width();
|
||||||
|
y = c_height();
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* play *
|
* play *
|
||||||
|
@ -406,8 +540,8 @@ int minesweeper(void)
|
||||||
rb->lcd_clear_display();
|
rb->lcd_clear_display();
|
||||||
|
|
||||||
/*display the mine field */
|
/*display the mine field */
|
||||||
for(i=0;i<height;i++){
|
for(i=c_height();i<c_height() + height;i++){
|
||||||
for(j=0;j<width;j++){
|
for(j=c_width();j<c_width() + width;j++){
|
||||||
#if LCD_DEPTH > 1
|
#if LCD_DEPTH > 1
|
||||||
rb->lcd_set_foreground(LCD_DARKGRAY);
|
rb->lcd_set_foreground(LCD_DARKGRAY);
|
||||||
rb->lcd_drawrect(j*8,i*8,8,8);
|
rb->lcd_drawrect(j*8,i*8,8,8);
|
||||||
|
@ -416,11 +550,10 @@ int minesweeper(void)
|
||||||
rb->lcd_drawrect(j*8,i*8,8,8);
|
rb->lcd_drawrect(j*8,i*8,8,8);
|
||||||
#endif
|
#endif
|
||||||
if(minefield[i][j].known){
|
if(minefield[i][j].known){
|
||||||
if(minefield[i][j].mine){
|
if(minefield[i][j].neighbors){
|
||||||
rb->lcd_putsxy(j*8+1,i*8+1,"b");
|
|
||||||
} else if(minefield[i][j].neighbors){
|
|
||||||
rb->lcd_set_drawmode(DRMODE_FG);
|
rb->lcd_set_drawmode(DRMODE_FG);
|
||||||
rb->lcd_mono_bitmap(num[minefield[i][j].neighbors],j*8,i*8,8,8);
|
rb->lcd_mono_bitmap(num[minefield[i][j].neighbors],
|
||||||
|
j*8,i*8,8,8);
|
||||||
rb->lcd_set_drawmode(DRMODE_SOLID);
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
||||||
}
|
}
|
||||||
} else if(minefield[i][j].flag) {
|
} else if(minefield[i][j].flag) {
|
||||||
|
@ -451,29 +584,33 @@ int minesweeper(void)
|
||||||
/* quit minesweeper (you really shouldn't use this button ...) */
|
/* quit minesweeper (you really shouldn't use this button ...) */
|
||||||
case MINESWP_QUIT:
|
case MINESWP_QUIT:
|
||||||
return MINESWEEPER_QUIT;
|
return MINESWEEPER_QUIT;
|
||||||
|
|
||||||
/* move cursor left */
|
/* move cursor left */
|
||||||
case BUTTON_LEFT:
|
case BUTTON_LEFT:
|
||||||
case (BUTTON_LEFT | BUTTON_REPEAT):
|
case (BUTTON_LEFT | BUTTON_REPEAT):
|
||||||
x = (x + width - 1)%width;
|
if(x<=c_width()) x = width + c_width();
|
||||||
|
x = x-1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* move cursor right */
|
/* move cursor right */
|
||||||
case BUTTON_RIGHT:
|
case BUTTON_RIGHT:
|
||||||
case (BUTTON_RIGHT | BUTTON_REPEAT):
|
case (BUTTON_RIGHT | BUTTON_REPEAT):
|
||||||
x = (x + 1)%width;
|
if(x>=width + c_width() - 1) x = c_width() - 1;
|
||||||
|
x = x+1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* move cursor down */
|
/* move cursor down */
|
||||||
case MINESWP_DOWN:
|
case MINESWP_DOWN:
|
||||||
case (MINESWP_DOWN | BUTTON_REPEAT):
|
case (MINESWP_DOWN | BUTTON_REPEAT):
|
||||||
y = (y + 1)%height;
|
if(y>=height + c_height() - 1) y = c_height() - 1;
|
||||||
|
y = y+1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* move cursor up */
|
/* move cursor up */
|
||||||
case MINESWP_UP:
|
case MINESWP_UP:
|
||||||
case (MINESWP_UP | BUTTON_REPEAT):
|
case (MINESWP_UP | BUTTON_REPEAT):
|
||||||
y = (y + height - 1)%height;
|
if(y<=c_height()) y = height + c_height();
|
||||||
|
y = y-1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* discover a tile (and it's neighbors if .neighbors == 0) */
|
/* discover a tile (and it's neighbors if .neighbors == 0) */
|
||||||
|
@ -484,14 +621,17 @@ int minesweeper(void)
|
||||||
if(minefield[y][x].flag) break;
|
if(minefield[y][x].flag) break;
|
||||||
/* we put the mines on the first "click" so that you don't */
|
/* we put the mines on the first "click" so that you don't */
|
||||||
/* lose on the first "click" */
|
/* lose on the first "click" */
|
||||||
if(tiles_left == width*height) minesweeper_putmines(p,x,y);
|
if(tiles_left == width*height && no_mines)
|
||||||
discover(x,y);
|
minesweeper_putmines(p,x,y);
|
||||||
|
|
||||||
|
discover(y, x);
|
||||||
|
|
||||||
if(minefield[y][x].mine){
|
if(minefield[y][x].mine){
|
||||||
return MINESWEEPER_LOSE;
|
return MINESWEEPER_LOSE;
|
||||||
}
|
}
|
||||||
tiles_left = 0;
|
tiles_left = 0;
|
||||||
for(i=0;i<height;i++){
|
for(i=c_height();i<c_height() + height;i++){
|
||||||
for(j=0;j<width;j++){
|
for(j=c_width();j<c_width() + width;j++){
|
||||||
if(minefield[i][j].known == 0) tiles_left++;
|
if(minefield[i][j].known == 0) tiles_left++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -515,13 +655,16 @@ int minesweeper(void)
|
||||||
/* show how many mines you think you have found and how many */
|
/* show how many mines you think you have found and how many */
|
||||||
/* there really are on the game */
|
/* there really are on the game */
|
||||||
case MINESWP_INFO:
|
case MINESWP_INFO:
|
||||||
|
if(no_mines) break;
|
||||||
tiles_left = 0;
|
tiles_left = 0;
|
||||||
for(i=0;i<height;i++){
|
for(i=c_height();i<c_height() + height;i++){
|
||||||
for(j=0;j<width;j++){
|
for(j=c_width();j<c_width() + width;j++){
|
||||||
if(minefield[i][j].flag) tiles_left++;
|
if(minefield[i][j].flag && !minefield[i][j].known)
|
||||||
|
tiles_left++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb->splash(HZ*2, true, "You found %d mines out of %d", tiles_left, mine_num);
|
rb->splash(HZ*2, true, "You found %d mines out of %d",
|
||||||
|
tiles_left, mine_num);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -547,11 +690,15 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
while(!exit) {
|
while(!exit) {
|
||||||
switch(minesweeper()){
|
switch(minesweeper()){
|
||||||
case MINESWEEPER_WIN:
|
case MINESWEEPER_WIN:
|
||||||
rb->splash(HZ*2, true, "You Win :)");
|
rb->splash(HZ*2, true, "You Won! Press a key");
|
||||||
|
rb->lcd_clear_display();
|
||||||
|
mine_show();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MINESWEEPER_LOSE:
|
case MINESWEEPER_LOSE:
|
||||||
rb->splash(HZ*2, true, "You Lose :(");
|
rb->splash(HZ*2, true, "You Lost! Press a key");
|
||||||
|
rb->lcd_clear_display();
|
||||||
|
mine_show();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MINESWEEPER_USB:
|
case MINESWEEPER_USB:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue