diff --git a/MultiversalDiplomacy/Model/Map.cs b/MultiversalDiplomacy/Model/Map.cs index 823176d..ec96762 100644 --- a/MultiversalDiplomacy/Model/Map.cs +++ b/MultiversalDiplomacy/Model/Map.cs @@ -22,11 +22,11 @@ public class Map /// /// The game powers. /// - public IReadOnlyCollection Powers => _Powers.AsReadOnly(); + public IReadOnlyCollection Powers => _Powers.AsReadOnly(); - private List _Powers { get; } + private List _Powers { get; } - private Map(MapType type, IEnumerable provinces, IEnumerable powers) + private Map(MapType type, IEnumerable provinces, IEnumerable powers) { Type = type; _Provinces = provinces.ToList(); @@ -84,10 +84,10 @@ public class Map : GetLocation(provinceName, l => l.Name == coastName || l.Abbreviation == coastName); /// - /// Get a power by name. Throws if there is not exactly one such power. + /// Get a power by full or partial name. Throws if there is not exactly one such power. /// - public Power GetPower(string powerName) - => Powers.SingleOrDefault(p => p!.Name == powerName || p.Name.StartsWith(powerName), null) + public string GetPower(string powerName) + => Powers.SingleOrDefault(p => p!.EqualsAnyCase(powerName) || p!.StartsWithAnyCase(powerName), null) ?? throw new KeyNotFoundException($"Power {powerName} not found (powers: {string.Join(", ", Powers)})"); public static Map FromType(MapType type) @@ -110,10 +110,7 @@ public class Map center.AddBorder(lef.Locations.First()); center.AddBorder(rig.Locations.First()); - Power a = new("Alpha"); - Power b = new("Beta"); - - return new(MapType.Test, [lef, cen, rig], [a, b]); + return new(MapType.Test, [lef, cen, rig], ["Alpha", "Beta"]); }); public static Map Classical => _Classical.Value; @@ -557,15 +554,15 @@ public class Map Water("WES").AddBorder(Coast("SPA", "sc")); #endregion - List powers = + List powers = [ - new("Austria"), - new("England"), - new("France"), - new("Germany"), - new("Italy"), - new("Russia"), - new("Turkey"), + "Austria", + "England", + "France", + "Germany", + "Italy", + "Russia", + "Turkey", ]; return new(MapType.Classical, provinces, powers); diff --git a/MultiversalDiplomacy/Model/Power.cs b/MultiversalDiplomacy/Model/Power.cs deleted file mode 100644 index ca49120..0000000 --- a/MultiversalDiplomacy/Model/Power.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace MultiversalDiplomacy.Model; - -/// -/// One of the rival nations vying for control of the map. -/// -public class Power -{ - /// - /// The power's name. - /// - public string Name { get; } - - public Power(string name) - { - this.Name = name; - } - - public override string ToString() - { - return this.Name; - } -} diff --git a/MultiversalDiplomacy/Model/World.cs b/MultiversalDiplomacy/Model/World.cs index ff1ecd0..227aca6 100644 --- a/MultiversalDiplomacy/Model/World.cs +++ b/MultiversalDiplomacy/Model/World.cs @@ -37,7 +37,7 @@ public class World /// The game powers. /// [JsonIgnore] - public IReadOnlyCollection Powers => this.Map.Powers; + public IReadOnlyCollection Powers => this.Map.Powers; /// /// Lookup for seasons by designation. @@ -190,7 +190,7 @@ public class World IEnumerable units = unitSpecs.Select(spec => { string[] splits = spec.Split(' ', 4); - Power power = Map.GetPower(splits[0]); + string power = Map.GetPower(splits[0]); UnitType type = splits[1] switch { "A" => UnitType.Army, @@ -202,7 +202,7 @@ public class World : splits.Length == 3 ? Map.GetWater(splits[2]) : Map.GetWater(splits[2], splits[3]); - Unit unit = Unit.Build(location.Key, this.RootSeason, power.Name, type); + Unit unit = Unit.Build(location.Key, this.RootSeason, power, type); return unit; }); return this.Update(units: units); diff --git a/MultiversalDiplomacy/StringExtensions.cs b/MultiversalDiplomacy/StringExtensions.cs new file mode 100644 index 0000000..045d90f --- /dev/null +++ b/MultiversalDiplomacy/StringExtensions.cs @@ -0,0 +1,10 @@ +namespace System; + +public static class StringExtensions +{ + public static bool EqualsAnyCase(this string str, string? other) + => str.Equals(other, StringComparison.InvariantCultureIgnoreCase); + + public static bool StartsWithAnyCase(this string str, string other) + => str.StartsWith(other, StringComparison.InvariantCultureIgnoreCase); +} diff --git a/MultiversalDiplomacyTests/TestCaseBuilder.cs b/MultiversalDiplomacyTests/TestCaseBuilder.cs index 2eb66bd..32aa991 100644 --- a/MultiversalDiplomacyTests/TestCaseBuilder.cs +++ b/MultiversalDiplomacyTests/TestCaseBuilder.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using MultiversalDiplomacy.Adjudicate; using MultiversalDiplomacy.Model; using MultiversalDiplomacy.Orders; +using NUnit.Framework; namespace MultiversalDiplomacyTests; @@ -254,14 +255,14 @@ public class TestCaseBuilder /// of this type. /// private Unit GetOrBuildUnit( - Power power, + string power, Location location, Season season, UnitType type) { foreach (Unit unit in this.World.Units) { - if (unit.Power == power.Name + if (unit.Power == power && World.Map.GetLocation(unit).Province == location.Province && unit.Season == season) { @@ -270,7 +271,7 @@ public class TestCaseBuilder } // Not found - Unit newUnit = Unit.Build(location.Key, season, power.Name, type); + Unit newUnit = Unit.Build(location.Key, season, power, type); this.World = this.World.Update(units: this.World.Units.Append(newUnit)); return newUnit; } @@ -344,13 +345,15 @@ public class TestCaseBuilder { public TestCaseBuilder Builder; public SeasonContext SeasonContext; - public Power Power; + public string Power; - public PowerContext(SeasonContext seasonContext, Power Power) + public PowerContext(SeasonContext seasonContext, string power) { + Assert.That(power, Is.AnyOf([.. seasonContext.Builder.World.Map.Powers]), "Invalid power"); + this.Builder = seasonContext.Builder; this.SeasonContext = seasonContext; - this.Power = Power; + this.Power = power; } public ISeasonContext this[(string timeline, int turn) seasonCoord] @@ -361,7 +364,7 @@ public class TestCaseBuilder public IUnitContext Army(string provinceName, string? powerName = null) { - Power power = powerName == null + string power = powerName == null ? this.Power : this.Builder.World.Map.GetPower(powerName); Location location = this.Builder.World.Map.GetLand(provinceName); @@ -372,7 +375,7 @@ public class TestCaseBuilder public IUnitContext Fleet(string provinceName, string? coast = null, string? powerName = null) { - Power power = powerName == null + string power = powerName == null ? this.Power : this.Builder.World.Map.GetPower(powerName); Location location = this.Builder.World.Map.GetWater(provinceName, coast); @@ -402,7 +405,7 @@ public class TestCaseBuilder public IOrderDefinedContext Holds() { - HoldOrder order = new HoldOrder(this.PowerContext.Power.Name, this.Unit); + HoldOrder order = new HoldOrder(this.PowerContext.Power, this.Unit); this.Builder.OrderList.Add(order); return new OrderDefinedContext(this, order); } @@ -417,7 +420,7 @@ public class TestCaseBuilder : this.Builder.World.Map.GetWater(provinceName, coast); Season destSeason = season ?? this.SeasonContext.Season; MoveOrder moveOrder = new MoveOrder( - this.PowerContext.Power.Name, + this.PowerContext.Power, this.Unit, destSeason.Key, destination); @@ -449,7 +452,7 @@ public class TestCaseBuilder public IConvoyDestinationContext Army(string provinceName, string? powerName = null) { - Power power = powerName == null + string power = powerName == null ? this.PowerContext.Power : this.Builder.World.Map.GetPower(powerName); Location location = this.Builder.World.Map.GetLand(provinceName); @@ -463,7 +466,7 @@ public class TestCaseBuilder string? coast = null, string? powerName = null) { - Power power = powerName == null + string power = powerName == null ? this.PowerContext.Power : this.Builder.World.Map.GetPower(powerName); Location location = this.Builder.World.Map.GetWater(provinceName, coast); @@ -494,7 +497,7 @@ public class TestCaseBuilder { Location location = this.Builder.World.Map.GetLand(provinceName); ConvoyOrder order = new ConvoyOrder( - this.PowerContext.Power.Name, + this.PowerContext.Power, this.UnitContext.Unit, this.Target, this.SeasonContext.Season, @@ -524,7 +527,7 @@ public class TestCaseBuilder Season? season = null, string? powerName = null) { - Power power = powerName == null + string power = powerName == null ? this.PowerContext.Power : this.Builder.World.Map.GetPower(powerName); Location location = this.Builder.World.Map.GetLand(provinceName); @@ -539,7 +542,7 @@ public class TestCaseBuilder string? coast = null, string? powerName = null) { - Power power = powerName == null + string power = powerName == null ? this.PowerContext.Power : this.Builder.World.Map.GetPower(powerName); Location location = this.Builder.World.Map.GetWater(provinceName, coast); @@ -569,7 +572,7 @@ public class TestCaseBuilder public IOrderDefinedContext Hold() { SupportHoldOrder order = new SupportHoldOrder( - this.PowerContext.Power.Name, + this.PowerContext.Power, this.UnitContext.Unit, this.Target); this.Builder.OrderList.Add(order); @@ -586,7 +589,7 @@ public class TestCaseBuilder : this.Builder.World.Map.GetWater(provinceName, coast); Season targetDestSeason = season ?? this.Target.Season; SupportMoveOrder order = new SupportMoveOrder( - this.PowerContext.Power.Name, + this.PowerContext.Power, this.UnitContext.Unit, this.Target, targetDestSeason, diff --git a/MultiversalDiplomacyTests/UnitTests.cs b/MultiversalDiplomacyTests/UnitTests.cs index bd5e2c3..41eefa0 100644 --- a/MultiversalDiplomacyTests/UnitTests.cs +++ b/MultiversalDiplomacyTests/UnitTests.cs @@ -13,9 +13,8 @@ public class UnitTests Location Mun = world.Map.GetLand("Mun"), Boh = world.Map.GetLand("Boh"), Tyr = world.Map.GetLand("Tyr"); - Power pw1 = world.Map.GetPower("Austria"); Season a0 = world.RootSeason; - Unit u1 = Unit.Build(Mun.Key, a0, pw1.Name, UnitType.Army); + Unit u1 = Unit.Build(Mun.Key, a0, "Austria", UnitType.Army); world = world.ContinueOrFork(a0, out Season a1); Unit u2 = u1.Next(Boh.Key, a1);