예제 #1
0
 public World()
 {
     roadsArray[0] = new Road(160, 308, 1);
     roadsArray[1] = new Road(180, 358, 2);
     roadsArray[2] = new Road(200, 408, 3);
     peagesArray[0] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 233, 0);
     peagesArray[1] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 283, 1);
     peagesArray[2] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 333, 2);
     peagesArray[3] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 383, 3);
     peagesArray[4] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 433, 4);
     peagesArray[5] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 483, 5);
 }
예제 #2
0
 public World()
 {
     roadsArray[0]  = new Road(160, 308, 1);
     roadsArray[1]  = new Road(180, 358, 2);
     roadsArray[2]  = new Road(200, 408, 3);
     peagesArray[0] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 233, 0);
     peagesArray[1] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 283, 1);
     peagesArray[2] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 333, 2);
     peagesArray[3] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 383, 3);
     peagesArray[4] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 433, 4);
     peagesArray[5] = new Peage(Road.ZONE_GUICHET_START + Road.ZONE_GUICHET_LENGTH + 48, 483, 5);
 }
예제 #3
0
 public void payement(Peage counter)
 {
     // We are at the counter, speed is 0, we haven't paid yet, and aren't already paying.
     if (counter.TimeToOpen != 0)
     {
         flagPaid   = true;
         flagPaying = false;
     }
     else if (counter.TimeToClose == 0)
     {
         counter.Payement(timeAtCounter);
         flagPaying = true;
     }
 }
예제 #4
0
        public void pickTargetCounter(Peage[] listPeages)
        {
            int target = 0;

            // A target counter is choosen in accordance with the payment type and current road.
            if (paymentType == 0)
            {
                target = MainWindow.rnd.Next(0, 2);
            }
            else if (road.Id == 3)
            {
                target = MainWindow.rnd.Next(4, 6);
            }
            else
            {
                target = MainWindow.rnd.Next(2, 4);
            }

            targetCounter = listPeages[target];
        }
예제 #5
0
        internal void Update(CarAgent[] listCars, Peage[] listPeages)
        {
            updateTargetY();
            updateSpeed(listCars, listPeages);
            updateAngle();

            if (speedX < 0.1 && flagCloseToCounter == true && flagPaid == false)
            {
                payement(targetCounter);
            }
            updatePosition();

            if (PosX > (Road.ZONE_PEAGE_START - 10) && flagCounterUpdated == false)
            {
                flagCounterUpdated = true;
                updateTargetCounter(listCars, listPeages);
            }
        }
