コード例 #1
0
ファイル: WorldModel.cs プロジェクト: JustinBritt/Epidemic
        /// <summary>
        /// Initializes a new instance of the <see cref="WorldModel"/> class.
        /// </summary>
        /// <param name="mapData">The map data.</param>
        /// <param name="countryData">The country data.</param>
        /// <param name="ortCounts">For each country, the number of Outbreak Response Teams it has, and the color they are rendered in.</param>
        /// <param name="execParameters">The execute parameters.</param>
        public WorldModel(MapData mapData, List<SimCountryData> countryData, Dictionary<string, Tuple<int,Color>> ortCounts = null, ExecParameters execParameters = null)
        {
            
            Executive = ExecFactory.Instance.CreateExecutive(ExecType.FullFeatured);
            ExecutionParameters = execParameters?? new ExecParameters();
            m_controller = new Controller(this);

            m_countryDataByCountryCodes = new Dictionary<string, SimCountryData>();
            countryData.ForEach(n=> m_countryDataByCountryCodes.Add(n.CountryCode, n));

            m_ortCounts = ortCounts??new Dictionary<string, Tuple<int, Color>>();
            m_mapData = mapData;
            m_nodes = new DiseaseNode[m_mapData.Width, m_mapData.Height];
            m_size = new Size(m_mapData.Width, m_mapData.Height);

            for (int x = 0; x < m_mapData.Width; x++)
            {
                for (int y = 0; y < m_mapData.Height; y++)
                {
                    double density = m_mapData.CellData[x, y].PopulationDensity;
                    if (Math.Abs(density - CellData.NO_DATA) < 0.01) density = 0.0;
                    double landArea = m_mapData.CellData[x, y].LandArea;
                    double waterArea = m_mapData.CellData[x, y].WaterArea;
                    Locale locale = new Locale(Locale.DEFAULT);
                    switch (m_mapData.CellData[x, y].CellState)
                    {
                        case CellState.Unknown:
                            locale.Population = 0;
                            locale.Area = Locale.DEFAULT.Area;
                            break;
                        case CellState.Occupied:
                            locale.Area = landArea + (Math.Abs(waterArea - CellData.NO_DATA) < 0.01 ? 0 : waterArea);
                            if (locale.Area <= 0.001) locale.Area = Locale.DEFAULT.Area;
                            locale.Population = density * landArea;
                            break;
                        case CellState.Unoccupied:
                            locale.Population = 0;
                            break;
                        case CellState.Ocean:
                            locale.Population = 0;
                            break;
                        default:
                            break;
                    }

                    double lat, lon;
                    m_mapData.DataXYToLatLon(x,y,out lat, out lon);
                    m_nodes[x, y] = new DiseaseNode(Policy.DEFAULT, locale, Disease.DEFAULT);

                    // Bidirectional Cross-Reference.
                    m_nodes[x, y].MapCell = m_mapData.CellData[x, y];
                    m_mapData.CellData[x, y].DiseaseModel = m_nodes[x, y];
                }
            }

            CreateAndAssignGovernments();
        }
コード例 #2
0
 /// <summary>
 /// Updates this country's disease nodes with disease-impacting country-specific data
 /// such as HealthCareEffectiveness and SocialStability.
 /// </summary>
 /// <param name="initializing">if set to <c>true</c> [initializing].</param>
 internal void UpdateDiseaseNodes(bool initializing = false)
 {
     foreach (Coordinates coordinates in DiseaseNodeCoordinates)
     {
         if (initializing)
         {
             DiseaseNode dn = WorldModel.DiseaseNodes[coordinates.X, coordinates.Y];
             dn.LocaleData.HealthCareEffectiveness         = SimCountryData.HealthCareEffectiveness;
             dn.LocaleData.SocialStability                 = SimCountryData.SocialStability;
             dn.LocaleData.ForeignImmunizationAidPerCapita = 0.0;
             // Birth rate, mortality, doctors per capita...
         }
         else
         {
             // TODO: Some day, we'll have dynamic evolution of ... stuff.
         }
     }
 }
