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); }
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; } }
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]; }
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); } }
// 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); }
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]; }
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; } }
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]; }
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; } }
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; } }
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(); }