예제 #6
0
        // Constructor
        public CarAgent(int paramID, CarAgent[] listCars, World world, Peage[] listPeages)
        {
            // unique ID attribution
            // Well... unique for as long as you only look at existing cars.
            id = paramID;
            flagAbort = false;
            flagPaid = false;
            flagPaying = false;
            flagCloseToCounter = false;
            flagCounterUpdated = false;
            theWorld = world;
            isBraking = 0;
            wasBraking = 0;

            // Roll of the speed mult.
            int rollSpeedMult = MainWindow.rnd.Next(0, 7);
            SpeedMult = 1 - ((rollSpeedMult - 3) / 100); // = 0.97 0.98 0.99 1 1.01 1.02 1.03

            // Payment type choice (0 = Télépéage, 1 = Others)
            int rollPayment = MainWindow.rnd.Next(0, 101);
            if (rollPayment < T_RATE)
            {
                paymentType = 0;
            }
            else
            {
                paymentType = 1;
            }
            // Choix de la couleur (if Télépéage, Orange)
            if (paymentType == 1)
            {
                int caseSwitch = MainWindow.rnd.Next(1,4); // 3 different colors
                switch (caseSwitch)
                {
                    case 1:
                        color = "white";
                        break;
                    case 2:
                        color = "black";
                        break;
                    case 3:
                        color = "grey";
                        break;
                }
            }
            else
            {
                color = "orange";
            }

            //road choice
            // TODO - Le placer sur une des trois voies, si y'a déjà une voiture, on tente de le placer autre part.
            PosX = -19;

            int nbRoad = 0;
            // Télépéage can't spawn on road 3. Non-télépéage can't spawn on road 1.
            if (PaymentType == 0)
            {
                nbRoad = MainWindow.rnd.Next(0, 2);
            }
            else
            {
                nbRoad = MainWindow.rnd.Next(1, 3);
            }
            road = world.roadsArray[nbRoad];
            PosY = road.PosY;
            targetY = PosY;

            // First Range Calculation for spawn-eligibility on the selected road.
            bool spawnable = false;
            bool pass;
            int attempts = 1;

            if (MainWindow.carCount > 0)
            {
                while (spawnable == false && attempts < 3)
                {
                    pass = true;

                    foreach (CarAgent car in listCars)
                    {
                        if (car != null)
                        {
                            if (car.Road == road) {
                                if (DistanceTo(car) < 70)
                                {
                                    pass = false;
                                    break;
                                }
                            }
                        }
                    }

                    if (pass == true)
                    {
                        spawnable = true;
                    }

                    else
                    {
                        if(nbRoad == 2 && PaymentType == 1) // Non-Télépéage is restricted to road 2 and 3.
                        {
                            nbRoad = 1;
                        }
                        else if (nbRoad == 1 && PaymentType == 0) // Télépéage is restricted to road 1 and 2.
                        {
                            nbRoad--; // Attempting road 1 since we didn't try it.
                        }
                        else
                        {
                            nbRoad++;
                        }
                        attempts++;
                        road = world.roadsArray[nbRoad];
                        PosY = road.PosY;
                        targetY = PosY;
                    }
                }

                if (attempts > 2)
                {
                    flagAbort = true;
                }
            }

            pickTargetCounter(listPeages);
            rollTimeAtCounter();

            proximity = (Road.MaxSpeedRoad * 2);

            // Obstacle detection : For cars
            proximity = detectProximityCars(proximity, listCars);

            if (proximity == (Road.MaxSpeedRoad * 2))
            {
                speedX = Road.MaxSpeedRoad;
            }
            else if (proximity < MIN_DISTANCE)
            {
                speedX = 0;
            }
            else if (proximity < MIN_DISTANCE * 2)
            {
                speedX = Road.MaxSpeedRoad * 0.1;
            }
            else if (proximity == Road.MaxSpeedRoad)
            {
                speedX = Road.MaxSpeedRoad * 0.5;
            }
            else
            {
                speedX = Road.MaxSpeedRoad * 0.2;
            }

            speedY = 0;
            updateSpeed(listCars, listPeages);
        }
예제 #7
0
        public void updateTargetCounter(CarAgent[] listCars, Peage[] listPeages)
        {
            int target = 0;
            int counter0 = 0;
            int counter1 = 0;
            int counter2 = 0;
            int counter3 = 0;
            int counter4 = 0;
            int counter5 = 0;

            // We count the number of cars waiting for each counter.
            foreach (CarAgent car in listCars)
            {
                if (car != null && car.Id != id)
                {
                    if (car.PosX > (Road.ZONE_PEAGE_START + 100) && car.PosX < (Road.ZONE_GUICHET_START))
                    {
                        if (car.targetCounter.Id == 5)
                        {
                            counter5++;
                        }
                        else if (car.targetCounter.Id == 4)
                        {
                            counter4++;
                        }
                        else if (car.targetCounter.Id == 3)
                        {
                            counter3++;
                        }
                        else if (car.targetCounter.Id == 2)
                        {
                            counter2++;
                        }
                        else if (car.targetCounter.Id == 1)
                        {
                            counter1++;
                        }
                        else if (car.targetCounter.Id == 0)
                        {
                            counter0++;
                        }
                        else
                        {
                            // ???
                        }
                    }
                }
            }

            // We re-evaluate our options
            switch (road.Id)
            {
                case (1):
                    if (counter0 >= counter1)
                    {
                        target = 1;
                    }
                    else
                    {
                        target = 0;
                    }
                    break;
                case (2):
                    if (counter2 > counter3 || counter4 > counter3)
                    {
                        target = 3;
                    }
                    else if (counter2 > (counter4 + 1))
                    {
                        target = 4;
                    }
                    else
                    {
                        target = 2;
                    }
                    break;
                case (3):
                    if (counter3 > counter4 || counter5 > counter4)
                    {
                        target = 4;
                    }
                    else if ((counter3 + 1) > counter5)
                    {
                        target = 5;
                    }
                    else
                    {
                        target = 3;
                    }
                    break;
            }

            targetCounter = listPeages[target];
        }
예제 #8
0
        public void updateSpeed(CarAgent[] listCars, Peage[] listPeages)
        {
            proximity = Road.MAX_SPEED_ROAD_3;

            // Obstacle detection : For cars
            proximity = detectProximityCars(proximity, listCars);

            // Obstacle detection : For Counters, if the car didn't pay already.
            if (flagPaid == false && (Road.getRoadZone(PosX) == 3 || Road.getRoadZone(PosX) == 4))
            {
                int peageID = -1;

                // Let's find which counter we need to keep track of.
                switch ((int)targetY)
                {
                    case (233):
                        peageID = 0;
                        break;
                    case (283):
                        peageID = 1;
                        break;
                    case (333):
                        peageID = 2;
                        break;
                    case (383):
                        peageID = 3;
                        break;
                    case (433):
                        peageID = 4;
                        break;
                    case (483):
                        peageID = 5;
                        break;
                }

                Peage counter = listPeages[peageID];
                double distance = DistanceTo(counter);
                if (distance < proximity)
                {
                    proximity = distance;
                    if (PosX > Road.ZONE_GUICHET_START)
                    {
                        flagCloseToCounter = true;
                    }
                }
                if (Math.Abs(counter.PosX - PosX) > CAR_WIDTH + 10)
                {
                    flagHorizontalProx = true;
                }
            }

            // Approaching Counter
            if (proximity < MIN_DISTANCE + 20 && flagCloseToCounter == true)
            {
                speedX = 0;
            }
            else if (proximity < speedX + MIN_DISTANCE)
            {
                // Using Brakes!
                if (proximity < MIN_DISTANCE + 20)
                {
                    speedX += (-Road.MAX_SPEED_ROAD_3 * BRAKES_EFFICIENCY) / ACCELERATION; // We take the speed of road 3 as its the fastest.
                    if (speedX < 0)
                    {
                        speedX = 0;
                    }
                }
                // Deceleration with obstacle :
                else if (proximity < (MIN_DISTANCE + 20) * 1.5)
                {
                    speedX += ((Road.MAX_SPEED_ROAD_3 / (proximity / MIN_DISTANCE)) - Road.MAX_SPEED_ROAD_3) / ACCELERATION; // A VERIFIER
                    if (speedX < (Road.MAX_SPEED_ROAD_3 * 0.2) && speedX > 0)
                    {
                        speedX = (Road.MAX_SPEED_ROAD_3 * 0.2);
                    }
                    else if (speedX < (Road.MAX_SPEED_ROAD_3 * 0.2) && speedX == 0)
                    {
                        speedX = (Road.MAX_SPEED_ROAD_3 * 0.1);
                    }
                }

                // Acceleration with obstacle :
                else
                {
                    switch (road.Id)
                    {
                        case 3:
                            speedX += (Road.MAX_SPEED_ROAD_1 - (Road.MAX_SPEED_ROAD_1 * ((MIN_DISTANCE + 20) / proximity))) / ACCELERATION; // A VERIFIER
                            if (speedX > Road.MAX_SPEED_ROAD_1)
                            {
                                speedX = Road.MAX_SPEED_ROAD_1;
                            }
                            break;
                        case 2:
                            speedX += (Road.MAX_SPEED_ROAD_2 - (Road.MAX_SPEED_ROAD_2 * ((MIN_DISTANCE + 20) / proximity))) / ACCELERATION; // A VERIFIER
                            if (speedX > Road.MAX_SPEED_ROAD_2)
                            {
                                speedX = Road.MAX_SPEED_ROAD_2;
                            }
                            break;
                        case 1:
                            speedX += (Road.MAX_SPEED_ROAD_3 - (Road.MAX_SPEED_ROAD_3 * ((MIN_DISTANCE + 20) / proximity))) / ACCELERATION; // A VERIFIER
                            if (speedX > Road.MAX_SPEED_ROAD_3)
                            {
                                speedX = Road.MAX_SPEED_ROAD_3;
                            }
                            break;
                    }
                }
            }
            else
            {
                // Acceleration without obstacle :
                switch (road.Id)
                {
                    case 3:
                        speedX += Road.MAX_SPEED_ROAD_1 / ACCELERATION;
                        if (speedX > Road.MAX_SPEED_ROAD_1)
                        {
                            speedX = Road.MAX_SPEED_ROAD_1;
                        }
                        break;
                    case 2:
                        speedX += Road.MAX_SPEED_ROAD_2 / ACCELERATION;
                        if (speedX > Road.MAX_SPEED_ROAD_2)
                        {
                            speedX = Road.MAX_SPEED_ROAD_2;
                        }
                        break;
                    case 1:
                        speedX += Road.MAX_SPEED_ROAD_3 / ACCELERATION;
                        if (speedX > Road.MAX_SPEED_ROAD_3)
                        {
                            speedX = Road.MAX_SPEED_ROAD_3;
                        }
                        break;
                }
            }

            if (targetY != PosY && flagVerticalProx == false)
            {
                // UP or DOWN?
                int direction = (targetY > PosY ? 1 : -1);
                int directionMov = (speedY >= 0 ? 1 : -1);

                double differenceAbs = Math.Abs(targetY - PosY);

                if (differenceAbs > 30)
                {
                    // Lots of Y distance yet
                    speedY += (speedX * direction) / ACCELERATION;
                }
                else
                {
                    // Not a lot of Y distance
                    double targetYSpeed = (targetY - PosY) * 1.5;
                    bool flagDeceleration = false;
                    if (Math.Abs(speedY) > Math.Abs(targetYSpeed))
                    {
                        speedY += ((-Road.MAX_SPEED_ROAD_3 * directionMov) / ACCELERATION);
                        flagDeceleration = true;
                    }

                    if (Math.Abs(speedY) < Math.Abs(targetYSpeed) && flagDeceleration == true)
                    {
                        speedY = targetYSpeed;
                    }
                    else if (Math.Abs(speedY) < Math.Abs(targetYSpeed) && flagDeceleration == false)
                    {
                        speedY += ((Road.MAX_SPEED_ROAD_3 * direction) / ACCELERATION);
                    }
                }

                if (Math.Abs(speedY) > (speedX * 0.5))
                {
                    speedY = (speedX * 0.5 * direction);
                }

                if (Math.Abs(targetY - PosY) < 3)
                {
                    speedY = 0;
                }
            }
            else
            {
                speedY = speedY/2;
            }
        }
예제 #9
0
        public void pickTargetCounter(Peage[] listPeages)
        {
            int target = 0;

            // A target counter is choosen in accordance with the payment type and current road.
            if (paymentType == 0)
            {
               target = MainWindow.rnd.Next(0,2);
            }
            else if (road.Id == 3)
            {
                target = MainWindow.rnd.Next(4,6);
            }
            else
            {
                target = MainWindow.rnd.Next(2,4);
            }

            targetCounter = listPeages[target];
        }
예제 #10
0
 public void payement(Peage counter)
 {
     // We are at the counter, speed is 0, we haven't paid yet, and aren't already paying.
     if(counter.TimeToOpen != 0)
     {
         flagPaid = true;
         flagPaying = false;
     }
     else if (counter.TimeToClose == 0)
     {
         counter.Payement(timeAtCounter);
         flagPaying = true;
     }
 }
예제 #11
0
        public void updateSpeed(CarAgent[] listCars, Peage[] listPeages)
        {
            proximity = Road.MAX_SPEED_ROAD_3;

            // Obstacle detection : For cars
            proximity = detectProximityCars(proximity, listCars);

            // Obstacle detection : For Counters, if the car didn't pay already.
            if (flagPaid == false && (Road.getRoadZone(PosX) == 3 || Road.getRoadZone(PosX) == 4))
            {
                int peageID = -1;

                // Let's find which counter we need to keep track of.
                switch ((int)targetY)
                {
                case (233):
                    peageID = 0;
                    break;

                case (283):
                    peageID = 1;
                    break;

                case (333):
                    peageID = 2;
                    break;

                case (383):
                    peageID = 3;
                    break;

                case (433):
                    peageID = 4;
                    break;

                case (483):
                    peageID = 5;
                    break;
                }

                Peage  counter  = listPeages[peageID];
                double distance = DistanceTo(counter);
                if (distance < proximity)
                {
                    proximity = distance;
                    if (PosX > Road.ZONE_GUICHET_START)
                    {
                        flagCloseToCounter = true;
                    }
                }
                if (Math.Abs(counter.PosX - PosX) > CAR_WIDTH + 10)
                {
                    flagHorizontalProx = true;
                }
            }

            // Approaching Counter
            if (proximity < MIN_DISTANCE + 20 && flagCloseToCounter == true)
            {
                speedX = 0;
            }
            else if (proximity < speedX + MIN_DISTANCE)
            {
                // Using Brakes!
                if (proximity < MIN_DISTANCE + 20)
                {
                    speedX += (-Road.MAX_SPEED_ROAD_3 * BRAKES_EFFICIENCY) / ACCELERATION; // We take the speed of road 3 as its the fastest.
                    if (speedX < 0)
                    {
                        speedX = 0;
                    }
                }
                // Deceleration with obstacle :
                else if (proximity < (MIN_DISTANCE + 20) * 1.5)
                {
                    speedX += ((Road.MAX_SPEED_ROAD_3 / (proximity / MIN_DISTANCE)) - Road.MAX_SPEED_ROAD_3) / ACCELERATION; // A VERIFIER
                    if (speedX < (Road.MAX_SPEED_ROAD_3 * 0.2) && speedX > 0)
                    {
                        speedX = (Road.MAX_SPEED_ROAD_3 * 0.2);
                    }
                    else if (speedX < (Road.MAX_SPEED_ROAD_3 * 0.2) && speedX == 0)
                    {
                        speedX = (Road.MAX_SPEED_ROAD_3 * 0.1);
                    }
                }

                // Acceleration with obstacle :
                else
                {
                    switch (road.Id)
                    {
                    case 3:
                        speedX += (Road.MAX_SPEED_ROAD_1 - (Road.MAX_SPEED_ROAD_1 * ((MIN_DISTANCE + 20) / proximity))) / ACCELERATION;     // A VERIFIER
                        if (speedX > Road.MAX_SPEED_ROAD_1)
                        {
                            speedX = Road.MAX_SPEED_ROAD_1;
                        }
                        break;

                    case 2:
                        speedX += (Road.MAX_SPEED_ROAD_2 - (Road.MAX_SPEED_ROAD_2 * ((MIN_DISTANCE + 20) / proximity))) / ACCELERATION;     // A VERIFIER
                        if (speedX > Road.MAX_SPEED_ROAD_2)
                        {
                            speedX = Road.MAX_SPEED_ROAD_2;
                        }
                        break;

                    case 1:
                        speedX += (Road.MAX_SPEED_ROAD_3 - (Road.MAX_SPEED_ROAD_3 * ((MIN_DISTANCE + 20) / proximity))) / ACCELERATION;     // A VERIFIER
                        if (speedX > Road.MAX_SPEED_ROAD_3)
                        {
                            speedX = Road.MAX_SPEED_ROAD_3;
                        }
                        break;
                    }
                }
            }
            else
            {
                // Acceleration without obstacle :
                switch (road.Id)
                {
                case 3:
                    speedX += Road.MAX_SPEED_ROAD_1 / ACCELERATION;
                    if (speedX > Road.MAX_SPEED_ROAD_1)
                    {
                        speedX = Road.MAX_SPEED_ROAD_1;
                    }
                    break;

                case 2:
                    speedX += Road.MAX_SPEED_ROAD_2 / ACCELERATION;
                    if (speedX > Road.MAX_SPEED_ROAD_2)
                    {
                        speedX = Road.MAX_SPEED_ROAD_2;
                    }
                    break;

                case 1:
                    speedX += Road.MAX_SPEED_ROAD_3 / ACCELERATION;
                    if (speedX > Road.MAX_SPEED_ROAD_3)
                    {
                        speedX = Road.MAX_SPEED_ROAD_3;
                    }
                    break;
                }
            }

            if (targetY != PosY && flagVerticalProx == false)
            {
                // UP or DOWN?
                int direction    = (targetY > PosY ? 1 : -1);
                int directionMov = (speedY >= 0 ? 1 : -1);

                double differenceAbs = Math.Abs(targetY - PosY);

                if (differenceAbs > 30)
                {
                    // Lots of Y distance yet
                    speedY += (speedX * direction) / ACCELERATION;
                }
                else
                {
                    // Not a lot of Y distance
                    double targetYSpeed     = (targetY - PosY) * 1.5;
                    bool   flagDeceleration = false;
                    if (Math.Abs(speedY) > Math.Abs(targetYSpeed))
                    {
                        speedY          += ((-Road.MAX_SPEED_ROAD_3 * directionMov) / ACCELERATION);
                        flagDeceleration = true;
                    }

                    if (Math.Abs(speedY) < Math.Abs(targetYSpeed) && flagDeceleration == true)
                    {
                        speedY = targetYSpeed;
                    }
                    else if (Math.Abs(speedY) < Math.Abs(targetYSpeed) && flagDeceleration == false)
                    {
                        speedY += ((Road.MAX_SPEED_ROAD_3 * direction) / ACCELERATION);
                    }
                }

                if (Math.Abs(speedY) > (speedX * 0.5))
                {
                    speedY = (speedX * 0.5 * direction);
                }

                if (Math.Abs(targetY - PosY) < 3)
                {
                    speedY = 0;
                }
            }
            else
            {
                speedY = speedY / 2;
            }
        }
