Skip to content

Commit

Permalink
Render: Fix Ri defn for 'more world colors' option, improve error rep…
Browse files Browse the repository at this point in the history
…orts
  • Loading branch information
inexorabletash committed Sep 15, 2018
1 parent abb2a4c commit 2825929
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 96 deletions.
2 changes: 1 addition & 1 deletion res/Sectors/Faraway/Foreven-ImperiumStaple.txt
Expand Up @@ -119,7 +119,7 @@ Hex Name UWP Remarks {Ix} (Ex) [Cx] N B Z PBG W A
2737 Trively E200677-7 Ni - - - 535 Na K1 II
2739 Wilthol B100200-A Lo Ni - - - 513 Na K5 V D
2831 Span B692995-C Hi In - S - 325 Na F1 V D
2837 Zymn C875657-8 Ni Ag DroyW - - R 301 Naxx D D
2837 Zymn C875657-8 Ni Ag DroyW - - R 301 NaXX D D
2838 Whinot D537899-5 - - - 604 Na F2 V D
2839 Olfaniston B206443-B Ni - M - 103 Na M6 V
2931 Iton E8C8463-6 Ni - - - 424 Na G2 V
Expand Down
175 changes: 95 additions & 80 deletions server/World.cs
Expand Up @@ -126,26 +126,20 @@ internal int PopulationMantissa
internal double Population => Math.Pow(10, PopulationExponent) * PopulationMantissa;
internal bool WaterPresent => (Hydrographics > 0) && (Atmosphere.InRange(2, 9) || Atmosphere.InRange(0xD, 0xF));

// Only define what is needed.
// TODO: Unify with validation checks.

// Planetary
internal bool IsAs => Size == 0;
internal bool IsDe => Atmosphere.InRange(2, 10) && Hydrographics == 0;
internal bool IsFl => Atmosphere >= 10 && Hydrographics > 0;
internal bool IsIc => Atmosphere.InList(0, 1) && Hydrographics > 0;
internal bool IsVa => Atmosphere == 0;
internal bool IsWa => Hydrographics == 10;

// Population
internal bool IsBa => PopulationExponent == 0;
internal bool IsLo => PopulationExponent < 4;
internal bool IsNi => PopulationExponent.InRange(1, 6);
internal bool IsHi => PopulationExponent >= 9;

// Economic
internal bool IsAg => Atmosphere.InRange(4, 9) && Hydrographics.InRange(4, 8) && PopulationExponent.InRange(5, 7);
internal bool IsNa => Atmosphere.InRange(0, 3) && Hydrographics.InRange(0, 3) && PopulationExponent.InRange(6, 10);
internal bool IsIn => Atmosphere.InList(0, 1, 2, 4, 7, 9) && PopulationExponent.InList(9, 10);
internal bool IsPo => Atmosphere.InList(2, 3, 4, 5) && Hydrographics.InList(0, 1, 2, 3) && PopulationExponent > 0;
internal bool IsRi => Atmosphere.InList(6, 7, 8) && PopulationExponent.InList(6, 7, 8) && Government.InList(4, 5, 6, 7, 8, 9);
internal bool IsIn => Atmosphere.InList(0, 1, 2, 4, 7, 9, 10, 11, 12) && PopulationExponent >= 9;
internal bool IsRi => Atmosphere.InList(6, 8) && PopulationExponent.InList(6, 7, 8);

internal bool IsCp => HasCode("Cp");
internal bool IsCs => HasCode("Cs");
Expand Down Expand Up @@ -288,6 +282,7 @@ internal void Validate(ErrorLogger errors, int lineNumber, string line)
// TODO: Validate partial UWPs
if (UWP.Contains('?') || UWP == "XXXXXXX-X") return;

#region Helpers
Action<string> Error = (string message) => { errors.Warning(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); };
Expand All @@ -309,7 +304,9 @@ internal void Validate(ErrorLogger errors, int lineNumber, string line)
ErrorUnless(!HasCode(code), $"Extraneous code: {code}");
return calc;
};
#endregion

