Ejemplo n.º 1
0
/* the big and ugly game function */
enum minesweeper_status minesweeper( void )
{
    int i, j;
    int button;
#if defined(HAVE_TOUCHSCREEN) || defined(MINESWP_TOGGLE_PRE)
    int lastbutton = BUTTON_NONE;
#endif

    /* the cursor coordinates */
    int x=0, y=0;

    /**
     * Show the menu
     */
    if( ( i = menu() ) != MINESWEEPER_WIN ) return i;

    /**
     * Init game
     */
    top = (LCD_HEIGHT-height*TileSize)/2;
    left = (LCD_WIDTH-width*TileSize)/2;

#ifdef HAVE_TOUCHSCREEN
    mine_raster.tl_x = left;
    mine_raster.tl_y = top;
    mine_raster.width = width*TileSize;
    mine_raster.height = height*TileSize;
#endif

    rb->srand( *rb->current_tick );
    minesweeper_init();
    x = 0;
    y = 0;

    /**
     * Play
     */
    while( true )
    {

        /* clear the screen buffer */
#ifdef HAVE_LCD_COLOR
        rb->lcd_set_background( BackgroundColor );
#endif
        rb->lcd_clear_display();

        /* display the mine field */
        for( i = 0; i < height; i++ )
        {
            for( j = 0; j < width; j++ )
            {
                if( minefield[i][j].known )
                {
                    draw_tile( minefield[i][j].neighbors, j, i );
                }
                else if(minefield[i][j].flag)
                {
                    draw_tile( Flag, j, i );
                }
                else
                {
                    draw_tile( Unknown, j, i );
                }
            }
        }

        /* display the cursor */
        invert_tile( x, y );

        /* update the screen */
        rb->lcd_update();

        button = rb->button_get(true);
#ifdef HAVE_TOUCHSCREEN
        if(button & BUTTON_TOUCHSCREEN)
        {
            struct ts_raster_result res;
            if(touchscreen_map_raster(&mine_raster, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff, &res) == 1)
            {
                button &= ~BUTTON_TOUCHSCREEN;
                lastbutton &= ~BUTTON_TOUCHSCREEN;

                if(button & BUTTON_REPEAT && lastbutton != MINESWP_TOGGLE && lastbutton ^ BUTTON_REPEAT)
                    button = MINESWP_TOGGLE;
                else if(button == BUTTON_REL && lastbutton ^ BUTTON_REPEAT)
                    button = MINESWP_DISCOVER;
                else
                    button |= BUTTON_TOUCHSCREEN;

                x = res.x;
                y = res.y;
            }
        }
#endif
        switch(button)
        {
            /* quit minesweeper (you really shouldn't use this button ...) */
#ifdef MINESWP_RC_QUIT
        case MINESWP_RC_QUIT:
#endif
        case MINESWP_QUIT:
            return MINESWEEPER_QUIT;

        /* move cursor left */
        case MINESWP_LEFT:
        case MINESWP_LEFT|BUTTON_REPEAT:
            if( --x < 0)
                x += width;
            break;

        /* move cursor right */
        case MINESWP_RIGHT:
        case MINESWP_RIGHT|BUTTON_REPEAT:
            if( ++x >= width )
                x -= width;
            break;

        /* move cursor down */
        case MINESWP_DOWN:
        case MINESWP_DOWN|BUTTON_REPEAT:
            if( ++y >= height )
                y -= height;
            break;

        /* move cursor up */
        case MINESWP_UP:
        case MINESWP_UP|BUTTON_REPEAT:
            if( --y < 0 )
                y += height;
            break;

            /*move cursor though the entire field*/
#ifdef MINESWP_SCROLLWHEEL
        case MINESWP_NEXT:
        case MINESWP_NEXT|BUTTON_REPEAT:
            if (x == width -1 ) {
                if( ++y >= height )
                    y -= height;
            }
            if( ++x >= width )
                x -= width;
            break;

        case MINESWP_PREV:
        case MINESWP_PREV|BUTTON_REPEAT:
            if (x == 0) {
                if( --y < 0 )
                    y += height;
            }
            if( --x < 0 )
                x += width;
            break;
#endif
        /* discover a tile (and it's neighbors if .neighbors == 0) */
        case MINESWP_DISCOVER:
#ifdef MINESWP_DISCOVER2
        case MINESWP_DISCOVER2:
#endif
            if( minefield[y][x].flag ) break;
            /* we put the mines on the first "click" so that you don't
             * lose on the first "click" */
            if( tiles_left == width*height && no_mines )
                minesweeper_putmines(percent,x,y);

            if( discover( y, x, true ) )
            {
                minefield[y][x].known = 1;
                return MINESWEEPER_LOSE;
            }

            tiles_left = count_tiles_left();
            if( tiles_left == mine_num )
            {
                return MINESWEEPER_WIN;
            }
            break;

        /* toggle flag under cursor */
        case MINESWP_TOGGLE:
#ifdef MINESWP_TOGGLE_PRE
            if( lastbutton != MINESWP_TOGGLE_PRE )
                break;
#endif
#ifdef MINESWP_TOGGLE2
        case MINESWP_TOGGLE2:
#endif
            if( !minefield[y][x].known )
                minefield[y][x].flag = !minefield[y][x].flag;
            break;

        /* show how many mines you think you have found and how many
         * there really are on the game */
        case MINESWP_INFO:
            if( no_mines )
                break;
            int flags_used = count_flags();
            if (flags_used == 1) {
                rb->splashf( HZ*2, "You marked 1 field. There are %d mines.",
                             mine_num );
            }
            else
            {
                rb->splashf( HZ*2, "You marked %d fields. There are %d mines.",
                             flags_used, mine_num );
            }
            break;

        default:
            if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
                return MINESWEEPER_USB;
            break;
        }
#if defined(HAVE_TOUCHSCREEN) || defined(MINESWP_TOGGLE_PRE)
        if( button != BUTTON_NONE )
            lastbutton = button;
#endif
    }

}
Ejemplo n.º 2
0
/* the big and ugly function that is the game */
int minesweeper(void)
{
    int i,j;
    int button;
    int lastbutton = BUTTON_NONE;

    /* the cursor coordinates */
    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 */
    char str[30];

    /* welcome screen where player can chose mine percentage */
    i = 0;
    while(true){
        rb->lcd_clear_display();

        rb->lcd_puts(0,0,"Mine Sweeper");

        rb->snprintf(str, 20, "%d%% mines", p);
        rb->lcd_puts(0,2,str);
        rb->lcd_puts(0,3,"down / up");
        rb->snprintf(str, 20, "%d cols x %d rows", width, height);
        rb->lcd_puts(0,4,str);
        rb->lcd_puts(0,5,"left x right ");
#if CONFIG_KEYPAD == RECORDER_PAD
        rb->lcd_puts(0,6,"ON to start");
#elif CONFIG_KEYPAD == ONDIO_PAD
        rb->lcd_puts(0,6,"MODE to start");
#elif CONFIG_KEYPAD == IRIVER_H100_PAD
        rb->lcd_puts(0,6,"SELECT to start");
#endif

        rb->lcd_update();


        button = rb->button_get(true);
        switch(button){
            case BUTTON_DOWN:
                p = (p + 98)%100;
                break;

            case BUTTON_UP:
                p = (p + 2)%100;
                break;

            case BUTTON_RIGHT:
                height = height%(LCD_HEIGHT/8)+1;
                break;

            case BUTTON_LEFT:
                width = width%(LCD_WIDTH/8)+1;
                break;

            case MINESWP_START:/* start playing */
                i = 1;
                break;

            case MINESWP_QUIT:/* quit program */
                return MINESWEEPER_QUIT;

            default:
                if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
                    return MINESWEEPER_USB;
                break;
        }
        if(i==1)
            break;
    }


    /********************
    *       init        *
    ********************/

    minesweeper_init();

    /**********************
    *        play         *
    **********************/

    while(true){

        //clear the screen buffer
        rb->lcd_clear_display();

        //display the mine field
        for(i=0;i<height;i++){
            for(j=0;j<width;j++){
#if LCD_DEPTH > 1
                rb->lcd_set_foreground(DARK_GRAY);
                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_putsxy(j*8+1,i*8+1,"b");
                    } 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);
                    }
                } else if(minefield[i][j].flag) {
                    rb->lcd_drawline(j*8+2,i*8+2,j*8+5,i*8+5);
                    rb->lcd_drawline(j*8+2,i*8+5,j*8+5,i*8+2);
                } else {
#if LCD_DEPTH > 1
                    rb->lcd_set_foreground(LIGHT_GRAY);
                    rb->lcd_fillrect(j*8+1,i*8+1,6,6);
                    rb->lcd_set_foreground(LCD_BLACK);
#else
                    rb->lcd_fillrect(j*8+2,i*8+2,4,4);
#endif
                }
            }
        }

        /* display the cursor */
        rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
        rb->lcd_fillrect(x*8,y*8,8,8);
        rb->lcd_set_drawmode(DRMODE_SOLID);

        /* update the screen */
        rb->lcd_update();

        button = rb->button_get(true);
        switch(button){
            /* quit minesweeper (you really shouldn't use this button ...) */
            case MINESWP_QUIT:
                return MINESWEEPER_QUIT;

                /* move cursor left */
            case BUTTON_LEFT:
            case (BUTTON_LEFT | BUTTON_REPEAT):
                x = (x + width - 1)%width;
                break;

                /* move cursor right */
            case BUTTON_RIGHT:
            case (BUTTON_RIGHT | BUTTON_REPEAT):
                x = (x + 1)%width;
                break;

                /* move cursor down */
            case BUTTON_DOWN:
            case (BUTTON_DOWN | BUTTON_REPEAT):
                y = (y + 1)%height;
                break;

                /* move cursor up */
            case BUTTON_UP:
            case (BUTTON_UP | BUTTON_REPEAT):
                y = (y + height - 1)%height;
                break;

                /* discover a tile (and it's neighbors if .neighbors == 0) */
            case MINESWP_DISCOVER:
#ifdef MINESWP_DISCOVER2
            case MINESWP_DISCOVER2:
#endif
                if(minefield[y][x].flag) break;
                /* we put the mines on the first "click" so that you don't */
                /* lose on the first "click" */
                if(tiles_left == width*height) minesweeper_putmines(p,x,y);
                discover(x,y);
                if(minefield[y][x].mine){
                    return MINESWEEPER_LOSE;
                }
                tiles_left = 0;
                for(i=0;i<height;i++){
                    for(j=0;j<width;j++){
                         if(minefield[i][j].known == 0) tiles_left++;
                    }
                }
                if(tiles_left == mine_num){
                    return MINESWEEPER_WIN;
                }
                break;

                /* toggle flag under cursor */
            case MINESWP_TOGGLE:
#ifdef MINESWP_TOGGLE_PRE
                if (lastbutton != MINESWP_TOGGLE_PRE)
                    break;
#endif
#ifdef MINESWP_TOGGLE2
            case MINESWP_TOGGLE2:
#endif
                minefield[y][x].flag = (minefield[y][x].flag + 1)%2;
                break;

                /* show how many mines you think you have found and how many */
                /* there really are on the game */
            case MINESWP_INFO:
                tiles_left = 0;
                for(i=0;i<height;i++){
                    for(j=0;j<width;j++){
                         if(minefield[i][j].flag) tiles_left++;
                    }
                }
                rb->splash(HZ*2, true, "You found %d mines out of %d", tiles_left, mine_num);
                break;

            default:
                if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
                    return MINESWEEPER_USB;
                break;
        }
        if (button != BUTTON_NONE)
            lastbutton = button;
    }

}