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