#region UWP
// UWP
ErrorIf(Atmosphere > 15,
$"UWP: Atm={Atmosphere} out of range; should be: 0...F");
Expand All @@ -331,7 +328,9 @@ internal void Validate(ErrorLogger errors, int lineNumber, string line)
ErrorUnless(TechLevel.InRange(tlmod + 1, tlmod + 6) ||
(PopulationExponent == 0 && TechLevel == 0),
$"UWP: TL={TechLevel} out of range; should be: mods(={tlmod}) + 1D");
#endregion

#region Codes
// Planetary
bool As = CC("As", Check(Size, "0") /*&& Check(Atmosphere, "0") && Check(Hydrographics, "0")*/);
bool De = CC("De", Check(Atmosphere, "23456789") && Check(Hydrographics, "0"));
Expand Down Expand Up @@ -362,94 +361,110 @@ internal void Validate(ErrorLogger errors, int lineNumber, string line)
bool Pr = CC("Pr", Check(Atmosphere, "68") && Check(PopulationExponent, "59"));
bool Ri = CC("Ri", Check(Atmosphere, "68") && Check(PopulationExponent, "678"));

ErrorUnless(As == IsAs, "Internal code failure: As/IsAs definitions");
ErrorUnless(Va == IsVa, "Internal code failure: Va/IsVa definitions");
ErrorUnless(Ag == IsAg, "Internal code failure: Ag/IsAg definitions");
ErrorUnless(In == IsIn, "Internal code failure: In/IsIn definitions");
ErrorUnless(Ri == IsRi, "Internal code failure: Ri/IsRi definitions");
#endregion

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

if ("AB".Contains(Starport)) ++imp;
if ("DEX".Contains(Starport)) --imp;
if (TechLevel >= 10) ++imp;
if (TechLevel >= 16) ++imp;
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" || Bases == "KV") ++imp;

ErrorUnless(Int32.Parse(ix) == imp,
$"{{Ix}} Importance={ix} incorrect; should be: {imp}");
if ("AB".Contains(Starport)) ++imp;
if ("DEX".Contains(Starport)) --imp;
if (TechLevel >= 10) ++imp;
if (TechLevel >= 16) ++imp;
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" || Bases == "KV") ++imp;

ErrorUnless(Int32.Parse(ix) == imp,
$"{{Ix}} Importance={ix} incorrect; should be: {imp}");
}
}

