From d58ab78e2cf89e1279536835a16ba9e2b32142a8 Mon Sep 17 00:00:00 2001 From: Robert Hak Date: Sun, 16 Jun 2002 23:24:22 +0000 Subject: first there was tetris, now we have sokoban git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1020 a1c6a512-1295-4272-9138-f99709370657 --- apps/recorder/sokoban.c | 586 ++++++++++++++++++++++++++++++++++++++++++++++++ apps/recorder/sokoban.h | 29 +++ 2 files changed, 615 insertions(+) create mode 100644 apps/recorder/sokoban.c create mode 100644 apps/recorder/sokoban.h diff --git a/apps/recorder/sokoban.c b/apps/recorder/sokoban.c new file mode 100644 index 0000000000..159516e361 --- /dev/null +++ b/apps/recorder/sokoban.c @@ -0,0 +1,586 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: sokoban.c,v 0.01 2002/06/15 + * + * Copyright (C) 2002 Eric Linenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" + +#ifdef HAVE_LCD_BITMAP + +#include "sokoban.h" +#include "lcd.h" +#include "button.h" +#include "kernel.h" + +#ifdef SIMULATOR +#include +#endif +#include + +#define SOKOBAN_TITLE "Sokoban" +#define SOKOBAN_TITLE_FONT 2 +#define NUM_LEVELS 4 + +int board[16][20]; +int current_level=0; +int moves=0; +int row=0; +int col=0; +int boxes_to_go=0; +int current_spot=1; + +/* 320 boxes per level */ +int levels[320*NUM_LEVELS] = { +/* level 01 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,3,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,1,2,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,2,4,1,4,3,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,3,1,4,5,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,2,2,4,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,2,3,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/* level 02 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,2,1,1,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,2,5,4,4,2,0,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,2,1,4,1,2,0,2,3,2,0,0,0,0,0,0, +0,0,0,0,0,2,2,2,1,2,2,2,3,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,1,1,1,1,3,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,1,1,1,2,1,1,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,1,1,1,2,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/* level 03 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,1,1,1,1,1,2,2,2,0,0,0,0,0, +0,0,0,0,0,2,2,4,2,2,2,1,1,1,2,0,0,0,0,0, +0,0,0,0,0,2,1,5,1,4,1,1,4,1,2,0,0,0,0,0, +0,0,0,0,0,2,1,3,3,2,1,4,1,2,2,0,0,0,0,0, +0,0,0,0,0,2,2,3,3,2,1,1,1,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/* level 04 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,2,2,1,1,3,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,1,1,1,4,1,1,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,1,4,4,1,4,3,2,0,0,0,0,0,0, +0,0,0,0,0,0,2,2,5,2,2,3,3,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +/* level 40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0, +0,0,0,0,0,2,1,1,1,1,1,1,2,0,0,0,0,0,0,0, +0,0,0,0,0,2,1,5,1,4,2,1,2,0,0,0,0,0,0,0, +0,0,0,0,0,2,2,1,2,1,1,1,2,0,0,0,0,0,0,0, +0,0,0,0,0,2,1,4,2,3,2,1,2,0,0,0,0,0,0,0, +0,0,0,0,0,2,1,1,3,4,3,4,2,0,0,0,0,0,0,0, +0,0,0,0,0,2,2,1,2,3,2,1,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,1,2,3,1,1,2,2,0,0,0,0,0,0, +0,0,0,0,0,2,2,1,4,3,2,1,1,2,0,0,0,0,0,0, +0,0,0,0,0,2,1,1,2,1,4,1,1,2,0,0,0,0,0,0, +0,0,0,0,0,2,1,1,1,1,1,2,2,2,0,0,0,0,0,0, +0,0,0,0,0,2,1,1,2,2,2,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 */ +}; + + + +void load_level(int level_to_load) { + int a = 0; + int b = 0; + int c = 0; + + /* load level into board */ + /* get to the current level in the level array */ + a = level_to_load*320; + + for(b=0 ; b<16 ; b++) { + for (c=0 ; c<20 ; c++) { + board[b][c] = levels[a]; + a++; + if (board[b][c]==5) { + row = b; + col = c; + } + if (board[b][c]==3) + boxes_to_go++; + } + } + return; +} + +void update_screen(void) { + int b = 0; + int c = 0; + char s[25]; + + /* load the board to the screen */ + for(b=0 ; b<16 ; b++) { + for (c=0 ; c<20 ; c++) { + + /* this is a black space */ + if (board[b][c]==0) { + lcd_drawrect (c*4, b*4, c*4+3, b*4+3); + lcd_drawrect (c*4+1, b*4+1, c*4+2, b*4+2); + } + /* this is a wall */ + if (board[b][c]==2) { + lcd_drawpixel (c*4, b*4); + lcd_drawpixel (c*4+2, b*4); + lcd_drawpixel (c*4+1, b*4+1); + lcd_drawpixel (c*4+3, b*4+1); + lcd_drawpixel (c*4, b*4+2); + lcd_drawpixel (c*4+2, b*4+2); + lcd_drawpixel (c*4+1, b*4+3); + lcd_drawpixel (c*4+3, b*4+3); + } + /* this is a box */ + if (board[b][c]==4) { + lcd_drawrect (c*4, b*4, c*4+3, b*4+3); + } + /* this is a home location */ + if (board[b][c]==3) { + lcd_drawrect (c*4+1, b*4+1, c*4+2, b*4+2); + } + /* this is you */ + if (board[b][c]==5) { + lcd_drawline (c*4+1, b*4, c*4+2, b*4); + lcd_drawline (c*4, b*4+1, c*4+3, b*4+1); + lcd_drawline (c*4+1, b*4+2, c*4+2, b*4+2); + lcd_drawpixel (c*4, b*4+3); + lcd_drawpixel (c*4+3, b*4+3); + } + /* this is a box on a home spot */ + if (board[b][c]==7) { + lcd_drawrect (c*4, b*4, c*4+3, b*4+3); + lcd_drawrect (c*4+1, b*4+1, c*4+2, b*4+2); + } + } + } + + + snprintf (s, sizeof(s), "%d", current_level+1); + lcd_putsxy (86, 20, s, 0); + snprintf (s, sizeof(s), "%d", moves); + lcd_putsxy (86, 52, s, 0); + + lcd_drawrect (80,0,111,31); + lcd_drawrect (80,32,111,63); + lcd_putsxy (81, 10, "Level", 0); + lcd_putsxy (81, 42, "Moves", 0); + /* print out the screen */ + lcd_update(); +} + + + +void sokoban_loop(void) { + int ii = 0; + int b = 0; + moves = 0; + current_level = 0; + load_level(current_level); + update_screen(); + + while(1) { + b = button_get(false); + + if ( b & BUTTON_OFF ) { + /* get out of here */ + return; + } + + + if ( b & BUTTON_F1 ) { + /* get out of here */ + boxes_to_go=0; + } + + if ( b & BUTTON_LEFT ) { + /* if it is a blank spot */ + if (board[row][col-1]==1) { + board[row][col-1]=5; + board[row][col]=current_spot; + current_spot=1; + col--; + moves++; + } + /* if it is a home spot */ + else if (board[row][col-1]==3) { + board[row][col-1]=5; + board[row][col]=current_spot; + current_spot=3; + col--; + moves++; + } + else if (board[row][col-1]==4) { + /* if there is a wall then do not move the box */ + if(board[row][col-2]==2) { + /* do nothing */ + } + /* if we are going from blank to blank */ + else if(board[row][col-2]==1) { + board[row][col-2]=board[row][col-1]; + board[row][col-1]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + col--; + moves++; + } + /* if we are going from a blank to home */ + else if(board[row][col-2]==3) { + board[row][col-2]=7; + board[row][col-1]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + col--; + boxes_to_go--; + moves++; + } + } + else if (board[row][col-1]==7) { + /* if there is a wall then do not move the box */ + if(board[row][col-2]==2) { + /* do nothing */ + } + /* we are going from a home to a blank */ + else if(board[row][col-2]==1) { + board[row][col-2]=4; + board[row][col-1]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + col--; + boxes_to_go++; + moves++; + } + /* if we are going from a home to home */ + else if(board[row][col-2]==3) { + board[row][col-2]=7; + board[row][col-1]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + col--; + moves++; + } + } + lcd_clear_display(); + update_screen(); + } + + + if ( b & BUTTON_RIGHT ) { + /* if it is a blank spot */ + if (board[row][col+1]==1) { + board[row][col+1]=5; + board[row][col]=current_spot; + current_spot=1; + col++; + moves++; + } + /* if it is a home spot */ + else if (board[row][col+1]==3) { + board[row][col+1]=5; + board[row][col]=current_spot; + current_spot=3; + col++; + moves++; + } + else if (board[row][col+1]==4) { + /* if there is a wall then do not move the box */ + if(board[row][col+2]==2) { + /* do nothing */ + } + /* if we are going from blank to blank */ + else if(board[row][col+2]==1) { + board[row][col+2]=board[row][col+1]; + board[row][col+1]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + col++; + moves++; + } + /* if we are going from a blank to home */ + else if(board[row][col+2]==3) { + board[row][col+2]=7; + board[row][col+1]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + col++; + boxes_to_go--; + moves++; + } + } + else if (board[row][col+1]==7) { + /* if there is a wall then do not move the box */ + if(board[row][col+2]==2) { + /* do nothing */ + } + /* we are going from a home to a blank */ + else if(board[row][col+2]==1) { + board[row][col+2]=4; + board[row][col+1]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + col++; + boxes_to_go++; + moves++; + } + /* if we are going from a home to home */ + else if(board[row][col+2]==3) { + board[row][col+2]=7; + board[row][col+1]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + col++; + moves++; + } + } + lcd_clear_display(); + update_screen(); + } + + if ( b & BUTTON_UP ) { + /* if it is a blank spot */ + if (board[row-1][col]==1) { + board[row-1][col]=5; + board[row][col]=current_spot; + current_spot=1; + row--; + moves++; + } + /* if it is a home spot */ + else if (board[row-1][col]==3) { + board[row-1][col]=5; + board[row][col]=current_spot; + current_spot=3; + row--; + moves++; + } + else if (board[row-1][col]==4) { + /* if there is a wall then do not move the box */ + if(board[row-2][col]==2) { + /* do nothing */ + } + /* if we are going from blank to blank */ + else if(board[row-2][col]==1) { + board[row-2][col]=board[row-1][col]; + board[row-1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + row--; + moves++; + } + /* if we are going from a blank to home */ + else if(board[row-2][col]==3) { + board[row-2][col]=7; + board[row-1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + row--; + boxes_to_go--; + moves++; + } + } + else if (board[row-1][col]==7) { + /* if there is a wall then do not move the box */ + if(board[row-2][col]==2) { + /* do nothing */ + } + /* we are going from a home to a blank */ + else if(board[row-2][col]==1) { + board[row-2][col]=4; + board[row-1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + row--; + boxes_to_go++; + moves++; + } + /* if we are going from a home to home */ + else if(board[row-2][col]==3) { + board[row-2][col]=7; + board[row-1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + row--; + moves++; + } + } + lcd_clear_display(); + update_screen(); + } + + if ( b & BUTTON_DOWN ) { + /* if it is a blank spot */ + if (board[row+1][col]==1) { + board[row+1][col]=5; + board[row][col]=current_spot; + current_spot=1; + row++; + moves++; + } + /* if it is a home spot */ + else if (board[row+1][col]==3) { + board[row+1][col]=5; + board[row][col]=current_spot; + current_spot=3; + row++; + moves++; + } + else if (board[row+1][col]==4) { + /* if there is a wall then do not move the box */ + if(board[row+2][col]==2) { + /* do nothing */ + } + /* if we are going from blank to blank */ + else if(board[row+2][col]==1) { + board[row+2][col]=board[row+1][col]; + board[row+1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + row++; + moves++; + } + /* if we are going from a blank to home */ + else if(board[row+2][col]==3) { + board[row+2][col]=7; + board[row+1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=1; + row++; + boxes_to_go--; + moves++; + } + } + else if (board[row+1][col]==7) { + /* if there is a wall then do not move the box */ + if(board[row+2][col]==2) { + /* do nothing */ + } + /* we are going from a home to a blank */ + else if(board[row+2][col]==1) { + board[row+2][col]=4; + board[row+1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + row++; + boxes_to_go++; + moves++; + } + /* if we are going from a home to home */ + else if(board[row+2][col]==3) { + board[row+2][col]=7; + board[row+1][col]=board[row][col]; + board[row][col]=current_spot; + current_spot=3; + row++; + moves++; + } + } + lcd_clear_display(); + update_screen(); + } + + if (boxes_to_go==0) { + moves=0; + current_level++; + if (current_level == NUM_LEVELS) { + lcd_clear_display(); + lcd_putsxy(10, 20, "YOU WIN!!", 2); + + lcd_update(); + for (ii=0 ; ii<20 ; ii++) { + lcd_invertrect(0,0,111,63); + lcd_update(); + } + return; + } + load_level(current_level); + lcd_clear_display(); + update_screen(); + } + } +} + + +void sokoban(void) +{ + int w, h; + int len = strlen(SOKOBAN_TITLE); + + lcd_getfontsize(SOKOBAN_TITLE_FONT, &w, &h); + + /* Get horizontel centering for text */ + len *= w; + if (len%2 != 0) + len = ((len+1)/2)+(w/2); + else + len /= 2; + + if (h%2 != 0) + h = (h/2)+1; + else + h /= 2; + + lcd_clear_display(); + lcd_putsxy(LCD_WIDTH/2-len, (LCD_HEIGHT/2)-h, SOKOBAN_TITLE, + SOKOBAN_TITLE_FONT); + lcd_putsxy( 3,42, "[Off] to stop", 0); + lcd_putsxy( 3,52, "[F1] + level",0); + + lcd_update(); + sleep(HZ*2); + lcd_clear_display(); + sokoban_loop(); +} + +#endif diff --git a/apps/recorder/sokoban.h b/apps/recorder/sokoban.h new file mode 100644 index 0000000000..8e6c54c43e --- /dev/null +++ b/apps/recorder/sokoban.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Robert E. Hak + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __SOKOBAN__ +#define __SOKOBAN__ + +void load_level(int); +void update_screen(void); +void sokoban_loop(void); +void sokoban(void); + +#endif /*__SOKOBAN__ */ + -- cgit v1.2.3