mirror of
https://github.com/gwenhael-le-moine/c-urs_-toil-s.git
synced 2024-12-27 09:58:44 +01:00
count moves + change a bit the display
This commit is contained in:
parent
b25a90e024
commit
9c50fdb739
1 changed files with 139 additions and 144 deletions
283
star.c
283
star.c
|
@ -4,142 +4,6 @@
|
||||||
|
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
|
|
||||||
/* levels have fixed, hardcoded dimensions */
|
|
||||||
#define LEVEL_HEIGHT 9
|
|
||||||
#define LEVEL_WIDTH 16
|
|
||||||
|
|
||||||
enum {
|
|
||||||
color_BALL = 1,
|
|
||||||
color_CUBE,
|
|
||||||
color_VOID,
|
|
||||||
color_GIFT,
|
|
||||||
color_WALL,
|
|
||||||
color_BALL_SELECTED,
|
|
||||||
color_CUBE_SELECTED,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WALL ='#',
|
|
||||||
BALL ='@',
|
|
||||||
CUBE ='H',
|
|
||||||
VOID =' ',
|
|
||||||
GIFT ='x'
|
|
||||||
} cell;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
UP ='u',
|
|
||||||
DOWN ='d',
|
|
||||||
LEFT ='l',
|
|
||||||
RIGHT ='r'
|
|
||||||
} direction;
|
|
||||||
|
|
||||||
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 make_a_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[] = { "################"
|
char *levels[] = { "################"
|
||||||
"#@## x#H#"
|
"#@## x#H#"
|
||||||
"# x ###"
|
"# x ###"
|
||||||
|
@ -390,18 +254,145 @@ char *levels[] = { "################"
|
||||||
"################"
|
"################"
|
||||||
" " };
|
" " };
|
||||||
|
|
||||||
|
/* levels have fixed, hardcoded dimensions */
|
||||||
|
#define LEVEL_HEIGHT 9
|
||||||
|
#define LEVEL_WIDTH 16
|
||||||
|
|
||||||
|
enum {
|
||||||
|
color_BALL = 1,
|
||||||
|
color_CUBE,
|
||||||
|
color_VOID,
|
||||||
|
color_GIFT,
|
||||||
|
color_WALL,
|
||||||
|
color_BALL_SELECTED,
|
||||||
|
color_CUBE_SELECTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WALL ='#',
|
||||||
|
BALL ='@',
|
||||||
|
CUBE ='H',
|
||||||
|
VOID =' ',
|
||||||
|
GIFT ='x'
|
||||||
|
} cell;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UP ='u',
|
||||||
|
DOWN ='d',
|
||||||
|
LEFT ='l',
|
||||||
|
RIGHT ='r'
|
||||||
|
} direction;
|
||||||
|
|
||||||
|
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 make_a_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 );
|
||||||
|
|
||||||
|
s->moves++;
|
||||||
|
|
||||||
|
free( item_coord );
|
||||||
|
}
|
||||||
|
|
||||||
void display_level( struct state *s )
|
void display_level( struct state *s )
|
||||||
{
|
{
|
||||||
int i, j, *ball, *cube;
|
int i, j, *ball, *cube;
|
||||||
|
|
||||||
mvprintw( 0, 0, "%i gifts left, ", count_gifts( s ) );
|
|
||||||
if ( won_or_not( s ) ) {
|
|
||||||
mvprintw( 0, 17, "You WON !\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mvprintw( 0, 17, "go on.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i = 0 ; i < LEVEL_HEIGHT ; i++ ) {
|
for( i = 0 ; i < LEVEL_HEIGHT ; i++ ) {
|
||||||
for( j = 0 ; j < LEVEL_WIDTH ; j++ ) {
|
for( j = 0 ; j < LEVEL_WIDTH ; j++ ) {
|
||||||
switch( get_cell( s, j, i ) ) {
|
switch( get_cell( s, j, i ) ) {
|
||||||
|
@ -454,6 +445,10 @@ void display_level( struct state *s )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mvprintw( 1, 35, "%i gifts left", count_gifts( s ) );
|
||||||
|
mvprintw( 2, 35, "%i moves made", s->moves );
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue