From 5d33b5b68fb2956df419322da613c3fc27177bc6 Mon Sep 17 00:00:00 2001 From: Eric Linenberg Date: Tue, 10 Sep 2002 15:55:37 +0000 Subject: [PATCH] classic snake game by Itai Shaked git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2260 a1c6a512-1295-4272-9138-f99709370657 --- apps/games_menu.c | 6 +- apps/recorder/snake.c | 266 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 apps/recorder/snake.c diff --git a/apps/games_menu.c b/apps/games_menu.c index 49f491753f..dd0c671be4 100644 --- a/apps/games_menu.c +++ b/apps/games_menu.c @@ -35,6 +35,7 @@ #include "sokoban.h" #include "wormlet.h" extern Menu tetris(void); +extern Menu snake(void); Menu games_menu(void) { @@ -42,9 +43,10 @@ Menu games_menu(void) Menu result; struct menu_items items[] = { - { "Tetris", tetris }, + { "Tetris", tetris }, { "Sokoban", sokoban }, - { "Wormlet", wormlet } + { "Wormlet", wormlet }, + { "Snake", snake } }; m=menu_init( items, sizeof items / sizeof(struct menu_items) ); diff --git a/apps/recorder/snake.c b/apps/recorder/snake.c new file mode 100644 index 0000000000..b0e42d8fd0 --- /dev/null +++ b/apps/recorder/snake.c @@ -0,0 +1,266 @@ +/* +Snake! + +by Itai Shaked + +ok, a little explanation - +board holds the snake and apple position - 1+ - snake body (the number +represents the age [1 is the snake's head]). +-1 is an apple, and 0 is a clear spot. +dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left; + +(i'll write more later) +*/ + +#include "sprintf.h" + + +#include "config.h" +#include "lcd.h" +#include "button.h" +#include "kernel.h" +#include "menu.h" + + +int board[28][16],snakelength; +unsigned int score,hiscore=0; +short dir,frames,apple,level=1,dead=0; + +int rand_num (int range) { + return current_tick % range; +} + +void die (void) { + char pscore[5],hscore[17]; + lcd_clear_display(); + snprintf(pscore,sizeof(pscore),"%d",score); + lcd_putsxy(3,12,"oops...",0); + lcd_putsxy(3,22,"Your Score :",0); + lcd_putsxy(3,32, pscore,0); + if (score>hiscore) { + hiscore=score; + lcd_putsxy(3,42,"New High Score!",0); + } + else { + snprintf(hscore,sizeof(hscore),"High Score %d",hiscore); + lcd_putsxy(3,42,hscore,0); + } + lcd_update(); + sleep(HZ); + dead=1; +} + +void colission (short x, short y) { + switch (board[x][y]) { + case 0: + break; + case -1: + snakelength+=2; + score+=level; + apple=0; + break; + default: + die(); + break; + } + if (x==28 || x<0 || y==16 || y<0) + die(); +} + +void move_head (short x, short y) { + switch (dir) { + case 0: + y-=1; + break; + case 1: + x+=1; + break; + case 2: + y+=1; + break; + case 3: + x-=1; + break; + } + colission (x,y); + if (dead) return; + board[x][y]=1; + lcd_fillrect(x*4,y*4,4,4); +} + +void frame (void) { + short x,y,head=0; + for (x=0; x<28; x++) { + for (y=0; y<16; y++) { + switch (board[x][y]) { + case 1: + if (!head) { + move_head(x,y); + if (dead) return; + board[x][y]++; + head=1; + } + break; + case 0: + break; + case -1: + break; + default: + if (board[x][y]==snakelength) { + board[x][y]=0; + lcd_clearrect(x*4,y*4,4,4); + } + else + board[x][y]++; + } + } + } + lcd_update(); +} + +void redraw (void) { + short x,y; + lcd_clear_display(); + for (x=0; x<28; x++) { + for (y=0; y<16; y++) { + switch (board[x][y]) { + case -1: + lcd_fillrect((x*4)+1,y*4,2,4); + lcd_fillrect(x*4,(y*4)+1,4,2); + break; + case 0: + break; + default: + lcd_fillrect(x*4,y*4,4,4); + break; + } + } + } + lcd_update(); +} + +void game_pause (void) { + lcd_clear_display(); + lcd_putsxy(3,12,"Game Paused",0); + lcd_putsxy(3,22,"[play] to resume",0); + lcd_putsxy(3,32,"[off] to quit",0); + lcd_update(); + while (1) { + switch (button_get(true)) { + case BUTTON_OFF: + dead=1; + return; + case BUTTON_PLAY: + redraw(); + sleep(HZ/2); + return; + } + } +} + + +void game (void) { + short x,y; + while (1) { + frame(); + if (dead) return; + frames++; + if (frames==10) { + frames=0; + if (!apple) { + do { + x=rand_num(28); + y=rand_num(16); + } while (board[x][y]); + apple=1; + board[x][y]=-1; + lcd_fillrect((x*4)+1,y*4,2,4); + lcd_fillrect(x*4,(y*4)+1,4,2); + } + } + + sleep(HZ/level); + + switch (button_get(false)) { + case BUTTON_UP: + if (dir!=2) dir=0; + break; + case BUTTON_RIGHT: + if (dir!=3) dir=1; + break; + case BUTTON_DOWN: + if (dir!=0) dir=2; + break; + case BUTTON_LEFT: + if (dir!=1) dir=3; + break; + case BUTTON_OFF: + dead=1; + return; + case BUTTON_PLAY: + game_pause(); + break; + } + } +} + +void game_init(void) { + short x,y; + char plevel[10],phscore[20]; + + for (x=0; x<28; x++) { + for (y=0; y<16; y++) { + board[x][y]=0; + } + } + dead=0; + apple=0; + snakelength=4; + score=0; + board[11][7]=1; + + + lcd_clear_display(); + snprintf(plevel,sizeof(plevel),"Level - %d",level); + snprintf(phscore,sizeof(phscore),"High Score - %d",hiscore); + lcd_putsxy(3,2, plevel,0); + lcd_putsxy(3,12, "(1 - slow, 9 - fast)",0); + lcd_putsxy(3,22, "[off] to quit",0); + lcd_putsxy(3,32, "[play] to start/pause",0); + lcd_putsxy(3,42, phscore,0); + lcd_update(); + + while (1) { + switch (button_get(true)) { + case BUTTON_RIGHT: + case BUTTON_UP: + if (level<9) + level++; + break; + case BUTTON_LEFT: + case BUTTON_DOWN: + if (level>1) + level--; + break; + case BUTTON_OFF: + dead=1; + return; + break; + case BUTTON_PLAY: + return; + break; + } + snprintf(plevel,sizeof(plevel),"Level - %d",level); + lcd_putsxy(3,2, plevel,0); + lcd_update(); + } + +} + +Menu snake(void) { + game_init(); + lcd_clear_display(); + game(); + return MENU_OK; +} +