private void DecomposeFreeBuildings(SerializableCivilizationData civData, ICivilization newCiv)
        {
            if (civData.FreeBuildings != null)
            {
                foreach (List <string> freeBuildingSetByName in civData.FreeBuildings)
                {
                    var freeBuildingSet = new List <IBuildingTemplate>();

                    foreach (string templateName in freeBuildingSetByName)
                    {
                        var templateOfName = BuildingTemplates.Where(template => template.name.Equals(templateName)).FirstOrDefault();

                        if (templateOfName == null)
                        {
                            throw new InvalidOperationException(
                                      string.Format("CivData.FreeBuildings had invalid building name {0} in it", templateName)
                                      );
                        }

                        freeBuildingSet.Add(templateOfName);
                    }

                    FreeBuildingsCanon.SubscribeFreeBuildingToCiv(freeBuildingSet, newCiv);
                }
            }
        }
        private void DecomposeTechs(SerializableCivilizationData civData, ICivilization newCiv)
        {
            if (civData.TechQueue != null)
            {
                for (int i = 0; i < civData.TechQueue.Count; i++)
                {
                    var techName = civData.TechQueue[i];

                    var techOfName = AvailableTechs.Where(tech => tech.Name.Equals(techName)).FirstOrDefault();
                    if (techOfName == null)
                    {
                        throw new InvalidOperationException(string.Format("CivData.TechQueue had invalid tech name {0} in it", techName));
                    }
                    newCiv.TechQueue.Enqueue(techOfName);
                }
            }

            if (civData.DiscoveredTechs != null)
            {
                foreach (var discoveredTechName in civData.DiscoveredTechs)
                {
                    var techOfName = AvailableTechs.Where(tech => tech.Name.Equals(discoveredTechName)).FirstOrDefault();
                    if (techOfName == null)
                    {
                        throw new InvalidOperationException(
                                  string.Format("CivData.DiscoveredTechs had invalid tech name {0} in it", discoveredTechName)
                                  );
                    }

                    TechCanon.SetTechAsDiscoveredForCiv(techOfName, newCiv);
                }
            }

            if (civData.ProgressOnTechs != null)
            {
                foreach (var techInProgressName in civData.ProgressOnTechs.Keys)
                {
                    var techOfName = AvailableTechs.Where(tech => tech.Name.Equals(techInProgressName)).FirstOrDefault();
                    if (techOfName == null)
                    {
                        throw new InvalidOperationException(
                                  string.Format("CivData.ProgressOnTechs had invalid tech name {0} in it", techInProgressName)
                                  );
                    }

                    TechCanon.SetProgressOnTechByCiv(techOfName, newCiv, civData.ProgressOnTechs[techInProgressName]);
                }
            }
        }
        public void ComposeCivilizations(SerializableMapData mapData)
        {
            mapData.Civilizations = new List <SerializableCivilizationData>();

            foreach (var civilization in CivilizationFactory.AllCivilizations)
            {
                var civData = new SerializableCivilizationData()
                {
                    TemplateName     = civilization.Template.Name,
                    GoldStockpile    = civilization.GoldStockpile,
                    CultureStockpile = civilization.CultureStockpile,
                    DiscoveredTechs  = TechCanon.GetTechsDiscoveredByCiv(civilization).Select(tech => tech.Name).ToList(),
                    SocialPolicies   = PolicyComposer.ComposePoliciesFromCiv(civilization),
                };

                if (civilization.TechQueue != null && civilization.TechQueue.Count > 0)
                {
                    civData.TechQueue = civilization.TechQueue.Select(tech => tech.Name).ToList();
                }
                else
                {
                    civData.TechQueue = null;
                }

                var availableTechs = TechCanon.GetTechsAvailableToCiv(civilization);

                if (availableTechs.Count() > 0)
                {
                    foreach (var availableTech in availableTechs)
                    {
                        int progress = TechCanon.GetProgressOnTechByCiv(availableTech, civilization);
                        if (progress != 0)
                        {
                            if (civData.ProgressOnTechs == null)
                            {
                                civData.ProgressOnTechs = new Dictionary <string, int>();
                            }

                            civData.ProgressOnTechs[availableTech.Name] = progress;
                        }
                    }
                }
                else
                {
                    civData.ProgressOnTechs = null;
                }

                var exploredCells = Grid.Cells.Where(cell => ExplorationCanon.IsCellExploredByCiv(cell, civilization));

                civData.ExploredCells = exploredCells.Select(cell => cell.Coordinates).ToList();

                civData.FreeBuildings = FreeBuildingsCanon
                                        .GetFreeBuildingsForCiv(civilization)
                                        .Select(buildingList => buildingList.Select(buildingTemplate => buildingTemplate.name).ToList())
                                        .ToList();

                civData.GoldenAgeTurnsLeft = GoldenAgeCanon.GetTurnsLeftOnGoldenAgeForCiv(civilization);
                civData.GoldenAgeProgress  = GoldenAgeCanon.GetGoldenAgeProgressForCiv(civilization);
                civData.PreviousGoldenAges = GoldenAgeCanon.GetPreviousGoldenAgesForCiv(civilization);

                mapData.Civilizations.Add(civData);
            }

            mapData.CivDiscoveryPairs = CivDiscoveryCanon.GetDiscoveryPairs().Select(
                pair => new Tuple <string, string>(pair.Item1.Template.Name, pair.Item2.Template.Name)
                ).ToList();
        }