From 6b7fb3408427ad87b07bbff3e1a4b717bf083b11 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Fri, 1 Jul 2011 15:03:50 +0200 Subject: [PATCH] . --- star.c | 228 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 121 insertions(+), 107 deletions(-) diff --git a/star.c b/star.c index 22fedf2..f5f1cc3 100644 --- a/star.c +++ b/star.c @@ -6,10 +6,127 @@ #define LEVEL_HEIGHT 9 #define LEVEL_WIDTH 16 -typedef enum { WALL='#', BALL='@', CUBE='H', VOID=' ', GIFT='*' } cell; -typedef enum { UP='u', DOWN='d', LEFT='l', RIGHT='r' } direction; +typedef enum { + WALL='#', + BALL='@', + CUBE='H', + VOID=' ', + GIFT='*' +} cell; +typedef enum { + UP='u', + DOWN='d', + LEFT='l', + RIGHT='r' +} direction; -char* levels[] = { "################" +struct state { + char level[ LEVEL_HEIGHT * LEVEL_WIDTH ]; + char moving; + int moves; +}; + +int count_gifts( struct state *s ) +{ + int i, n = 0; + for( i = 0 ; i < LEVEL_HEIGHT * LEVEL_WIDTH ; i++ ) { + if ( s->level[ i ] == GIFT ) { + n++; + } + } + return n; +} + +void get_pos( struct state *s, int* pos ) +{ + int p; + + p = (int)( strchr( s->level, s->moving ) - s->level ); + + pos[ 1 ] = p / LEVEL_WIDTH; + pos[ 0 ] = p - ( pos[ 1 ] * LEVEL_WIDTH ); +} + +char get_cell( struct state *s, int x, int y ) +{ + return s->level[ y * LEVEL_WIDTH + x ]; +} + +void set_cell( struct state *s, int x, int y, cell value ) +{ + s->level[ y * LEVEL_WIDTH + x ] = value; +} + +void load_level( struct state *s, char* lvl ) +{ + strncpy( s->level, lvl, LEVEL_HEIGHT * LEVEL_WIDTH ); + s->moving = BALL; + s->moves = 0; +} + +void switch_actor( struct state *s ) +{ + s->moving = (s->moving == BALL) ? CUBE : BALL; +} + +int won_or_not( struct state *s ) +{ + return( count_gifts( s ) == 0 ); +} + +void move( struct state *s, direction where ) +{ + int dx = 0, dy = 0, tmpx, tmpy, *item_coord; + item_coord = malloc( sizeof( int ) * 2 ); + get_pos( s, item_coord ); + tmpx = item_coord[ 0 ]; + tmpy = item_coord[ 1 ]; + + switch( where ) { + case UP: + dy--; + break; + case DOWN: + dy++; + break; + case LEFT: + dx--; + break; + case RIGHT: + dx++; + break; + default: break; + } + + /* Calculating arrival coordinates */ + while ( /* Hairy conditions ahead */ + /* target cell is within level's boundaries */ + ( ( tmpx + dx >= 0 ) && ( tmpx + dx < LEVEL_WIDTH ) ) && + ( ( tmpy + dy >= 0 ) && ( tmpy + dy < LEVEL_HEIGHT ) ) && + /* and target cell is empty */ + ( get_cell( s, tmpx + dx, tmpy + dy ) == VOID ) + /* or, in case the ball is moving, target cell can be a gift (which we'll eat) */ + || ( s->moving == BALL && ( get_cell( s, tmpx + dx, tmpy + dy ) == GIFT ) ) + ) { + tmpx += dx; + tmpy += dy; + + if ( s->moving == BALL && get_cell( s, tmpx, tmpy ) == GIFT ) { + set_cell( s, tmpx, tmpy, VOID ); + } + } + + /* Moving to arrival coordinates */ + set_cell( s, item_coord[ 0 ], item_coord[ 1 ], VOID ); + set_cell( s, tmpx, tmpy, s->moving ); + + free( item_coord ); +} + +/* below for testing, my kind-of/sort-of unti-testing */ + +/* so if I declare level as cell* levels[] I get a warning :/ */ +char *levels[] = { "################" "#@## *#H#" "# * ###" "# ##* #" @@ -259,109 +376,6 @@ char* levels[] = { "################" "################" " " }; -struct state { - char level[ LEVEL_HEIGHT * LEVEL_WIDTH ]; - char moving; - int moves; -}; - -int count_gifts( struct state *s ) -{ - int i, n = 0; - for( i = 0 ; i < LEVEL_HEIGHT * LEVEL_WIDTH ; i++ ) { - if ( s->level[ i ] == GIFT ) { - n++; - } - } - return n; -} - -void get_pos( struct state *s, int* pos ) -{ - int p; - - p = (int)( strchr( s->level, s->moving ) - s->level ); - - pos[ 1 ] = p / LEVEL_WIDTH; - pos[ 0 ] = p - ( pos[ 1 ] * LEVEL_WIDTH ); -} - -char get_cell( struct state *s, int x, int y ) -{ - return s->level[ y * LEVEL_WIDTH + x ]; -} - -void set_cell( struct state *s, int x, int y, cell value ) -{ - s->level[ y * LEVEL_WIDTH + x ] = value; -} - -void load_level( struct state *s, char* lvl ) -{ - strncpy( s->level, lvl, LEVEL_HEIGHT * LEVEL_WIDTH ); - s->moving = BALL; - s->moves = 0; -} - -void switch_actor( struct state *s ) -{ - s->moving = (s->moving == BALL) ? CUBE : BALL; -} - -int won_or_not( struct state *s ) -{ - return( count_gifts( s ) == 0 ); -} - -void move( struct state *s, direction where ) -{ - int dx = 0, dy = 0, tmpx, tmpy, *item_coord; - item_coord = malloc( sizeof( int ) * 2 ); - get_pos( s, item_coord ); - tmpx = item_coord[ 0 ]; - tmpy = item_coord[ 1 ]; - - switch( where ) { - case UP: - dy--; - break; - case DOWN: - dy++; - break; - case LEFT: - dx--; - break; - case RIGHT: - dx++; - break; - default: break; - } - - /* Calculating arrival coordinates */ - while ( /* Hairy conditions ahead */ - /* target cell is within level's boundaries */ - ( ( tmpx + dx >= 0 ) && ( tmpx + dx < LEVEL_WIDTH ) ) && - ( ( tmpy + dy >= 0 ) && ( tmpy + dy < LEVEL_HEIGHT ) ) && - /* and target cell is empty */ - ( get_cell( s, tmpx + dx, tmpy + dy ) == VOID ) - /* or, in case the ball is moving, target cell can be a gift (which we'll eat) */ - || ( s->moving == BALL && ( get_cell( s, tmpx + dx, tmpy + dy ) == GIFT ) ) - ) { - tmpx += dx; - tmpy += dy; - - if ( s->moving == BALL && get_cell( s, tmpx, tmpy ) == GIFT ) { - set_cell( s, tmpx, tmpy, VOID ); - } - } - - /* Moving to arrival coordinates */ - set_cell( s, item_coord[ 0 ], item_coord[ 1 ], VOID ); - set_cell( s, tmpx, tmpy, s->moving ); - - free( item_coord ); -} - void display_level( struct state *s ) { int i, j, *ball, *cube; @@ -392,7 +406,7 @@ void display_level( struct state *s ) case GIFT: printf( "<>" ); break; - default: break; + default: break; /* ignore newlines */ } } printf( "\n" );