예제 #12
0
        public void updateTargetCounter(CarAgent[] listCars, Peage[] listPeages)
        {
            int target   = 0;
            int counter0 = 0;
            int counter1 = 0;
            int counter2 = 0;
            int counter3 = 0;
            int counter4 = 0;
            int counter5 = 0;

            // We count the number of cars waiting for each counter.
            foreach (CarAgent car in listCars)
            {
                if (car != null && car.Id != id)
                {
                    if (car.PosX > (Road.ZONE_PEAGE_START + 100) && car.PosX < (Road.ZONE_GUICHET_START))
                    {
                        if (car.targetCounter.Id == 5)
                        {
                            counter5++;
                        }
                        else if (car.targetCounter.Id == 4)
                        {
                            counter4++;
                        }
                        else if (car.targetCounter.Id == 3)
                        {
                            counter3++;
                        }
                        else if (car.targetCounter.Id == 2)
                        {
                            counter2++;
                        }
                        else if (car.targetCounter.Id == 1)
                        {
                            counter1++;
                        }
                        else if (car.targetCounter.Id == 0)
                        {
                            counter0++;
                        }
                        else
                        {
                            // ???
                        }
                    }
                }
            }

            // We re-evaluate our options
            switch (road.Id)
            {
            case (1):
                if (counter0 >= counter1)
                {
                    target = 1;
                }
                else
                {
                    target = 0;
                }
                break;

            case (2):
                if (counter2 > counter3 || counter4 > counter3)
                {
                    target = 3;
                }
                else if (counter2 > (counter4 + 1))
                {
                    target = 4;
                }
                else
                {
                    target = 2;
                }
                break;

            case (3):
                if (counter3 > counter4 || counter5 > counter4)
                {
                    target = 4;
                }
                else if ((counter3 + 1) > counter5)
                {
                    target = 5;
                }
                else
                {
                    target = 3;
                }
                break;
            }

            targetCounter = listPeages[target];
        }