// (Ex)
if (!string.IsNullOrWhiteSpace(Economic))
{
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(resources.InRange(2, 12),
$"(Ex) Resources={resources} out of range; should be: 2D if TL(={TechLevel})<8");
else
ErrorUnless(resources.InRange(2 + GasGiants + Belts, 12 + GasGiants + Belts),
$"(Ex) Resources={resources} out of range; should be: 2D + GG(={GasGiants}) + Belts(={Belts}) if TL(={TechLevel})=8+");

ErrorUnless(labor == Math.Max(0, PopulationExponent - 1),
$"(Ex) Labor={labor} incorrect; should be: Pop(={PopulationExponent}) - 1");

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

ErrorUnless(efficiency.InRange(-5, 5),
$"(Ex) Efficiency={efficiency} out of range; should be: Flux");
if (ex != "")
{
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(resources.InRange(2, 12),
$"(Ex) Resources={resources} out of range; should be: 2D if TL(={TechLevel})<8");
else
ErrorUnless(resources.InRange(2 + GasGiants + Belts, 12 + GasGiants + Belts),
$"(Ex) Resources={resources} out of range; should be: 2D + GG(={GasGiants}) + Belts(={Belts}) if TL(={TechLevel})=8+");

ErrorUnless(labor == Math.Max(0, PopulationExponent - 1),
$"(Ex) Labor={labor} incorrect; should be: Pop(={PopulationExponent}) - 1");

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

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

// [Cx]
if (!string.IsNullOrWhiteSpace(Cultural))
{
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 (cx != "")
{
ErrorUnless(homogeneity == 0,
$"[Cx] Homogeneity={homogeneity} incorrect; should be: 0 if Pop=0");
ErrorUnless(acceptance == 0,
$"[Cx] Acceptance={acceptance} incorrect; should be: 0 if Pop=0");
ErrorUnless(strangeness == 0,
$"[Cx] Strangeness={strangeness} incorrect; should be: 0 if Pop=0");
ErrorUnless(symbols == 0,
$"[Cx] Symbols={symbols} incorrect; should be: 0 if Pop=0");
}
else
{
ErrorUnless(homogeneity.InRange(Math.Max(1, PopulationExponent - 5), Math.Max(1, PopulationExponent + 5)),
$"[Cx] Homogeneity={homogeneity} out of range; should be: Pop(={PopulationExponent}) + Flux");
ErrorUnless(acceptance == Math.Max(1, PopulationExponent + imp),
$"[Cx] Acceptance={acceptance} incorrect; should be: Pop(={PopulationExponent}) + Imp(={imp})");
ErrorUnless(strangeness.InRange(Math.Max(1, 5 - 5), Math.Max(1, 5 + 5)),
$"[Cx] Strangeness={strangeness} out of range; should be: Flux + 5");
ErrorUnless(symbols.InRange(Math.Max(1, TechLevel - 5), Math.Max(1, TechLevel + 5)),
$"[Cx] Symbols={symbols} out of range; should be: TL(={TechLevel}) + Flux");
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)
{
ErrorUnless(homogeneity == 0,
$"[Cx] Homogeneity={homogeneity} incorrect; should be: 0 if Pop=0");
ErrorUnless(acceptance == 0,
$"[Cx] Acceptance={acceptance} incorrect; should be: 0 if Pop=0");
ErrorUnless(strangeness == 0,
$"[Cx] Strangeness={strangeness} incorrect; should be: 0 if Pop=0");
ErrorUnless(symbols == 0,
$"[Cx] Symbols={symbols} incorrect; should be: 0 if Pop=0");
}
else
{
ErrorUnless(homogeneity.InRange(Math.Max(1, PopulationExponent - 5), Math.Max(1, PopulationExponent + 5)),
$"[Cx] Homogeneity={homogeneity} out of range; should be: Pop(={PopulationExponent}) + Flux");
ErrorUnless(acceptance == Math.Max(1, PopulationExponent + imp),
$"[Cx] Acceptance={acceptance} incorrect; should be: Pop(={PopulationExponent}) + Imp(={imp})");
ErrorUnless(strangeness.InRange(Math.Max(1, 5 - 5), Math.Max(1, 5 + 5)),
$"[Cx] Strangeness={strangeness} out of range; should be: Flux + 5");
ErrorUnless(symbols.InRange(Math.Max(1, TechLevel - 5), Math.Max(1, TechLevel + 5)),
$"[Cx] Symbols={symbols} out of range; should be: TL(={TechLevel}) + Flux");
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions server/admin/AdminHandler.cs
Expand Up @@ -57,6 +57,16 @@ protected static string GetStringOption(HttpContext context, string name)
return queryDefaults[name].ToString();
return null;
}

protected static bool GetBoolOption(HttpContext context, string name, bool defaultValue = false)
{
if (context.Request[name] != null)
return context.Request[name] == "1";
var queryDefaults = Defaults(context);
if (queryDefaults != null && queryDefaults.ContainsKey(name))
return queryDefaults[name].ToString() == "1";
return defaultValue;
}
}

internal class AdminHandler : AdminHandlerBase
Expand Down
8 changes: 5 additions & 3 deletions server/admin/ErrorsHandler.cs
Expand Up @@ -18,6 +18,7 @@ protected override void Process(System.Web.HttpContext context, ResourceManager
string type = GetStringOption(context, "type");
string milieu = GetStringOption(context, "milieu");
string tag = GetStringOption(context, "tag");
ErrorLogger.Severity severity = GetBoolOption(context, "warnings", true) ? 0 : ErrorLogger.Severity.Error;

// NOTE: This (re)initializes a static data structure used for
// resolving names into sector locations, so needs to be run
Expand All @@ -37,7 +38,7 @@ protected override void Process(System.Web.HttpContext context, ResourceManager

foreach (var sector in sectorQuery)
{
context.Response.Output.WriteLine(sector.Names[0].Text);
context.Response.Output.WriteLine($"{sector.Names[0].Text} - {sector.Milieu}");
#if DEBUG
int error_count = 0;
int warning_count = 0;
Expand All @@ -51,7 +52,7 @@ protected override void Process(System.Web.HttpContext context, ResourceManager
context.Response.Output.WriteLine($"{worlds.Count()} world(s) - population: {pop / 1e9:#,###.##} billion");
else
context.Response.Output.WriteLine($"{worlds.Count()} world(s) - population: N/A");
worlds.ErrorList.Report(context.Response.Output);
worlds.ErrorList.Report(context.Response.Output, severity);
error_count += worlds.ErrorList.CountOf(ErrorLogger.Severity.Error);
warning_count += worlds.ErrorList.CountOf(ErrorLogger.Severity.Warning);
}
Expand Down Expand Up @@ -86,7 +87,8 @@ protected override void Process(System.Web.HttpContext context, ResourceManager
}
else if (distance > 4)
{
context.Response.Output.WriteLine($"Warning: Route length {distance}: {route.ToString()}");
if (severity <= ErrorLogger.Severity.Warning)
context.Response.Output.WriteLine($"Warning: Route length {distance}: {route.ToString()}");
++warning_count;
}
/*
Expand Down
21 changes: 9 additions & 12 deletions server/utilities/Util.cs
Expand Up @@ -63,12 +63,7 @@ internal static class ExtensionMethods
}

public static bool InRange<T>(this IComparable<T> item, T a, T b) => item.CompareTo(a) >= 0 && item.CompareTo(b) <= 0;

public static bool InList<T>(this T item, T o1, T o2) => item.Equals(o1) || item.Equals(o2);
public static bool InList<T>(this T item, T o1, T o2, T o3) => item.Equals(o1) || item.Equals(o2) || item.Equals(o3);
public static bool InList<T>(this T item, T o1, T o2, T o3, T o4) => item.Equals(o1) || item.Equals(o2) || item.Equals(o3) || item.Equals(o4);
public static bool InList<T>(this T item, T o1, T o2, T o3, T o4, T o5) => item.Equals(o1) || item.Equals(o2) || item.Equals(o3) || item.Equals(o4) || item.Equals(o5);
public static bool InList<T>(this T item, T o1, T o2, T o3, T o4, T o5, T o6) => item.Equals(o1) || item.Equals(o2) || item.Equals(o3) || item.Equals(o4) || item.Equals(o5) || item.Equals(o6);
public static bool InList<T>(this T item, params T[] options) => options.Contains(item);
#endregion

#region String Methods
Expand Down Expand Up @@ -327,11 +322,12 @@ public void Clear()

internal class ErrorLogger
{
// In increasing order, for filtering
public enum Severity {
Fatal,
Error,
Hint,
Warning,
Hint
Error,
Fatal
}

public struct Record
Expand Down Expand Up @@ -381,19 +377,20 @@ public void Log(Severity sev, string message, int lineNumber, string line)

public int CountOf(Severity sev) => log.Where(r => r.severity == sev).Count();

public void Report(TextWriter writer)
public void Report(TextWriter writer, Severity minSeverity)
{
foreach (var record in log)
{
writer.WriteLine($"{record.severity.ToString()}: {record.message}");
if (record.severity >= minSeverity)
writer.WriteLine($"{record.severity.ToString()}: {record.message}");
}
}

public override string ToString()
{
using (StringWriter writer = new StringWriter())
{
Report(writer);
Report(writer, Severity.Hint);
writer.WriteLine($"{CountOf(Severity.Error)} errors, {CountOf(Severity.Warning)} warnings.");
return writer.ToString();
}
Expand Down

0 comments on commit 2825929

Please sign in to comment.