Пример #1
0
        internal void Validate(ErrorLogger errors, int lineNumber, string line)
        {
            if (UWP == "???????-?")
            {
                return;
            }

            Action <string>       Error   = (string message) => { errors.Error(message, lineNumber, line); };
            Action <bool, string> ErrorIf = (bool test, string message) => { if (test)
                                                                             {
                                                                                 Error(message);
                                                                             }
            };
            Action <bool, string> ErrorUnless = (bool test, string message) => { if (!test)
                                                                                 {
                                                                                     Error(message);
                                                                                 }
            };
            Func <int, string, bool> Check = (int value, string hex) =>
            {
                for (int i = 0; i < hex.Length; ++i)
                {
                    if (value == SecondSurvey.FromHex(hex[i]))
                    {
                        return(true);
                    }
                }
                return(false);
            };

            Func <string, bool, bool> CC = (string code, bool calc) =>
            {
                if (calc)
                {
                    ErrorUnless(HasCode(code), $"Missing code: {code}");
                }
                else
                {
                    ErrorUnless(!HasCode(code), $"Extraneous code: {code}");
                }
                return(calc);
            };

#if VALIDATE_UWP
            // UWP
            ErrorIf(Atmosphere > 15, $"UWP: Atm>F: {Atmosphere}");
            ErrorIf(Hydrographics > 10, $"UWP: Hyd>A: {Hydrographics}");
            ErrorIf(PopulationExponent > 15, $"UWP: Pop>F: {PopulationExponent}");
            ErrorUnless(Util.InRange(Government, PopulationExponent - 5, Math.Max(15, PopulationExponent + 5)),
                        $"UWP: Gov={Government} out of range (Pop={PopulationExponent} + Flux)");
            ErrorUnless(Util.InRange(Law, Government - 5, Math.Max(18, Government + 5)),
                        $"UWP: Law={Law} out of range (Gov={Government} + Flux)");
            int tlmod =
                (Starport == 'A' ? 6 : 0) + (Starport == 'B' ? 4 : 0) + (Starport == 'C' ? 2 : 0) + (Starport == 'X' ? -4 : 0) +
                (Size == 0 || Size == 1 ? 2 : 0) + (Size == 2 || Size == 3 || Size == 4 ? 1 : 0) +
                (Atmosphere <= 3 ? 1 : 0) + (Atmosphere >= 10 ? 1 : 0) +
                (Hydrographics == 9 ? 1 : 0) + (Hydrographics == 10 ? 2 : 0) +
                (Util.InRange(PopulationExponent, 1, 5) ? 1 : 0) + (PopulationExponent == 9 ? 2 : 0) + (PopulationExponent >= 10 ? 4 : 0) +
                (Government == 0 || Government == 5 ? 1 : 0) + (Government == 13 ? -2 : 0);
            ErrorUnless(Util.InRange(TechLevel, tlmod + 1, tlmod + 6),
                        $"UWP: TL={TechLevel} out of range (mods={tlmod} + 1D)");
#endif

            // Planetary
            bool As = CC("As", Check(Size, "0") /*&& Check(Atmosphere, "0") && Check(Hydrographics, "0")*/);
            bool De = CC("De", Check(Atmosphere, "23456789") && Check(Hydrographics, "0"));
            bool Fl = CC("Fl", Check(Atmosphere, "ABC") && Check(Hydrographics, "123456789A"));
            bool Ga = CC("Ga", Check(Size, "678") && Check(Atmosphere, "568") && Check(Hydrographics, "567"));
            bool He = CC("He", Check(Size, "3456789A" /* + "BC" */) && Check(Atmosphere, "2479ABC") && Check(Hydrographics, "012")); // TODO: Add BC to T5SS spreadsheet calcs
            bool Ic = CC("Ic", Check(Atmosphere, "01") && Check(Hydrographics, "123456789A"));
            bool Oc = CC("Oc", Check(Size, "ABC") && Check(Atmosphere, "3456789") && Check(Hydrographics, "A"));
            bool Va = CC("Va", Check(Atmosphere, "0"));
            bool Wa = CC("Wa", Check(Size, "3456789") && Check(Atmosphere, "3456789") && Check(Hydrographics, "A"));

            // Population
            bool Di = CC("Di", PopulationExponent == 0 /*&& Government == 0 && Law == 0*/ && TechLevel > 0);
            bool Ba = CC("Ba", PopulationExponent == 0 /*&& Government == 0 && Law == 0*/ && TechLevel == 0);
            bool Lo = CC("Lo", Check(PopulationExponent, "123"));
            bool Ni = CC("Ni", Check(PopulationExponent, "456"));
            bool Ph = CC("Ph", Check(PopulationExponent, "8"));
            bool Hi = CC("Hi", Check(PopulationExponent, "9ABCDEF"));

            // Economic
            bool Pa = CC("Pa", Check(Atmosphere, "456789") && Check(Hydrographics, "45678") && Check(PopulationExponent, "48"));
            bool Ag = CC("Ag", Check(Atmosphere, "456789") && Check(Hydrographics, "45678") && Check(PopulationExponent, "567"));
            bool Na = CC("Na", Check(Atmosphere, "0123") && Check(Hydrographics, "0123") && Check(PopulationExponent, "6789ABCDEF"));
            bool Pi = CC("Pi", Check(Atmosphere, "012479") && Check(PopulationExponent, "78"));
            bool In = CC("In", Check(Atmosphere, "012479ABC") && Check(PopulationExponent, "9ABCDEF"));
            bool Po = CC("Po", Check(Atmosphere, "2345") && Check(Hydrographics, "0123"));
            bool Pr = CC("Pr", Check(Atmosphere, "68") && Check(PopulationExponent, "59"));
            bool Ri = CC("Ri", Check(Atmosphere, "68") && Check(PopulationExponent, "678"));

            // {Ix}
            int imp = 0;
            {
                string ix = Importance.Replace('{', ' ').Replace('}', ' ').Trim();

                if ("AB".Contains(Starport))
                {
                    ++imp;
                }
                if ("DEX".Contains(Starport))
                {
                    --imp;
                }
                if (TechLevel >= 10)
                {
                    ++imp;
                }
                //if (TechLevel >= 16) ++imp; // TODO: Add to T5SS spreadsheet calcs
                if (TechLevel <= 8)
                {
                    --imp;
                }
                if (PopulationExponent <= 6)
                {
                    --imp;
                }
                if (PopulationExponent >= 9)
                {
                    ++imp;
                }
                if (Ag)
                {
                    ++imp;
                }
                if (Ri)
                {
                    ++imp;
                }
                if (In)
                {
                    ++imp;
                }
                if (Bases == "NS" || Bases == "NW" || Bases == "W" || Bases == "X" || Bases == "D" || Bases == "RT" || Bases == "CK" || Bases == "KM")
                {
                    ++imp;
                }

                ErrorUnless(Int32.Parse(ix) == imp,
                            $"{{Ix}}={Importance} does not match calculated Importance={imp}");
            }

            // (Ex)
            {
                string ex             = Economic.Replace('(', ' ').Replace(')', ' ').Trim();
                int    resources      = SecondSurvey.FromHex(ex[0]);
                int    labor          = SecondSurvey.FromHex(ex[1]);
                int    infrastructure = SecondSurvey.FromHex(ex[2]);
                int    efficiency     = Int32.Parse(ex.Substring(3));

                if (TechLevel < 8)
                {
                    ErrorUnless(Util.InRange(resources, 2, 12),
                                $"(Ex) Resources={resources} out of range for TL<8={TechLevel} (2D)");
                }
                else
                {
                    ErrorUnless(Util.InRange(resources, 2 + GasGiants + Belts, 12 + GasGiants + Belts),
                                $"(Ex) Resources={resources} out of range for TL8+={TechLevel} (2D + GG={GasGiants} + Belts={Belts})");
                }

                ErrorUnless(labor == Math.Max(0, PopulationExponent - 1),
                            $"(Ex) Labor={labor} does not match Pop={PopulationExponent} - 1");

                if (Ba)
                {
                    ErrorUnless(infrastructure == 0, $"(Ex) Infrastructure={infrastructure} should be 0 if Ba");
                }
                else if (Lo)
                {
                    ErrorUnless(infrastructure == 1, $"(Ex) Infrastructure={infrastructure} should be 1 if Lo");
                }
                else if (Ni)
                {
                    ErrorUnless(Util.InRange(infrastructure, Math.Max(0, imp + 1), Math.Max(0, imp + 6)),
                                $"(Ex) Infrastructure={infrastructure} out of range for Ni (Imp={imp} + 1D)");
                }
                else
                {
                    ErrorUnless(Util.InRange(infrastructure, Math.Max(0, imp + 2), Math.Max(0, imp + 12)),
                                $"(Ex) Infrastructure={infrastructure} out of range (Imp={imp} + 2D)");
                }

                ErrorUnless(Util.InRange(efficiency, -5, 5),
                            $"(Ex) Efficiency={efficiency} out of range (Flux)");
            }

            // [Cx]
            {
                string cx          = Cultural.Replace('[', ' ').Replace(']', ' ').Trim();
                int    homogeneity = SecondSurvey.FromHex(cx[0]);
                int    acceptance  = SecondSurvey.FromHex(cx[1]);
                int    strangeness = SecondSurvey.FromHex(cx[2]);
                int    symbols     = SecondSurvey.FromHex(cx[3]);

                if (PopulationExponent == 0)
                {
                    if (homogeneity != 0)
                    {
                        Error($"[Cx] Homogeneity={homogeneity} - expected 0 for Pop 0");
                    }
                    if (acceptance != 0)
                    {
                        Error($"[Cx] Acceptance={acceptance} - expected 0 for Pop 0");
                    }
                    if (strangeness != 0)
                    {
                        Error($"[Cx] Strangeness={strangeness} - expected 0 for Pop 0");
                    }
                    if (symbols != 0)
                    {
                        Error($"[Cx] Symbols={symbols} - expected 0 for Pop 0");
                    }
                }
                else
                {
                    ErrorUnless(Util.InRange(homogeneity, Math.Max(1, PopulationExponent - 5), Math.Max(1, PopulationExponent + 5)),
                                $"[Cx] Homogeneity={homogeneity} out of range (Pop={PopulationExponent} + Flux)");
                    ErrorUnless(acceptance == Math.Max(1, PopulationExponent + imp),
                                $"[Cx] Acceptance={acceptance} not equal Pop={PopulationExponent} + Imp={imp}");
                    ErrorUnless(Util.InRange(strangeness, Math.Max(1, 5 - 5), Math.Max(1, 5 + 5)),
                                $"[Cx] Strangeness={strangeness} out of range (Flux + 5)");
                    ErrorUnless(Util.InRange(symbols, Math.Max(1, TechLevel - 5), Math.Max(1, TechLevel + 5)),
                                $"[Cx] Symbols={symbols} out of range (TL={TechLevel} + Flux)");
                }
            }

            // Ownership
            if (Government == 6 && !(HasCodePrefix("O:") || HasCodePrefix("Mr") || HasCode("Re") || HasCode("Px")))
            {
                errors.Warning("Gov 6 missing O:/Mr/Re/Px", lineNumber, line);
            }
        }
Пример #2
0
        public WorldCollection()
        {
#if DEBUG
            errors = new ErrorLogger();
#endif
        }