예제 #13
0
        void theWorld_WorldUpdatedEvent(CarAgent[] listCars, Peage[] listPeages)
        {
            worldCanvas.Children.Clear();

            // Let's roll the dice for new cars!
            randomRoll = rnd.Next(1, (CarAgent.SPAWN_RATE + 1));

            if (randomRoll == 1)
            {
                // Lucky Roll! This step will see a new car.
                n = 0;

                while (n <= carCount)
                {
                    // Let's find the first position available in the list.
                    if (listCars[n] == null)
                    {
                        listCars[n] = new CarAgent(n, listCars, theWorld, listPeages);
                        n = carCount;
                    }
                    n++;
                }

                carCount++;
            }

            if (carCount > 0)
            {
                foreach (CarAgent car in listCars)
                {
                    if (car != null) {
                        DrawCar(car, listCars);
                    }
                }
            }

            // UI Update

            // Car Count
                TextBlock tbCarCount = new TextBlock();
                tbCarCount.Text = "Nombre de voitures : " + carCount;
                tbCarCount.Foreground = new SolidColorBrush(Colors.White);
                Canvas.SetTop(tbCarCount, (5));
                Canvas.SetLeft(tbCarCount, (5));
                worldCanvas.Children.Add(tbCarCount);

            // Spawn Rate
                TextBlock tbSpawnRate = new TextBlock();
                tbSpawnRate.Text = "Taux d'apparition : " + CarAgent.SPAWN_RATE_INVERSE;
                tbSpawnRate.Foreground = new SolidColorBrush(Colors.White);
                Canvas.SetTop(tbSpawnRate, (5));
                Canvas.SetLeft(tbSpawnRate, (175));
                worldCanvas.Children.Add(tbSpawnRate);

            // Minimum Time At Counter
                TextBlock tbMinTAT = new TextBlock();
                tbMinTAT.Text = "Durée minimum au guichet : " + CarAgent.MIN_TAT_DURATION;
                tbMinTAT.Foreground = new SolidColorBrush(Colors.White);
                Canvas.SetTop(tbMinTAT, (17));
                Canvas.SetLeft(tbMinTAT, (175));
                worldCanvas.Children.Add(tbMinTAT);

            // Maximum Time At Counter
                TextBlock tbMaxTAT = new TextBlock();
                tbMaxTAT.Text = "Durée maximum au guichet : " + CarAgent.MAX_TAT_DURATION;
                tbMaxTAT.Foreground = new SolidColorBrush(Colors.White);
                Canvas.SetTop(tbMaxTAT, (29));
                Canvas.SetLeft(tbMaxTAT, (175));
                worldCanvas.Children.Add(tbMaxTAT);

            // Minimum Time At Counter
                TextBlock tbMinTATT = new TextBlock();
                tbMinTATT.Text = "Durée minimum au guichet télépéage : " + CarAgent.MIN_TAT_DURATION_T;
                tbMinTATT.Foreground = new SolidColorBrush(Colors.White);
                Canvas.SetTop(tbMinTATT, (41));
                Canvas.SetLeft(tbMinTATT, (175));
                worldCanvas.Children.Add(tbMinTATT);

            // Maximum Time At Counter
                TextBlock tbMaxTATT = new TextBlock();
                tbMaxTATT.Text = "Durée maximum au guichet télépéage : " + CarAgent.MAX_TAT_DURATION_T;
                tbMaxTATT.Foreground = new SolidColorBrush(Colors.White);
                Canvas.SetTop(tbMaxTATT, (53));
                Canvas.SetLeft(tbMaxTATT, (175));
                worldCanvas.Children.Add(tbMaxTATT);

            worldCanvas.UpdateLayout();
        }