Example #1
0
        [MethodImpl(MethodImplOptions.Synchronized)] //Alters state of simulation, therefore access synchronized.
        public void Step()
        {
            try
            {
                Airplane outgoing  = null;                               //Next plane to takeoff.
                Airplane incoming  = null;                               //Next plane to land.
                AirRoute currRoute = null;                               //Airplanes current AirRoute.
                Airplane ap;                                             //Current airplane of loop.
                double   currRouteDist;
                for (int i = m_airport.Airplanes.Count - 1; i >= 0; i--) //Reverse for loop used because airplanes are removed from list.
                {
                    ap = m_airport.Airplanes[i];
                    switch (ap.State)
                    {
                    case 'I':                                                    //In transit
                        ap.Fuel -= (ap.FuelConsPerHour / 4.0);                   //Decrement fuel.
                        ap.DistanceAlongRoute += (ap.CruisingKPH / 4.0);         //Increment distance along route.
                        currRoute              = GetRoute(ap.CurrentAirRouteID); //Get airplane's current route.
                        if (currRoute != null)
                        {
                            if (ap.DistanceAlongRoute >= currRoute.DistanceKM)     //If reached airport pass control.
                            {
                                ap.DistanceAlongRoute = currRoute.DistanceKM;
                                ap.State = 'C';
                                m_ATCBiz.PassControl(ap, currRoute.ToAirportID);
                                m_airport.Airplanes.Remove(ap);
                            }
                            else if (ap.DistanceAlongRoute + 300.0 >= currRoute.DistanceKM)     //If within 300km of airport pass control.
                            {
                                ap.State = 'E';
                                m_ATCBiz.PassControl(ap, currRoute.ToAirportID);
                                m_airport.Airplanes.Remove(ap);
                            }
                        }
                        else
                        {
                            System.Console.WriteLine("Error: No assigned route for In Transit Airplane " + ap.AirplaneID); //Should never reach this state.
                        }
                        currRoute = null;                                                                                  //Reset.
                        break;

                    case 'E':                                                                 //Entering circling
                        SelectLanding(ap, ref incoming);                                      //Test if this plane should land next.
                        ap.Fuel -= (ap.FuelConsPerHour / 4.0);                                //Decrement fuel.
                        ap.DistanceAlongRoute += (ap.CruisingKPH / 4.0);                      //Increment distance along route.
                        currRouteDist          = m_ATCBiz.GetRouteDist(ap.CurrentAirRouteID); //Get airplane's current route.
                        if (ap.Fuel <= 0.0)                                                   //Test if crashed.
                        {
                            ap.Fuel  = 0.0;
                            ap.State = 'X';
                        }
                        else if (currRouteDist != 0)
                        {
                            if (ap.DistanceAlongRoute >= currRouteDist)     //Can either land this time step (From Entering Circling state) or start Circling.
                            {
                                ap.DistanceAlongRoute = currRouteDist;
                                ap.State = 'C';     //Set to Circling in case plane can't land this time step.
                            }
                        }
                        else
                        {
                            System.Console.WriteLine("Error: No assigned route for Entering Circling Airplane " + ap.AirplaneID);      //Should never reach this state.
                        }
                        break;

                    case 'C':                                  //Circling
                        SelectLanding(ap, ref incoming);       //Test if this plane should land next.
                        ap.Fuel -= (ap.FuelConsPerHour / 4.0); //Decrement fuel.
                        if (ap.Fuel <= 0.0)                    //Test if crashed.
                        {
                            ap.Fuel  = 0.0;
                            ap.State = 'X';
                        }
                        break;

                    case 'L':                    //Landed
                        if (ap.TimeLanded >= 60) //If refuelled.
                        {
                            if (outgoing != null)
                            {
                                if (ap.TimeLanded > outgoing.TimeLanded)
                                {
                                    outgoing = ap;                                          //Select airplane thats been waiting the longest.
                                }
                            }
                            else
                            {
                                outgoing = ap;
                            }
                        }
                        ap.TimeLanded += 15;     //Increment time landed.
                        break;

                    case 'X':    //Crashed
                        break;   //Ignore. No processing required.

                    default:     //Should never reach this.
                        System.Console.WriteLine("Airplane " + ap.AirplaneID + " in unexpected state: " + ap.State);
                        break;
                    }
                }

                //Finished updating planes status. Now process planes selected to take off & land.
                if (outgoing != null)     //If a plane has been selected to take off.
                {
                    outgoing.State = 'I'; //Set to In transit and update values.
                    outgoing.DistanceAlongRoute = 0;
                    outgoing.CurrentAirRouteID  = m_airport.Routes[m_airport.NextRoute].AirRouteID;
                    outgoing.CurrentAirportID   = -1;
                    outgoing.TimeLanded         = -1;
                    outgoing.Fuel = (m_airport.Routes[m_airport.NextRoute].DistanceKM / outgoing.CruisingKPH) * outgoing.FuelConsPerHour * 1.15;
                    if (m_airport.Routes[m_airport.NextRoute].DistanceKM <= 300) //If airport within 300km then pass control (Unlikely).
                    {
                        m_ATCBiz.PassControl(outgoing, m_airport.Routes[m_airport.NextRoute].ToAirportID);
                        m_airport.Airplanes.Remove(outgoing);
                    }
                    if (m_airport.NextRoute + 2 > m_airport.Routes.Count)
                    {
                        m_airport.NextRoute = 0;                                                   //Set next airroute.
                    }
                    else
                    {
                        m_airport.NextRoute += 1;
                    }
                }
                if (incoming != null)                  //If a plane has been selected to land.
                {
                    incoming.State              = 'L'; //Set to Landed and update values.
                    incoming.CurrentAirRouteID  = -1;
                    incoming.DistanceAlongRoute = -1;
                    incoming.CurrentAirportID   = m_airport.AirportID;
                    incoming.TimeLanded         = 0;
                }
            }
            catch (FaultException ex) //SOAP fault.
            {
                System.Console.WriteLine(ex.Message);
            }
            catch (CommunicationException ex) //Communication error.
            {
                System.Console.WriteLine("Can't connect to Server");
                System.Console.WriteLine(ex.Message);
            }
            catch (TimeoutException ex) //Server likely has died or halted.
            {
                System.Console.WriteLine("Server timed out");
                System.Console.WriteLine(ex.Message);
            }
            catch (Exception ex) //Generic exception for unknown problem.
            {
                System.Console.WriteLine("Exception type: " + ex.GetType());
                System.Console.WriteLine("Exception message: " + ex.Message);
            }
        }