コード例 #3
0
        /// <summary>
        /// The national government is given an opportunity to reassess itself after each cycle.
        /// </summary>
        /// <param name="exec">The execute.</param>
        internal void Reassess(IExecutive exec)
        {
            double evidentlyInfected = 0;
            double population        = 0;

            foreach (Coordinates dnCoordinates in DiseaseNodeCoordinates)
            {
                DiseaseNode dn = WorldModel.DiseaseNodes[dnCoordinates.X, dnCoordinates.Y];
                evidentlyInfected += dn.NonContagiousInfected;
                evidentlyInfected += dn.ContagiousAsymptomatic;
                evidentlyInfected += dn.ContagiousSymptomatic;
                evidentlyInfected += dn.Killed;
                population        += dn.Population;
            }

            // Once we have greater than half a percent of the
            // population infected, establish a quarantine on every
            // cell in the country.
            if (evidentlyInfected > (.005 * population))
            {
                bool alreadyQuarantined = false;
                foreach (Coordinates dnCoordinates in DiseaseNodeCoordinates)
                {
                    DiseaseNode dn = WorldModel.DiseaseNodes[dnCoordinates.X, dnCoordinates.Y];
                    if (dn.Quarantined)
                    {
                        alreadyQuarantined = true;
                        break;
                    }
                    dn.Quarantined = true;
                }
                if (!alreadyQuarantined)
                {
                    console.WriteLine($"{exec.Now} : {SimCountryData.Name} is quarantining all of its cells.");
                }
            }
        }
