Esempio n. 1
0
    public void Generate()
    {
        generation++;
        highestFitness = 0;
        for (int i = 0; i < population.Count; i++)
        {
            if (population[i].fitness > highestFitness)
            {
                highestFitness = population[i].fitness;
            }
        }

        CollectStats();

        List <Car_Class> newPopulation = new List <Car_Class>();

        for (int i = 0; i < population.Count; i++)
        {
            Car_Class partnerA = AcceptReject();
            Car_Class partnerB = AcceptReject();
            Car_Class child    = partnerA.CrossOver(partnerB);
            child.Mutate();
            newPopulation.Add(child);
        }
        tempPopulation = newPopulation;
        DestroyPreviousGeneration();
        population = newPopulation;
    }
Esempio n. 2
0
    // This function will randomly combine the genes of two Car_Classes.
    public Car_Class CrossOver(Car_Class partner)
    {
        GameObject parent = new GameObject("ParentDel");
        GameObject body   = new GameObject("BodyDel");

        parent.tag = "Delete";
        body.tag   = "Delete";

        Car_Class child = new Car_Class(
            parent,                           // Parent GameObject
            body,                             // Reference to body object
            new Vector3(0.5f, 0.5f, 0),       // Size of car
            new List <Wheel> {
        },                                    // Array of wheels
            new Engine(1000f, 10000f, 1000f), // Cars engine. Engine speed | Max torque | Rotation speed
            new Driver(0f, 0f)                // Driver. CorrectionCone | AccelerationCone
            );

        int midPoint = Random.Range(0, DNA.Count);

        for (int i = 0; i < DNA.Count; i++)
        {
            if (i > midPoint)
            {
                child.DNA[i] = DNA[i];
            }
            else
            {
                child.DNA[i] = partner.DNA[i];
            }
        }

        List <Wheel>  wheels = (List <Wheel>)child.DNA[3];
        List <object> temp   = child.DNA;

        child = new Car_Class(
            (GameObject)child.DNA[0], // Parent GameObject
            (GameObject)child.DNA[1], // Reference to body object
            (Vector3)child.DNA[2],    // Size of car
            wheels,                   // Array of wheels
            (Engine)child.DNA[4],     // Cars engine. Engine speed | Max torque | Rotation speed
            (Driver)child.DNA[5]      // Driver. CorrectionCone | AccelerationCone
            );

        return(child);
    }
Esempio n. 3
0
    // This function will return a Car_Class, but it will disproportionally favor Car_Classes with higher fitness.
    // It means the best cars are more likely to have their genes make up the next generation of cars.
    private Car_Class AcceptReject()
    {
        int useProtection = 0;

        while (true)
        {
            int       index   = UnityEngine.Random.Range(0, population.Count - 1);
            float     r       = UnityEngine.Random.Range(0f, highestFitness);
            Car_Class partner = population[index];
            if (r < partner.fitness)
            {
                return(partner);
            }
            useProtection++;
            if (useProtection > 10000)
            {
                print("HAD TO USE PROTECTIOn"); return(null);
            }
        }
    }
Esempio n. 4
0
    // This function is responsible for spawning a car based on a Car_Class input. It will return a Car_Class
    // with references to the spawned objects of that car.
    public Car_Class SpawnCar(Car_Class car)
    {
        // If wheel amount is not affected by evolution, make sure every car has 2 wheels
        if (!main.wheelAmountAffectedByEvolution)
        {
            car.Wheels = car.Wheels.GetRange(0, 2);
            for (int i = 0; i < 2; i++)
            {
                if (car.Wheels.Count <= 1)
                {
                    car.Wheels.Add(new Wheel(new GameObject("Wheel WTF"), new Vector2(-1, -1), new Suspension(5, 0.5f), 1));
                }
            }
        }

        // Create a parent object that all other objects can be listed under in the hierarchy
        string carParentName = car.CarParent.name;

        Destroy(car.CarParent);
        if (carParentName == "")
        {
            carParentName = "Car";
        }
        car.CarParent = new GameObject(carParentName);
        car.DNA[0]    = car.CarParent;

        // Create the car body
        Destroy(car.Body);
        car.Body   = Instantiate(bodyPrefab, emptyVector3, emptyQuaternion, car.CarParent.transform);
        car.DNA[1] = car.Body;
        car.Body.transform.localScale = car.Size;

        // Make sure the body has a body tag, so we can exclude it from colliding with other cars.
        car.Body.layer = 8;

        // Determine the cars weight based on scale
        float mass = car.Size.x * car.Size.y * 100 * main.percentageOfCalculatedMass;

        if (mass < main.lowestMass)
        {
            mass = main.lowestMass;
        }
        car.Body.GetComponent <Rigidbody2D>().mass = mass;

        // Initialize the car controller component on the car body
        Car_Controller car_controller = car.Body.GetComponent <Car_Controller>();

        // Setup the engine
        car_controller.EngineSpeed       = car.Engine.EngineSpeed;
        car_controller.MaxMotorTorque    = car.Engine.MaxMotorTorque;
        car_controller.CarRotationTorque = car.Engine.CarRotationTorque;

        // Prepare the car driver
        car_controller.CorrectionCone   = car.Driver.CorrectionCone;
        car_controller.AccelerationCone = car.Driver.AccelerationCone;
        if (car.Driver.CorrectionCone != 0 || car.Driver.AccelerationCone != 0)
        {
            car_controller.hasDriver = true;
        }

        // Add the wheels
        float carLengthX = car.Body.GetComponent <SpriteRenderer>().bounds.size.x *(1 / car.Size.x) / 2;
        float carLengthY = car.Body.GetComponent <SpriteRenderer>().bounds.size.y *(1 / car.Size.y) / 2;

        foreach (Wheel wheel in car.Wheels)
        {
            // Get the position and instantiate the wheel object
            Vector3 wheelPos = new Vector3(Map(wheel.Position.x, -1, 1, carLengthX * -1, carLengthX), Map(wheel.Position.y, -1, 1, carLengthY * -1, carLengthY), 0);
            wheel.WheelGO = Instantiate(wheelPrefab, wheelPos, emptyQuaternion, car.CarParent.transform);

            // Add the wheel join
            WheelJoint2D wheelJoint = car.Body.AddComponent <WheelJoint2D>();
            wheelJoint.connectedBody = wheel.WheelGO.GetComponent <Rigidbody2D>();
            wheelJoint.anchor        = wheelPos;

            // Set wheels graphical size
            wheel.WheelGO.GetComponent <SpriteRenderer>().size = new Vector3(wheel.SizeX, wheel.SizeX);

            // Add wheel to the car tag, to avoid cars colliding with each other
            wheel.WheelGO.layer = 8;

            // Setup the suspension
            wheelJoint.suspension = new JointSuspension2D {
                frequency = wheel.Suspension.Stiffness, dampingRatio = wheel.Suspension.DampingRatio, angle = 90
            };
        }
        car.Body.GetComponent <Car_Controller>().wheels = car.Body.GetComponents <WheelJoint2D>();
        car.DNA[3] = car.Wheels;

        return(car);
    }