Genetic generation of cars in a 2D environment
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 
 

114 lines
2.8 KiB

//
// Path.cpp
// OSXGLEssentials
//
// Created by Joshua Moerman on 10/03/14.
//
//
#include "Path.h"
#include <cmath>
#include <random>
// A default thingy which makes implementing it easier. A subclass only have to
// provide new points, which will be connected (So this is not suitable for
// e.g. jumps or circles)
struct DefaultBuilder : PathBuilder {
// number of vertices in one chunk
static constexpr auto chainLength = 8;
DefaultBuilder(b2World & world_, b2Vec2 startingPoint)
: world(world_)
, previous(startingPoint)
, current(startingPoint)
{
fixture.friction = 2.0;
}
void buildUpTo(float x) override {
b2BodyDef groundBodyDef;
groundBodyDef.position = {0.0f, -10.0f};
while(current.x < x){
auto oldPreviousPoint = previous;
b2Vec2 chainPositions[chainLength];
chainPositions[0] = current;
for(int i = 1; i < chainLength; ++i){
chainPositions[i] = next;
previous = current;
current = next;
// we always generate one more, for the b2 ghost vertices
generate_next();
}
b2ChainShape chain;
chain.CreateChain(chainPositions, chainLength);
chain.SetPrevVertex(oldPreviousPoint);
chain.SetNextVertex(next);
fixture.shape = &chain;
auto groundBody = world.CreateBody(&groundBodyDef);
groundBody->CreateFixture(&fixture);
}
}
virtual void generate_next() = 0;
protected:
std::mt19937 generator{0};
std::uniform_real_distribution<float> distribution{-1.0, 1.0};
b2World & world;
b2Vec2 previous;
b2Vec2 current;
b2Vec2 next;
b2FixtureDef fixture;
};
// Creates random terrain, roughness comes with time
struct RandomBuilder : DefaultBuilder {
RandomBuilder(b2World & world_, b2Vec2 startingPoint)
: DefaultBuilder(world_, startingPoint)
{
generate_next();
}
virtual void generate_next() override {
auto t = current.x;
float m = std::sqrt(0.001f*t + 1) - 1;
if(t <= 0) m = 0;
float slope = m * distribution(generator);
auto rot = b2Rot(slope);
next = b2Mul(rot, {10, 0}) + current;
}
};
// A flat road
struct FlatBuilder : DefaultBuilder {
FlatBuilder(b2World & world_, b2Vec2 startingPoint)
: DefaultBuilder(world_, startingPoint)
{
generate_next();
}
virtual void generate_next() override {
b2Vec2 newPiece = {10, 0};
next = newPiece + current;
}
};
Path::Path(b2World & world_)
: world(world_)
, impl(new RandomBuilder(world, {-20, 0}))
{}
void Path::buildUpTo(float x){
impl->buildUpTo(x);
}