StudentInFinance
StudentInFinance

Reputation: 145

Application crashes using the sort function

I have a program that is supposed to evolve an IA. I have tried to do something like a genetic algorithm (the main steps are: -select best populations, -mutate population, breed population). To select best populations, I want to sort them and consider the best (considering an order function).

I used the std::sort function, but sometimes it just crashes, but I can't find what is the cause.

Since I am blocked on this project, I did not really know how much of it I should present. Here are following the main ideas:

I define an IA (with some parameters):

IA ia = IA(100, { 6, 4, 1 });

I then want it to do 50 evolution steps:

ia.evolve(50);

Visual S. crashing at execution

Looking deeper in the sort function (debugging), I sometimes get to the following state:

enter image description here

where the "last element", contains just impossible stuff (means "unexpected (for me) stuff").

Since it is the g (Game) object that doesn't contains the correct stuff, I have given the following and related code (even if It might not be the cause at all):

Here is my g (Game) constructor:

Game::Game() {
     nextBarX = BAR_SPACING;
     speed = 0.;
     ySpacing = Y_SPA;
     currentY = GAME_HEIGHT / 2.0;

    passedBars = 0;
    //std::cout << "[Game] Default ctor" << std::endl;
    centerY = std::vector<double>(5);
    centerY[0] = 30.0;
    centerY[1] = 30.0;
    centerY[2] = 30.0;
    centerY[3] = 30.0;
    centerY[4] = 30.0;
}

I may use this:

Game& Game::operator=(Game rhs) {
    //std::cout << "[Game] Assignment operator" << std::endl;
        this->centerY = std::vector<double>(5);
    this->centerY = rhs.centerY;
    this->currentY = rhs.currentY;
    this->nextBarX = rhs.nextBarX;
    this->passedBars = rhs.passedBars;
    this->speed = rhs.speed;
    this->ySpacing = rhs.ySpacing;


    return *this;
}

and that:

void Game::reset(){
    nextBarX = BAR_SPACING;
    speed = 0.;
    ySpacing = Y_SPA;
    currentY = GAME_HEIGHT / 2.0;


    centerY = std::vector<double>(5);
    centerY[0] = 30.0;
    centerY[1] = 30.0;
    centerY[2] = 30.0;
    centerY[3] = 30.0;
    centerY[4] = 30.0;  passedBars = 0;
}

or that:

Game& Game::operator=(Game rhs) {
    //std::cout << "[Game] Assignment operator" << std::endl;
        this->centerY = std::vector<double>(5);
    this->centerY = rhs.centerY;
    this->currentY = rhs.currentY;
    this->nextBarX = rhs.nextBarX;
    this->passedBars = rhs.passedBars;
    this->speed = rhs.speed;
    this->ySpacing = rhs.ySpacing;


    return *this;
}

The IA almost only contains simulations (I simplified it in this question, in reality it contains other stuff):

class IA {
private:
    std::vector<Simul> sim_;
}

To sum it all in a nutshell, IA::evolve do a for loop that calls a IA::getNewGen function. That calls a

void IA::sortIA() {
    std::sort(sim_.begin(), sim_.end());
}

In Simul I defined this:

bool operator<( Simul& v) ;

as:

bool Simul::operator<( Simul& v) 
{
    if (play() > v.play()){
        return true;
    }
    else{
        return false;
    }
}

play() test the Game (reset it and calculates a score):

int Simul::play(){
    bool stillPlaying = true;
    g.reset();

    while (stillPlaying){
        //g.display();
        bool pressed = ask_if_press();
        stillPlaying = !g.step(pressed);
        if (g.getScore() > 100){
            return g.getScore();
        }
    }
    return g.getScore();
}

I look forward to getting some advice, or ideas of what is actually causing the app crash.

Upvotes: 1

Views: 347

Answers (1)

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32742

Your operator< does not implement a strict weak ordering. Part of that means if A < B, then !(B < A), and if A < B and B < C then A < C. Since your operator calls play, which appears to update the score, the value for successive comparisons of elements changes for different comparisons, and the compiler is complaining because it is getting inconsistent results from the comparison.

Don't call play from the comparison, just call g.getScore() and compare those values.

Upvotes: 2

Related Questions