/// <summary> /// Ongoing car race /// </summary> /// <param name="auto">The car in the race</param> public void CarRaceProcess(Automobile auto) { // Making sure all 3 cars start the race at the same time raceCDE.Signal(); raceCDE.Wait(); // All cars start moving around the same time auto.Move(auto); // While the car tank has gas he can run the race while (auto.TankVolume > 0) { // Driving towards the semaphore DrivingWithoutStop(10, auto); Console.WriteLine("{0} {1} reached the semaphore, currently the light is {2}", auto.Color, auto.Producer, semaphoreColor); while (semaphoreColor == "Red") { Thread.Sleep(0); } // Thread safe counter Interlocked.Increment(ref carCounter); // Driving towards the gas station DrivingWithoutStop(3, auto); if (auto.TankVolume < 15) { ChargingAtGasStation(auto); } else { Console.WriteLine("{0} {1} passed the gas station with tank: {2}l.", auto.Color, auto.Producer, auto.TankVolume); } // Driving to the finish line DrivingWithoutStop(7, auto); break; } // Checks if the car is out of gas if (auto.TankVolume <= 0) { auto.Stop(auto); Console.WriteLine("\t\t\t\t\t\t\t\t{0} {1} is out of gas and left the race.", auto.Color, auto.Producer); } else if (auto.TankVolume > 0) { Console.WriteLine("{0} {1} crossed the finish line.", auto.Color, auto.Producer); // Reset the tank volume auto.TankVolume = 45; auto.Stop(auto); } winner.WaitOne(); FinalResult(auto); }
/// <summary> /// Charging the car tanks one by one /// </summary> public void ChargingAtGasStation(Automobile auto) { gasStationQueue.Wait(); Console.WriteLine("{0} {1} is charging their tank, current tank: {2}l", auto.Color, auto.Producer, auto.TankVolume); // Time it takes to charge it Thread.Sleep(100); auto.TankVolume = 45; Console.WriteLine("{0} {1} finished charging their tank", auto.Color, auto.Producer); gasStationQueue.Release(); }
/// <summary> /// Car is driving towards an objective without stop /// </summary> /// <param name="time">Given time until an objective appears</param> /// <param name="auto">The car that is driving</param> public void DrivingWithoutStop(int time, Automobile auto) { for (int i = 0; i < time; i++) { Thread.Sleep(1000); if (auto.TankVolume <= 0) { break; } } }
/// <summary> /// Prints out the final result depending on the circumstances /// </summary> /// <param name="auto">The car that crossed the finish line</param> public void FinalResult(Automobile auto) { // Thread safe counter Interlocked.Increment(ref carCounter); // Increment only for cars that crossed the finish line if (auto.TankVolume > 0) { Interlocked.Increment(ref winCarCounter); } // Print ranking board if (winCarCounter == 1 && auto.TankVolume > 0) { Console.WriteLine("\t\t\t\t\t\t\t\tRanking board:\n\t\t\t\t\t\t\t\t{0}. {1} {2}", winCarCounter, auto.Color, auto.Producer); } else if (auto.TankVolume > 0) { Console.WriteLine("\t\t\t\t\t\t\t\t{0}. {1} {2}", winCarCounter, auto.Color, auto.Producer); } // Print top red car board if (auto.Color == "Red" && noOne == false && auto.TankVolume > 0) { noOne = true; FastestRedCar(auto); } else if (carCounter == 3 && Program.containsRedCar == false) { Console.WriteLine("\n-----------------\nThere were no red cars in the race.\n-----------------"); raceOver = true; } else if (carCounter == 3 && Program.containsRedCar == true && noOne == false) { Console.WriteLine("\n-----------------\nNo red cars crossed the finish line.\n-----------------"); raceOver = true; } else if (carCounter == 3) { raceOver = true; } winner.Set(); }
/// <summary> /// Creates a new car /// </summary> public override void Create() { Automobile auto = new Automobile { MotorVolume = Math.Round(rng.NextDouble() * 1000, 2), Weight = rng.Next(1000, 2001), Category = allCategory[rng.Next(0, allCategory.Length)], MotorType = allMotorType[rng.Next(0, allMotorType.Length)], Color = allColors[rng.Next(0, allColors.Length)], MotorNumber = rng.Next(30, 101), RegistrationNumber = rng.Next(1000, 10000).ToString(), DoorNumber = rng.Next(2, 6), TankVolume = 45, TransportType = allTransportType[rng.Next(0, allTransportType.Length)], Producer = allProducer[rng.Next(0, allProducer.Length)], TrafficNumber = rng.Next(1000, 10000) }; Raceing.raceCDE.AddCount(); Program.allAutomobiles.Add(auto); }
/// <summary> /// Method that stops the vehicles motor /// </summary> /// <param name="obj">vehicle we are running</param> public override void Stop(object obj) { Automobile auto = (Automobile)obj; Console.WriteLine(auto.Color + " " + auto.Producer + " turned off the motor and stopped moving."); }
/// <summary> /// Fastest red card board /// </summary> /// <param name="auto">Shows the red cars as the pass the finish line</param> public void FastestRedCar(Automobile auto) { winner.Set(); Console.WriteLine("\n-----------------\nFastest red car is: {0} {1}.\n-----------------", auto.Color, auto.Producer); }
/// <summary> /// The main Method /// </summary> /// <param name="args">Main arguments</param> static void Main(string[] args) { Automobile auto = new Automobile(); Truck truck = new Truck(); Tractor tractor = new Tractor(); Raceing race = new Raceing(); // Creating vehicle objects for (int i = 0; i < 2; i++) { auto.Create(); truck.Create(); tractor.Create(); } // Countdown for (int i = 0; i < 6; i++) { Console.WriteLine(i); if (i == 5) { break; } Thread.Sleep(1000); } // Starting threads for (int i = 0; i < allAutomobiles.Count; i++) { // Because i is not thread safe due to being located on the same memory location for every thread and it is incremented all the time. int temp = i; Thread thread1 = new Thread(() => race.CarRaceProcess(allAutomobiles[temp])); thread1.Start(); } containsRedCar = Program.allAutomobiles.Any(car => car.Color == "Red"); // Creating golf car Random rng = new Random(); Automobile golf = new Automobile { Color = "Orange", TankVolume = 45, Producer = "Golf" }; allAutomobiles.Add(golf); // Starting golf Console.WriteLine(golf.Color + " " + golf.Producer + " joined the race\n\n--------------------------"); Thread thread2 = new Thread(() => race.CarRaceProcess(golf)); thread2.Start(); // Thread that changes the semaphore color every 2 seconds Thread thread3 = new Thread(race.ChangeSemaphoreColor) { IsBackground = true }; thread3.Start(); // Thread that reduces the Tank Volume every 1 second Thread thread4 = new Thread(race.TankDecrease) { IsBackground = true }; thread4.Start(); Console.ReadKey(); }