コード例 #4
0
ファイル: WorldModel.cs プロジェクト: JustinBritt/Epidemic
        /// <summary>
        /// Updates the world model by one SD timeslice.
        /// </summary>
        /// <param name="exec">The executive under which this update is being done.</param>
        /// <param name="manualResetEvent1">The manual reset event1.</param>
        /// <param name="manualResetEvent2">The manual reset event2.</param>
        internal void Update(IExecutive exec, ManualResetEvent manualResetEvent1 = null, ManualResetEvent manualResetEvent2 = null)
        {
            ILineWriter console = Locator.Resolve<ILineWriter>("console");
            m_governments.ForEach(n=>n.UpdateDiseaseNodes());
            bool travelOnlyFromToApparentlyDiseaseFree = NoAirTravelFromToKnownInfected;
            manualResetEvent1?.WaitOne();
            manualResetEvent2?.WaitOne();
            //DateTime now = DateTime.Now;
            DiseaseNode[,] newNodes = new DiseaseNode[m_mapData.Width, m_mapData.Height];
            // Progress the simulation one time step.

            int count1 = 0, count2 = 0;

#if AUTO_INOCULATE
            if (m_nodes[0, 0].TimeSliceNdx == 10 && m_districtsOfInterest != null)
            {
                {
                    foreach (var tuple in m_districtsOfInterest)
                    {
                        console.WriteLine($"Inoculating at {tuple.Item1},{tuple.Item2} with patient zero.");
                        m_nodes[tuple.Item1, tuple.Item2].ContagiousAsymptomatic++;
                        console.WriteLine(m_nodes[tuple.Item1, tuple.Item2]);
                    }
                }
            }
#endif

#if USE_PARALLEL
            Parallel.For(0, m_mapData.Width, x =>
            {
#else
            for (int x = 0; x < m_data.Width; x++)
            {
#endif
                for (int y = 0; y < m_mapData.Height; y++)
                {
                    if (!m_mapData.CellData[x, y].CellState.Equals(CellState.Occupied))
                    {
                        if (m_mapData.CellData[x, y].DiseaseModel.Population > 0) Debugger.Break();
                        newNodes[x, y] = m_nodes[x, y];
                        newNodes[x, y].TimeSliceNdx++;
                        Interlocked.Increment(ref count1);
                    }
                    else
                    {
                        //EpidemicNode.m_debug = (x == 243 && y == 240);
                        //if ( x== 243 && y == 240 && m_nodes[x, y].TimeSliceNdx == 63) Debugger.Break();
                        DiseaseNode oldNode = m_nodes[x, y];
                        DiseaseNode newNode = Behavior<DiseaseNode>.RunOneTimeslice(m_nodes[x, y]);
                        newNodes[x, y] = newNode;
                        if (oldNode.ContagiousAsymptomatic < EPSILON && newNode.ContagiousAsymptomatic > EPSILON)
                        {
                            ReportNewlyInfectedNode(new Coordinates() {X=x, Y=y});
                        }
                        Interlocked.Increment(ref count2);
                    }
                }

#if USE_PARALLEL
            });
#else
            } // Non-parallel.
コード例 #5
0
ファイル: WorldModel.cs プロジェクト: JustinBritt/Epidemic
        private void CreateAndAssignGovernments()
        {
            m_allORTs = new List<OutbreakResponseTeam>();
            ILineWriter console = Locator.Resolve<ILineWriter>("console");
            Dictionary<string, List<Coordinates>> nodeToCountryMapping = new Dictionary<string, List<Coordinates>>();

            for (int x = 0; x < m_mapData.Width; x++)
            {
                for (int y = 0; y < m_mapData.Height; y++)
                {
                    DiseaseNode dn = m_nodes[x, y];
                    string cc = dn.MapCell.CountryCode;
                    if (cc != null && !"--".Equals(cc))
                    {
                        List<Coordinates> diseaseNodeCoordinates;
                        if (!nodeToCountryMapping.TryGetValue(cc, out diseaseNodeCoordinates))
                        {
                            diseaseNodeCoordinates = new List<Coordinates>();
                            nodeToCountryMapping.Add(cc, diseaseNodeCoordinates);
                        }
                        diseaseNodeCoordinates.Add(new Coordinates {X = x, Y = y});
                    }
                }
            }

            Dictionary<string, NationalGovernment> govts = new Dictionary<string, NationalGovernment>();
            for (int x = 0; x < m_mapData.Width; x++)
            {
                for (int y = 0; y < m_mapData.Height; y++)
                {
                    DiseaseNode dn = m_nodes[x, y];
                    string countryCode = dn.MapCell.CountryCode;
                    if ("--".Equals(countryCode)) continue;
                    if (countryCode == null) continue;
                    if (!m_countryDataByCountryCodes.ContainsKey(countryCode))
                    {
                        //console.WriteLine($"No country data for country code \"{countryCode}\".");
                        continue;
                    }
                    SimCountryData simCountryData = m_countryDataByCountryCodes[countryCode];
                    if (nodeToCountryMapping.ContainsKey(dn.MapCell.CountryCode))
                    {
                        if (!govts.ContainsKey(countryCode))
                        {
                            NationalGovernment ng = new NationalGovernment(this)
                            {
                                WorldModel = this,
                                SimCountryData = m_countryDataByCountryCodes[countryCode],
                                DiseaseNodeCoordinates = nodeToCountryMapping[countryCode]
                            };

                            if (m_ortCounts.ContainsKey(simCountryData.CountryCode))
                            {
                                var ortCount = m_ortCounts[simCountryData.CountryCode];
                                int numberOfResponseTeams = ortCount.Item1;
                                for (int i = 0; i < numberOfResponseTeams; i++)
                                {
                                    int randomDiseaseNode = m_random.Next(0, ng.DiseaseNodeCoordinates.Count - 1);
                                    Coordinates initialCoordinates = ng.DiseaseNodeCoordinates[randomDiseaseNode];
                                    OutbreakResponseTeam ort = 
                                        new OutbreakResponseTeam(simCountryData.CountryCode, i, ortCount.Item2, this, initialCoordinates);
                                    ng.ResponseTeams.Add(ort);
                                    simCountryData.ResponseTeams.Add(ort);
                                    m_allORTs.Add(ort);
                                }
                            }

                            simCountryData.Government = ng;
                            govts.Add(countryCode, ng);
                            ng.UpdateDiseaseNodes(true);
                        }
                    }
                    else
                    {
                        console.WriteLine($"Could not find a list of nodes for country code {simCountryData.CountryCode}");
                    }

                }
            }
            m_governments.AddRange(govts.Values);
        }