diff --git a/libngstar2/NGStar2.cc b/libngstar2/NGStar2.cc index f807d56..56fc849 100644 --- a/libngstar2/NGStar2.cc +++ b/libngstar2/NGStar2.cc @@ -28,380 +28,380 @@ using namespace std; namespace ngstar2 { - // NGSTAR2 class implementation - // in order of declaration - // private: + // NGSTAR2 class implementation + // in order of declaration + // private: - // - // Set the cell(x, y) with the given value (if valid) - // - void NGStar2::set_cell( int x, int y , char value ) - { - if ( ( x <= NGSTAR_LEVEL_WIDTH ) && ( y <= NGSTAR_LEVEL_HEIGHT ) ) { - switch ( value ) { - case WALL : // char if for ngs levels - case 3 : // int is for gsl levels - this->board[y*NGSTAR_LEVEL_WIDTH+x] = wall; - break; - case EMPTY : - case 2 : - this->board[y*NGSTAR_LEVEL_WIDTH+x] = empty; - break; - case GIFT : - case 4 : - this->board[y*NGSTAR_LEVEL_WIDTH+x] = gift; - this->nb_gifts++; - break; - case BALL : - case 0 : - this->board[y*NGSTAR_LEVEL_WIDTH+x] = ball; - this->ball_X = x; - this->ball_Y = y; - break; - case CUBE : - case 1 : - this->board[y*NGSTAR_LEVEL_WIDTH+x] = cube; - this->cube_X = x; - this->cube_Y = y; - break; - case '\n' : - break; - default : - throw InvalidCellValue( value ); - break; + // + // Set the cell(x, y) with the given value (if valid) + // + void NGStar2::set_cell( int x, int y , char value ) + { + if ( ( x <= NGSTAR_LEVEL_WIDTH ) && ( y <= NGSTAR_LEVEL_HEIGHT ) ) { + switch ( value ) { + case WALL : // char if for ngs levels + case 3 : // int is for gsl levels + this->board[y*NGSTAR_LEVEL_WIDTH+x] = wall; + break; + case EMPTY : + case 2 : + this->board[y*NGSTAR_LEVEL_WIDTH+x] = empty; + break; + case GIFT : + case 4 : + this->board[y*NGSTAR_LEVEL_WIDTH+x] = gift; + this->nb_gifts++; + break; + case BALL : + case 0 : + this->board[y*NGSTAR_LEVEL_WIDTH+x] = ball; + this->ball_X = x; + this->ball_Y = y; + break; + case CUBE : + case 1 : + this->board[y*NGSTAR_LEVEL_WIDTH+x] = cube; + this->cube_X = x; + this->cube_Y = y; + break; + case '\n' : + break; + default : + throw InvalidCellValue( value ); + break; + } + } else { + throw InvalidCellCoordinates( x, y ); } - } else { - throw InvalidCellCoordinates( x, y ); - } - } + } - // - // Load a level from file filename in NGStar format - // - inline void NGStar2::read_ngs_level( const string *filename ) - { - int i; - int j; - char current_cell; - bool ball_set=false; - bool cube_set=false; + // + // Load a level from file filename in NGStar format + // + inline void NGStar2::read_ngs_level( const string *filename ) + { + int i; + int j; + char current_cell; + bool ball_set=false; + bool cube_set=false; - ifstream file; + ifstream file; - file.open( filename->c_str( ), ios::in ); - if ( file == NULL ) { - throw InvalidLevelFile( filename ); - } - - this->level_h = NGSTAR_LEVEL_HEIGHT; - this->level_w = NGSTAR_LEVEL_WIDTH; - this->board = new cell[ this->level_w * this->level_h ]; - - for ( i=NGSTAR_LEVEL_HEIGHT ; i-- ; ) { - for ( j=NGSTAR_LEVEL_WIDTH ; j-- ; ) { - file.read( ¤t_cell, 1 ); - if ( file.eof( ) ) - throw InvalidLevelFile( filename ); - this->set_cell( j, i, current_cell ); - if ( current_cell == BALL ) - ball_set = true; - else - if ( current_cell == CUBE ) - cube_set = true; + file.open( filename->c_str( ), ios::in ); + if ( file == NULL ) { + throw InvalidLevelFile( filename ); } - } - file.close( ); + this->level_h = NGSTAR_LEVEL_HEIGHT; + this->level_w = NGSTAR_LEVEL_WIDTH; + this->board = new cell[ this->level_w * this->level_h ]; - if ( ball_set == false || cube_set == false ) { - throw InvalidLevelFile( filename ); - } - } - - // - // Load a level from file filename in G-star format - // (from g-star source, translated into C++ and adapted - // but basically the structure is the same) - // - inline void NGStar2::read_gsl_level( const string *filename ) - { - int i; - int j; - char current_cell; - char width; - char height; - bool ball_set=false; - bool cube_set=false; - - ifstream file; - - file.open( filename->c_str( ), ios::binary ); - if ( file == NULL ) { - throw InvalidLevelFile( filename ); - } - - /* skeeping header "gsl1" */ - file.seekg( 4 ); - - file.read( &width, 1 ); - file.read( &height, 1 ); - - this->level_h = (int)height; //NGSTAR_LEVEL_HEIGHT; - this->level_w = (int)width; //NGSTAR_LEVEL_WIDTH; - this->board = new cell[ this->level_w * this->level_h ]; - - if (( width == NGSTAR_LEVEL_WIDTH ) && ( height == NGSTAR_LEVEL_HEIGHT )) { for ( i=NGSTAR_LEVEL_HEIGHT ; i-- ; ) { - for ( j=NGSTAR_LEVEL_WIDTH ; j-- ; ) { - file.read( ¤t_cell, 1 ); - if ( file.eof( ) ) - throw InvalidLevelFile( filename ); - this->set_cell( j, i, current_cell ); - if ( current_cell == 0 ) - ball_set = true; - else - if ( current_cell == 1 ) - cube_set = true; - } + for ( j=NGSTAR_LEVEL_WIDTH ; j-- ; ) { + file.read( ¤t_cell, 1 ); + if ( file.eof( ) ) + throw InvalidLevelFile( filename ); + this->set_cell( j, i, current_cell ); + if ( current_cell == BALL ) + ball_set = true; + else + if ( current_cell == CUBE ) + cube_set = true; + } } - } - file.close( ); - - if ( ball_set == false || cube_set == false ) { - throw InvalidLevelFile( filename ); - } - } - - // - // Determine the format of level in filename and call - // the corresponding method - // - void NGStar2::read_level( const string *filename ) - { - ifstream file; - char *foo = new char[ 5 ]; - - this->nb_gifts = 0; - - file.open( filename->c_str( ), ios::binary ); - if ( file == NULL ) { - throw InvalidLevelFile( filename ); - } - - /* verifying file type (gsl or ngs) */ - file.read( foo, 4 ); - foo[4] = '\0'; - if ( (new string( foo ))->compare( "gsl1" ) == 0 ) { file.close( ); - read_gsl_level( filename ); - } - else { + + if ( ball_set == false || cube_set == false ) { + throw InvalidLevelFile( filename ); + } + } + + // + // Load a level from file filename in G-star format + // (from g-star source, translated into C++ and adapted + // but basically the structure is the same) + // + inline void NGStar2::read_gsl_level( const string *filename ) + { + int i; + int j; + char current_cell; + char width; + char height; + bool ball_set=false; + bool cube_set=false; + + ifstream file; + + file.open( filename->c_str( ), ios::binary ); + if ( file == NULL ) { + throw InvalidLevelFile( filename ); + } + + /* skeeping header "gsl1" */ + file.seekg( 4 ); + + file.read( &width, 1 ); + file.read( &height, 1 ); + + this->level_h = (int)height; //NGSTAR_LEVEL_HEIGHT; + this->level_w = (int)width; //NGSTAR_LEVEL_WIDTH; + this->board = new cell[ this->level_w * this->level_h ]; + + if (( width == NGSTAR_LEVEL_WIDTH ) && ( height == NGSTAR_LEVEL_HEIGHT )) { + for ( i=NGSTAR_LEVEL_HEIGHT ; i-- ; ) { + for ( j=NGSTAR_LEVEL_WIDTH ; j-- ; ) { + file.read( ¤t_cell, 1 ); + if ( file.eof( ) ) + throw InvalidLevelFile( filename ); + this->set_cell( j, i, current_cell ); + if ( current_cell == 0 ) + ball_set = true; + else + if ( current_cell == 1 ) + cube_set = true; + } + } + } + file.close( ); - read_ngs_level( filename ); - } - this->nb_moves = 0; - this->moving = ball; - } + if ( ball_set == false || cube_set == false ) { + throw InvalidLevelFile( filename ); + } + } - // - // Move the ball in given direction - // stopped by walls and the cube - // - void NGStar2::move_ball( direction direction ) - { - int dh=0; - int dv=0; - unsigned int tmp_ball_X = this->ball_X; - unsigned int tmp_ball_Y = this->ball_Y; + // + // Determine the format of level in filename and call + // the corresponding method + // + void NGStar2::read_level( const string *filename ) + { + ifstream file; + char *foo = new char[ 5 ]; - /* determining the direction it will go */ - switch ( direction ) { - case go_up : dv=1; break; - case go_down : dv=-1; break; - case go_left : dh=1; break; - case go_right : dh=-1; break; - default : break; - } + this->nb_gifts = 0; - /* determining the cell it will go */ - while ( - /* checking board limits */ - (( tmp_ball_Y + dv >= 0 ) && - ( tmp_ball_Y + dv < NGSTAR_LEVEL_HEIGHT )) && - (( tmp_ball_X + dh >= 0 ) && - ( tmp_ball_X + dh < NGSTAR_LEVEL_WIDTH )) && - /* is next cell a wall ? */ - (this->board[(tmp_ball_Y + dv)*NGSTAR_LEVEL_WIDTH+tmp_ball_X + dh] != wall) && - (this->board[(tmp_ball_Y + dv)*NGSTAR_LEVEL_WIDTH+tmp_ball_X + dh] != cube) - ) - { - tmp_ball_Y += dv; - tmp_ball_X += dh; - - /* did it collect a gift ? */ - if ( this->board[tmp_ball_Y*NGSTAR_LEVEL_WIDTH+tmp_ball_X] == gift ) - { - this->board[tmp_ball_Y*NGSTAR_LEVEL_WIDTH+tmp_ball_X] = empty; - this->nb_gifts--; - } + file.open( filename->c_str( ), ios::binary ); + if ( file == NULL ) { + throw InvalidLevelFile( filename ); } - if ( ( tmp_ball_X != this->ball_X ) || ( tmp_ball_Y != this->ball_Y ) ) { - // if it's the first move then set t1 as the start of level - if ( this->nb_moves == 0 ) - (void) time( &( this->t1 ) ); - /* empty previous cell */ - this->board[this->ball_Y*NGSTAR_LEVEL_WIDTH+this->ball_X] = empty; - - /* changing coordinates */ - this->ball_Y = tmp_ball_Y; - this->ball_X = tmp_ball_X; - - /* set destination cell */ - this->board[tmp_ball_Y*NGSTAR_LEVEL_WIDTH+tmp_ball_X] = ball; - - ++(this->nb_moves); - } - } - - // - // Move the cube in given direction - // stopped by walls, gifts and the ball - // slightly different from move_ball - // - void NGStar2::move_cube( direction direction ) - { - int dh=0; - int dv=0; - unsigned int tmp_cube_X = this->cube_X; - unsigned int tmp_cube_Y = this->cube_Y; - - /* determining the direction it will go */ - switch ( direction ) { - case go_up : dv=1; break; - case go_down : dv=-1; break; - case go_left : dh=1; break; - case go_right : dh=-1; break; - default : break; - } - - /* determining the cell it will go */ - while ( - /* checking board limits */ - (( tmp_cube_Y + dv >= 0 ) && - ( tmp_cube_Y + dv < NGSTAR_LEVEL_HEIGHT )) && - (( tmp_cube_X + dh >= 0 ) && - ( tmp_cube_X + dh < NGSTAR_LEVEL_WIDTH )) && - /* is next cell a wall ? */ - (this->board[(tmp_cube_Y + dv)*NGSTAR_LEVEL_WIDTH+tmp_cube_X + dh] == empty) - ) - { - tmp_cube_Y += dv; - tmp_cube_X += dh; + /* verifying file type (gsl or ngs) */ + file.read( foo, 4 ); + foo[4] = '\0'; + if ( (new string( foo ))->compare( "gsl1" ) == 0 ) { + file.close( ); + read_gsl_level( filename ); + } + else { + file.close( ); + read_ngs_level( filename ); } - if ( ( tmp_cube_X != this->cube_X ) || ( tmp_cube_Y != this->cube_Y ) ) { - // if it's the first move then set t1 as the start of level - if ( this->nb_moves == 0 ) - (void) time( &( this->t1 ) ); - /* empty previous cell */ - this->board[this->cube_Y*NGSTAR_LEVEL_WIDTH+this->cube_X] = empty; + this->nb_moves = 0; + this->moving = ball; + } - /* changing coordinates */ - this->cube_Y = tmp_cube_Y; - this->cube_X = tmp_cube_X; + // + // Move the ball in given direction + // stopped by walls and the cube + // + void NGStar2::move_ball( direction direction ) + { + int dh=0; + int dv=0; + unsigned int tmp_ball_X = this->ball_X; + unsigned int tmp_ball_Y = this->ball_Y; - /* set destination cell */ - this->board[tmp_cube_Y*NGSTAR_LEVEL_WIDTH+tmp_cube_X] = cube; + /* determining the direction it will go */ + switch ( direction ) { + case go_up : dv=1; break; + case go_down : dv=-1; break; + case go_left : dh=1; break; + case go_right : dh=-1; break; + default : break; + } - ++(this->nb_moves); - } - } + /* determining the cell it will go */ + while ( + /* checking board limits */ + (( tmp_ball_Y + dv >= 0 ) && + ( tmp_ball_Y + dv < NGSTAR_LEVEL_HEIGHT )) && + (( tmp_ball_X + dh >= 0 ) && + ( tmp_ball_X + dh < NGSTAR_LEVEL_WIDTH )) && + /* is next cell a wall ? */ + (this->board[(tmp_ball_Y + dv)*NGSTAR_LEVEL_WIDTH+tmp_ball_X + dh] != wall) && + (this->board[(tmp_ball_Y + dv)*NGSTAR_LEVEL_WIDTH+tmp_ball_X + dh] != cube) + ) + { + tmp_ball_Y += dv; + tmp_ball_X += dh; - // public: + /* did it collect a gift ? */ + if ( this->board[tmp_ball_Y*NGSTAR_LEVEL_WIDTH+tmp_ball_X] == gift ) + { + this->board[tmp_ball_Y*NGSTAR_LEVEL_WIDTH+tmp_ball_X] = empty; + this->nb_gifts--; + } + } - // - // Constructor, initialize things - // - NGStar2::NGStar2( Configuration *config ) - { - this->config = config; - this->load_level( ); - } + if ( ( tmp_ball_X != this->ball_X ) || ( tmp_ball_Y != this->ball_Y ) ) { + // if it's the first move then set t1 as the start of level + if ( this->nb_moves == 0 ) + (void) time( &( this->t1 ) ); + /* empty previous cell */ + this->board[this->ball_Y*NGSTAR_LEVEL_WIDTH+this->ball_X] = empty; - // - // Load level nb_level from current levelset if level exists - // - void NGStar2::load_level( ) - { - string *level_filename; + /* changing coordinates */ + this->ball_Y = tmp_ball_Y; + this->ball_X = tmp_ball_X; - if ( ( this->config->levelset != NULL ) && - ( this->config->current_level <= this->config->nb_levels ) ) { - level_filename = new string( this->config->levelsets_path->c_str( ) ); - level_filename->append( "/" ); - level_filename->append( this->config->levelset->c_str( ) ); - level_filename->append( "/" ); - level_filename->append( itos( this->config->current_level ) ); + /* set destination cell */ + this->board[tmp_ball_Y*NGSTAR_LEVEL_WIDTH+tmp_ball_X] = ball; - read_level( level_filename ); - } - } + ++(this->nb_moves); + } + } - // - // Load level nb_level from current levelset if level exists - // - void NGStar2::load_level( const char *filename ) - { - read_level( new string( filename ) ); - } + // + // Move the cube in given direction + // stopped by walls, gifts and the ball + // slightly different from move_ball + // + void NGStar2::move_cube( direction direction ) + { + int dh=0; + int dv=0; + unsigned int tmp_cube_X = this->cube_X; + unsigned int tmp_cube_Y = this->cube_Y; - void NGStar2::next_level ( ) - { - if( ( this->config->current_level + 1 ) <= this->config->nb_levels ) - ++(this->config->current_level); + /* determining the direction it will go */ + switch ( direction ) { + case go_up : dv=1; break; + case go_down : dv=-1; break; + case go_left : dh=1; break; + case go_right : dh=-1; break; + default : break; + } - this->load_level( ); - } + /* determining the cell it will go */ + while ( + /* checking board limits */ + (( tmp_cube_Y + dv >= 0 ) && + ( tmp_cube_Y + dv < NGSTAR_LEVEL_HEIGHT )) && + (( tmp_cube_X + dh >= 0 ) && + ( tmp_cube_X + dh < NGSTAR_LEVEL_WIDTH )) && + /* is next cell a wall ? */ + (this->board[(tmp_cube_Y + dv)*NGSTAR_LEVEL_WIDTH+tmp_cube_X + dh] == empty) + ) + { + tmp_cube_Y += dv; + tmp_cube_X += dh; + } - void NGStar2::previous_level( ) - { - if( this->config->current_level > 1 ) - --(this->config->current_level); + if ( ( tmp_cube_X != this->cube_X ) || ( tmp_cube_Y != this->cube_Y ) ) { + // if it's the first move then set t1 as the start of level + if ( this->nb_moves == 0 ) + (void) time( &( this->t1 ) ); + /* empty previous cell */ + this->board[this->cube_Y*NGSTAR_LEVEL_WIDTH+this->cube_X] = empty; - this->load_level( ); - } + /* changing coordinates */ + this->cube_Y = tmp_cube_Y; + this->cube_X = tmp_cube_X; - void NGStar2::switch_moving( ) - { - ++( this->nb_moves ); - this->moving = ( this->moving == ball ) ? cube : ball; - } + /* set destination cell */ + this->board[tmp_cube_Y*NGSTAR_LEVEL_WIDTH+tmp_cube_X] = cube; - void NGStar2::move( direction where ) - { - if ( this->moving == ball ) - this->move_ball( where ); - else - this->move_cube( where ); - } + ++(this->nb_moves); + } + } - // - // Check is there's gifts left and return the result - // - bool NGStar2::is_it_over( void ) - { - return( ( this->nb_gifts > 0 ) ? false : true ); - } + // public: - int NGStar2::get_duration( ) - { - time_t t2; - (void) time( &( t2 ) ); - return( (int)t2 - ( this->t1 ) ); - } + // + // Constructor, initialize things + // + NGStar2::NGStar2( Configuration *config ) + { + this->config = config; + this->load_level( ); + } + + // + // Load level nb_level from current levelset if level exists + // + void NGStar2::load_level( ) + { + string *level_filename; + + if ( ( this->config->levelset != NULL ) && + ( this->config->current_level <= this->config->nb_levels ) ) { + level_filename = new string( this->config->levelsets_path->c_str( ) ); + level_filename->append( "/" ); + level_filename->append( this->config->levelset->c_str( ) ); + level_filename->append( "/" ); + level_filename->append( itos( this->config->current_level ) ); + + read_level( level_filename ); + } + } + + // + // Load level nb_level from current levelset if level exists + // + void NGStar2::load_level( const char *filename ) + { + read_level( new string( filename ) ); + } + + void NGStar2::next_level ( ) + { + if( ( this->config->current_level + 1 ) <= this->config->nb_levels ) + ++(this->config->current_level); + + this->load_level( ); + } + + void NGStar2::previous_level( ) + { + if( this->config->current_level > 1 ) + --(this->config->current_level); + + this->load_level( ); + } + + void NGStar2::switch_moving( ) + { + ++( this->nb_moves ); + this->moving = ( this->moving == ball ) ? cube : ball; + } + + void NGStar2::move( direction where ) + { + if ( this->moving == ball ) + this->move_ball( where ); + else + this->move_cube( where ); + } + + // + // Check is there's gifts left and return the result + // + bool NGStar2::is_it_over( void ) + { + return( ( this->nb_gifts > 0 ) ? false : true ); + } + + int NGStar2::get_duration( ) + { + time_t t2; + (void) time( &( t2 ) ); + return( (int)t2 - ( this->t1 ) ); + } } // end namespace ngstar2