Compare commits
No commits in common. "7749d8df4e0e5189aa36ad808f9ed395830cc67d" and "b2ff8896b2ff16071afe724f19d0b32a5ddd7964" have entirely different histories.
7749d8df4e
...
b2ff8896b2
|
@ -91,33 +91,19 @@ public class MovementDecisions
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
(Province province, Season season) Point(Unit unit)
|
|
||||||
=> (world.Map.GetLocation(unit.Location).Province, unit.Season);
|
|
||||||
|
|
||||||
// Create a hold strength decision with an associated order for every province with a unit.
|
// Create a hold strength decision with an associated order for every province with a unit.
|
||||||
foreach (UnitOrder order in relevantOrders)
|
foreach (UnitOrder order in relevantOrders)
|
||||||
{
|
{
|
||||||
HoldStrength[Point(order.Unit)] = new(Point(order.Unit), order);
|
HoldStrength[order.Unit.Point] = new(order.Unit.Point, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsIncoming(UnitOrder me, MoveOrder other)
|
|
||||||
=> me != other
|
|
||||||
&& other.Season == me.Unit.Season
|
|
||||||
&& other.Province == world.Map.GetLocation(me.Unit).Province;
|
|
||||||
|
|
||||||
bool AreOpposing(MoveOrder one, MoveOrder two)
|
|
||||||
=> one.Season == two.Unit.Season
|
|
||||||
&& two.Season == one.Unit.Season
|
|
||||||
&& one.Province == world.Map.GetLocation(two.Unit).Province
|
|
||||||
&& two.Province == world.Map.GetLocation(one.Unit).Province;
|
|
||||||
|
|
||||||
// Create all other relevant decisions for each order in the affected timelines.
|
// Create all other relevant decisions for each order in the affected timelines.
|
||||||
foreach (UnitOrder order in relevantOrders)
|
foreach (UnitOrder order in relevantOrders)
|
||||||
{
|
{
|
||||||
// Create a dislodge decision for this unit.
|
// Create a dislodge decision for this unit.
|
||||||
List<MoveOrder> incoming = relevantOrders
|
List<MoveOrder> incoming = relevantOrders
|
||||||
.OfType<MoveOrder>()
|
.OfType<MoveOrder>()
|
||||||
.Where(other => IsIncoming(order, other))
|
.Where(order.IsIncoming)
|
||||||
.ToList();
|
.ToList();
|
||||||
IsDislodged[order.Unit] = new(order, incoming);
|
IsDislodged[order.Unit] = new(order, incoming);
|
||||||
|
|
||||||
|
@ -132,7 +118,7 @@ public class MovementDecisions
|
||||||
// Determine if this move is a head-to-head battle.
|
// Determine if this move is a head-to-head battle.
|
||||||
MoveOrder? opposingMove = relevantOrders
|
MoveOrder? opposingMove = relevantOrders
|
||||||
.OfType<MoveOrder>()
|
.OfType<MoveOrder>()
|
||||||
.FirstOrDefault(other => AreOpposing(move, other!), null);
|
.FirstOrDefault(other => other!.IsOpposing(move), null);
|
||||||
|
|
||||||
// Find competing moves.
|
// Find competing moves.
|
||||||
List<MoveOrder> competing = relevantOrders
|
List<MoveOrder> competing = relevantOrders
|
||||||
|
@ -156,11 +142,11 @@ public class MovementDecisions
|
||||||
GivesSupport[support] = new(support, incoming);
|
GivesSupport[support] = new(support, incoming);
|
||||||
|
|
||||||
// Ensure a hold strength decision exists for the target's province.
|
// Ensure a hold strength decision exists for the target's province.
|
||||||
HoldStrength.Ensure(Point(support.Target), () => new(Point(support.Target)));
|
HoldStrength.Ensure(support.Target.Point, () => new(support.Target.Point));
|
||||||
|
|
||||||
if (support is SupportHoldOrder supportHold)
|
if (support is SupportHoldOrder supportHold)
|
||||||
{
|
{
|
||||||
HoldStrength[Point(support.Target)].Supports.Add(supportHold);
|
HoldStrength[support.Target.Point].Supports.Add(supportHold);
|
||||||
}
|
}
|
||||||
else if (support is SupportMoveOrder supportMove)
|
else if (support is SupportMoveOrder supportMove)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
|
|
||||||
// Trivial check: a unit cannot move to where it already is.
|
// Trivial check: a unit cannot move to where it already is.
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
AdjudicatorHelpers.InvalidateIfNotMatching(
|
||||||
order => !(order.Location.Designation == order.Unit.Location && order.Season == order.Unit.Season),
|
order => !(order.Location == order.Unit.Location && order.Season == order.Unit.Season),
|
||||||
ValidationReason.DestinationMatchesOrigin,
|
ValidationReason.DestinationMatchesOrigin,
|
||||||
ref moveOrders,
|
ref moveOrders,
|
||||||
ref validationResults);
|
ref validationResults);
|
||||||
|
@ -90,7 +90,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
ILookup<bool, MoveOrder> moveOrdersByAdjacency = moveOrders
|
ILookup<bool, MoveOrder> moveOrdersByAdjacency = moveOrders
|
||||||
.ToLookup(order =>
|
.ToLookup(order =>
|
||||||
// Map adjacency
|
// Map adjacency
|
||||||
world.Map.GetLocation(order.Unit).Adjacents.Contains(order.Location)
|
order.Unit.Location.Adjacents.Contains(order.Location)
|
||||||
// Turn adjacency
|
// Turn adjacency
|
||||||
&& Math.Abs(order.Unit.Season.Turn - order.Season.Turn) <= 1
|
&& Math.Abs(order.Unit.Season.Turn - order.Season.Turn) <= 1
|
||||||
// Timeline adjacency
|
// Timeline adjacency
|
||||||
|
@ -138,7 +138,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
// Trivial check: cannot convoy a unit to its own location
|
// Trivial check: cannot convoy a unit to its own location
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
AdjudicatorHelpers.InvalidateIfNotMatching(
|
||||||
order => !(
|
order => !(
|
||||||
order.Location.Designation == order.Target.Location
|
order.Location == order.Target.Location
|
||||||
&& order.Season == order.Target.Season),
|
&& order.Season == order.Target.Season),
|
||||||
ValidationReason.DestinationMatchesOrigin,
|
ValidationReason.DestinationMatchesOrigin,
|
||||||
ref convoyOrders,
|
ref convoyOrders,
|
||||||
|
@ -175,8 +175,8 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
AdjudicatorHelpers.InvalidateIfNotMatching(
|
||||||
order =>
|
order =>
|
||||||
// Map adjacency with respect to province
|
// Map adjacency with respect to province
|
||||||
world.Map.GetLocation(order.Unit).Adjacents.Any(
|
order.Unit.Location.Adjacents.Any(
|
||||||
adjLocation => adjLocation.Province == world.Map.GetLocation(order.Target).Province)
|
adjLocation => adjLocation.Province == order.Target.Province)
|
||||||
// Turn adjacency
|
// Turn adjacency
|
||||||
&& Math.Abs(order.Unit.Season.Turn - order.Target.Season.Turn) <= 1
|
&& Math.Abs(order.Unit.Season.Turn - order.Target.Season.Turn) <= 1
|
||||||
// Timeline adjacency
|
// Timeline adjacency
|
||||||
|
@ -195,7 +195,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
// Support-move orders are invalid if the unit supports a move to any location in its own
|
// Support-move orders are invalid if the unit supports a move to any location in its own
|
||||||
// province.
|
// province.
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
AdjudicatorHelpers.InvalidateIfNotMatching(
|
||||||
order => world.Map.GetLocation(order.Unit).Province != order.Province,
|
order => order.Unit.Province != order.Province,
|
||||||
ValidationReason.NoSupportMoveAgainstSelf,
|
ValidationReason.NoSupportMoveAgainstSelf,
|
||||||
ref supportMoveOrders,
|
ref supportMoveOrders,
|
||||||
ref validationResults);
|
ref validationResults);
|
||||||
|
@ -207,7 +207,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
AdjudicatorHelpers.InvalidateIfNotMatching(
|
||||||
order =>
|
order =>
|
||||||
// Map adjacency with respect to province
|
// Map adjacency with respect to province
|
||||||
world.Map.GetLocation(order.Unit).Adjacents.Any(
|
order.Unit.Location.Adjacents.Any(
|
||||||
adjLocation => adjLocation.Province == order.Province)
|
adjLocation => adjLocation.Province == order.Province)
|
||||||
// Turn adjacency
|
// Turn adjacency
|
||||||
&& Math.Abs(order.Unit.Season.Turn - order.Season.Turn) <= 1
|
&& Math.Abs(order.Unit.Season.Turn - order.Season.Turn) <= 1
|
||||||
|
@ -337,7 +337,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
Season moveSeason = doesMove.Order.Season;
|
Season moveSeason = doesMove.Order.Season;
|
||||||
if (doesMove.Outcome == true && createdFutures.ContainsKey(moveSeason))
|
if (doesMove.Outcome == true && createdFutures.ContainsKey(moveSeason))
|
||||||
{
|
{
|
||||||
Unit next = doesMove.Order.Unit.Next(doesMove.Order.Location.Designation, createdFutures[moveSeason]);
|
Unit next = doesMove.Order.Unit.Next(doesMove.Order.Location, createdFutures[moveSeason]);
|
||||||
logger.Log(3, "Advancing unit to {0}", next);
|
logger.Log(3, "Advancing unit to {0}", next);
|
||||||
createdUnits.Add(next);
|
createdUnits.Add(next);
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
if (isDislodged.Outcome == false)
|
if (isDislodged.Outcome == false)
|
||||||
{
|
{
|
||||||
// Non-dislodged units continue into the future.
|
// Non-dislodged units continue into the future.
|
||||||
Unit next = order.Unit.Next(world.Map.GetLocation(order.Unit).Designation, future);
|
Unit next = order.Unit.Next(order.Unit.Location, future);
|
||||||
logger.Log(3, "Advancing unit to {0}", next);
|
logger.Log(3, "Advancing unit to {0}", next);
|
||||||
createdUnits.Add(next);
|
createdUnits.Add(next);
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
// Create a retreat for each dislodged unit.
|
// Create a retreat for each dislodged unit.
|
||||||
// TODO check valid retreats and disbands
|
// TODO check valid retreats and disbands
|
||||||
logger.Log(3, "Creating retreat for {0}", order.Unit);
|
logger.Log(3, "Creating retreat for {0}", order.Unit);
|
||||||
var validRetreats = world.Map.GetLocation(order.Unit).Adjacents
|
var validRetreats = order.Unit.Location.Adjacents
|
||||||
.Select(loc => (future, loc))
|
.Select(loc => (future, loc))
|
||||||
.ToList();
|
.ToList();
|
||||||
RetreatingUnit retreat = new(order.Unit, validRetreats);
|
RetreatingUnit retreat = new(order.Unit, validRetreats);
|
||||||
|
@ -633,7 +633,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
|
|
||||||
// If the origin and destination are adjacent, then there is a path.
|
// If the origin and destination are adjacent, then there is a path.
|
||||||
if (// Map adjacency
|
if (// Map adjacency
|
||||||
world.Map.GetLocation(decision.Order.Unit).Adjacents.Contains(decision.Order.Location)
|
decision.Order.Unit.Location.Adjacents.Contains(decision.Order.Location)
|
||||||
// Turn adjacency
|
// Turn adjacency
|
||||||
&& Math.Abs(decision.Order.Unit.Season.Turn - decision.Order.Season.Turn) <= 1
|
&& Math.Abs(decision.Order.Unit.Season.Turn - decision.Order.Season.Turn) <= 1
|
||||||
// Timeline adjacency
|
// Timeline adjacency
|
||||||
|
|
|
@ -30,13 +30,13 @@ public static class PathFinder
|
||||||
// also have coasts, and between those coasts there is a path of adjacent sea provinces
|
// also have coasts, and between those coasts there is a path of adjacent sea provinces
|
||||||
// (not coastal) that are occupied by fleets. The move order is valid even if the fleets
|
// (not coastal) that are occupied by fleets. The move order is valid even if the fleets
|
||||||
// belong to another power or were not given convoy orders; it will simply fail.
|
// belong to another power or were not given convoy orders; it will simply fail.
|
||||||
IDictionary<(string location, Season season), Unit> fleets = world.Units
|
IDictionary<(Location location, Season season), Unit> fleets = world.Units
|
||||||
.Where(unit => unit.Type == UnitType.Fleet)
|
.Where(unit => unit.Type == UnitType.Fleet)
|
||||||
.ToDictionary(unit => (unit.Location, unit.Season));
|
.ToDictionary(unit => (unit.Location, unit.Season));
|
||||||
|
|
||||||
// Verify that the origin is a coastal province.
|
// Verify that the origin is a coastal province.
|
||||||
if (world.Map.GetLocation(movingUnit).Type != LocationType.Land) return false;
|
if (movingUnit.Location.Type != LocationType.Land) return false;
|
||||||
IEnumerable<Location> originCoasts = world.Map.GetLocation(movingUnit).Province.Locations
|
IEnumerable<Location> originCoasts = movingUnit.Province.Locations
|
||||||
.Where(location => location.Type == LocationType.Water);
|
.Where(location => location.Type == LocationType.Water);
|
||||||
if (!originCoasts.Any()) return false;
|
if (!originCoasts.Any()) return false;
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ public static class PathFinder
|
||||||
// If not, add this location to the to-visit set if it isn't a coast, has a fleet,
|
// If not, add this location to the to-visit set if it isn't a coast, has a fleet,
|
||||||
// and hasn't already been visited.
|
// and hasn't already been visited.
|
||||||
if (!adjLocation.Province.Locations.Any(l => l.Type == LocationType.Land)
|
if (!adjLocation.Province.Locations.Any(l => l.Type == LocationType.Land)
|
||||||
&& fleets.ContainsKey((adjLocation.Designation, adjSeason))
|
&& fleets.ContainsKey((adjLocation, adjSeason))
|
||||||
&& !visited.Contains((adjLocation, adjSeason)))
|
&& !visited.Contains((adjLocation, adjSeason)))
|
||||||
{
|
{
|
||||||
toVisit.Enqueue((adjLocation, adjSeason));
|
toVisit.Enqueue((adjLocation, adjSeason));
|
||||||
|
|
|
@ -20,12 +20,12 @@ public class Location
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location's full human-readable name.
|
/// The location's full human-readable name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; }
|
public string? Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location's shorthand abbreviation.
|
/// The location's shorthand abbreviation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Abbreviation { get; }
|
public string? Abbreviation { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location's type.
|
/// The location's type.
|
||||||
|
@ -39,12 +39,7 @@ public class Location
|
||||||
public IEnumerable<Location> Adjacents => this.AdjacentList;
|
public IEnumerable<Location> Adjacents => this.AdjacentList;
|
||||||
private List<Location> AdjacentList { get; set; }
|
private List<Location> AdjacentList { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public Location(Province province, string? name, string? abbreviation, LocationType type)
|
||||||
/// The unique name of this location in the map.
|
|
||||||
/// </summary>
|
|
||||||
public string Designation => $"{this.ProvinceName}/{this.Abbreviation}";
|
|
||||||
|
|
||||||
public Location(Province province, string name, string abbreviation, LocationType type)
|
|
||||||
{
|
{
|
||||||
this.Province = province;
|
this.Province = province;
|
||||||
this.Name = name;
|
this.Name = name;
|
||||||
|
@ -55,7 +50,7 @@ public class Location
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return this.Name == "land" || this.Name == "water"
|
return this.Name == null
|
||||||
? $"{this.Province.Name} ({this.Type})"
|
? $"{this.Province.Name} ({this.Type})"
|
||||||
: $"{this.Province.Name} ({this.Type}:{this.Name}]";
|
: $"{this.Province.Name} ({this.Type}:{this.Name}]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ public class Map
|
||||||
|
|
||||||
private List<Province> _Provinces { get; }
|
private List<Province> _Provinces { get; }
|
||||||
|
|
||||||
private Dictionary<string, Location> LocationLookup { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The game powers.
|
/// The game powers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -31,10 +29,6 @@ public class Map
|
||||||
Type = type;
|
Type = type;
|
||||||
_Provinces = provinces.ToList();
|
_Provinces = provinces.ToList();
|
||||||
_Powers = powers.ToList();
|
_Powers = powers.ToList();
|
||||||
|
|
||||||
LocationLookup = Provinces
|
|
||||||
.SelectMany(province => province.Locations)
|
|
||||||
.ToDictionary(location => location.Designation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -47,27 +41,29 @@ public class Map
|
||||||
/// Get a province by name. Throws if the province is not found.
|
/// Get a province by name. Throws if the province is not found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static Province GetProvince(string provinceName, IEnumerable<Province> provinces)
|
private static Province GetProvince(string provinceName, IEnumerable<Province> provinces)
|
||||||
=> provinces.SingleOrDefault(
|
{
|
||||||
p => p!.Name.Equals(provinceName, StringComparison.InvariantCultureIgnoreCase)
|
string provinceNameUpper = provinceName.ToUpperInvariant();
|
||||||
|| p.Abbreviations.Any(
|
Province? foundProvince = provinces.SingleOrDefault(
|
||||||
a => a.Equals(provinceName, StringComparison.InvariantCultureIgnoreCase)),
|
p => p!.Name.ToUpperInvariant() == provinceNameUpper
|
||||||
null)
|
|| p.Abbreviations.Any(a => a.ToUpperInvariant() == provinceNameUpper),
|
||||||
?? throw new KeyNotFoundException($"Province {provinceName} not found");
|
null);
|
||||||
|
if (foundProvince == null) throw new KeyNotFoundException(
|
||||||
|
$"Province {provinceName} not found");
|
||||||
|
return foundProvince;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the location in a province matching a predicate. Throws if there is not exactly one
|
/// Get the location in a province matching a predicate. Throws if there is not exactly one
|
||||||
/// such location.
|
/// such location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Location GetLocation(string provinceName, Func<Location, bool> predicate)
|
private Location GetLocation(string provinceName, Func<Location, bool> predicate)
|
||||||
=> GetProvince(provinceName).Locations.SingleOrDefault(
|
{
|
||||||
l => l != null && predicate(l), null)
|
Location? foundLocation = GetProvince(provinceName).Locations.SingleOrDefault(
|
||||||
?? throw new KeyNotFoundException($"No such location in {provinceName}");
|
l => l != null && predicate(l), null);
|
||||||
|
if (foundLocation == null) throw new KeyNotFoundException(
|
||||||
public Location GetLocation(string designation)
|
$"No such location in {provinceName}");
|
||||||
=> LocationLookup[designation];
|
return foundLocation;
|
||||||
|
}
|
||||||
public Location GetLocation(Unit unit)
|
|
||||||
=> GetLocation(unit.Location);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the sole land location of a province.
|
/// Get the sole land location of a province.
|
||||||
|
@ -125,10 +121,10 @@ public class Map
|
||||||
#region Provinces
|
#region Provinces
|
||||||
Province.Empty("North Africa", "NAF")
|
Province.Empty("North Africa", "NAF")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Tunis", "TUN")
|
Province.Supply("Tunis", "TUN")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Bohemia", "BOH")
|
Province.Empty("Bohemia", "BOH")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Supply("Budapest", "BUD")
|
Province.Supply("Budapest", "BUD")
|
||||||
|
@ -137,71 +133,71 @@ public class Map
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Supply("Trieste", "TRI")
|
Province.Supply("Trieste", "TRI")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Tyrolia", "TYR")
|
Province.Empty("Tyrolia", "TYR")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Time("Vienna", "VIE")
|
Province.Time("Vienna", "VIE")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Empty("Albania", "ALB")
|
Province.Empty("Albania", "ALB")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Bulgaria", "BUL")
|
Province.Supply("Bulgaria", "BUL")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddCoastLocation("east coast", "ec")
|
.AddCoastLocation("east coast", "ec")
|
||||||
.AddCoastLocation("south coast", "sc"),
|
.AddCoastLocation("south coast", "sc"),
|
||||||
Province.Supply("Greece", "GRE")
|
Province.Supply("Greece", "GRE")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Rumania", "RUM", "RMA")
|
Province.Supply("Rumania", "RUM", "RMA")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Serbia", "SER")
|
Province.Supply("Serbia", "SER")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Empty("Clyde", "CLY")
|
Province.Empty("Clyde", "CLY")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Edinburgh", "EDI")
|
Province.Supply("Edinburgh", "EDI")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Liverpool", "LVP", "LPL")
|
Province.Supply("Liverpool", "LVP", "LPL")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Time("London", "LON")
|
Province.Time("London", "LON")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Wales", "WAL")
|
Province.Empty("Wales", "WAL")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Yorkshire", "YOR")
|
Province.Empty("Yorkshire", "YOR")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Brest", "BRE")
|
Province.Supply("Brest", "BRE")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Burgundy", "BUR")
|
Province.Empty("Burgundy", "BUR")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Empty("Gascony", "GAS")
|
Province.Empty("Gascony", "GAS")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Marseilles", "MAR")
|
Province.Supply("Marseilles", "MAR")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Time("Paris", "PAR")
|
Province.Time("Paris", "PAR")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Empty("Picardy", "PIC")
|
Province.Empty("Picardy", "PIC")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Time("Berlin", "BER")
|
Province.Time("Berlin", "BER")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Kiel", "KIE")
|
Province.Supply("Kiel", "KIE")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Munich", "MUN")
|
Province.Supply("Munich", "MUN")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Empty("Prussia", "PRU")
|
Province.Empty("Prussia", "PRU")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Ruhr", "RUH", "RHR")
|
Province.Empty("Ruhr", "RUH", "RHR")
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Empty("Silesia", "SIL")
|
Province.Empty("Silesia", "SIL")
|
||||||
|
@ -212,43 +208,43 @@ public class Map
|
||||||
.AddCoastLocation("south coast", "sc"),
|
.AddCoastLocation("south coast", "sc"),
|
||||||
Province.Supply("Portugal", "POR")
|
Province.Supply("Portugal", "POR")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Apulia", "APU")
|
Province.Empty("Apulia", "APU")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Naples", "NAP")
|
Province.Supply("Naples", "NAP")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Piedmont", "PIE")
|
Province.Empty("Piedmont", "PIE")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Time("Rome", "ROM", "RME")
|
Province.Time("Rome", "ROM", "RME")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Tuscany", "TUS")
|
Province.Empty("Tuscany", "TUS")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Venice", "VEN")
|
Province.Supply("Venice", "VEN")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Belgium", "BEL")
|
Province.Supply("Belgium", "BEL")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Holland", "HOL")
|
Province.Supply("Holland", "HOL")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Finland", "FIN")
|
Province.Empty("Finland", "FIN")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Livonia", "LVN", "LVA")
|
Province.Empty("Livonia", "LVN", "LVA")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Time("Moscow", "MOS")
|
Province.Time("Moscow", "MOS")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Sevastopol", "SEV")
|
Province.Supply("Sevastopol", "SEV")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Saint Petersburg", "STP")
|
Province.Supply("Saint Petersburg", "STP")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddCoastLocation("north coast", "nc")
|
.AddCoastLocation("north coast", "nc")
|
||||||
|
@ -259,28 +255,28 @@ public class Map
|
||||||
.AddLandLocation(),
|
.AddLandLocation(),
|
||||||
Province.Supply("Denmark", "DEN")
|
Province.Supply("Denmark", "DEN")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Norway", "NWY")
|
Province.Supply("Norway", "NWY")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Sweden", "SWE")
|
Province.Supply("Sweden", "SWE")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Ankara", "ANK")
|
Province.Supply("Ankara", "ANK")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Armenia", "ARM")
|
Province.Empty("Armenia", "ARM")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Time("Constantinople", "CON")
|
Province.Time("Constantinople", "CON")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Supply("Smyrna", "SMY")
|
Province.Supply("Smyrna", "SMY")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Syria", "SYR")
|
Province.Empty("Syria", "SYR")
|
||||||
.AddLandLocation()
|
.AddLandLocation()
|
||||||
.AddOceanLocation(),
|
.AddCoastLocation(),
|
||||||
Province.Empty("Barents Sea", "BAR")
|
Province.Empty("Barents Sea", "BAR")
|
||||||
.AddOceanLocation(),
|
.AddOceanLocation(),
|
||||||
Province.Empty("English Channel", "ENC", "ECH")
|
Province.Empty("English Channel", "ENC", "ECH")
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class Province
|
||||||
this.Abbreviations = abbreviations;
|
this.Abbreviations = abbreviations;
|
||||||
this.IsSupplyCenter = isSupply;
|
this.IsSupplyCenter = isSupply;
|
||||||
this.IsTimeCenter = isTime;
|
this.IsTimeCenter = isTime;
|
||||||
this.LocationList = [];
|
this.LocationList = new List<Location>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@ -49,26 +49,26 @@ public class Province
|
||||||
/// Create a new province with no supply center.
|
/// Create a new province with no supply center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Province Empty(string name, params string[] abbreviations)
|
public static Province Empty(string name, params string[] abbreviations)
|
||||||
=> new(name, abbreviations, isSupply: false, isTime: false);
|
=> new Province(name, abbreviations, isSupply: false, isTime: false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new province with a supply center.
|
/// Create a new province with a supply center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Province Supply(string name, params string[] abbreviations)
|
public static Province Supply(string name, params string[] abbreviations)
|
||||||
=> new(name, abbreviations, isSupply: true, isTime: false);
|
=> new Province(name, abbreviations, isSupply: true, isTime: false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new province with a time center.
|
/// Create a new province with a time center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Province Time(string name, params string[] abbreviations)
|
public static Province Time(string name, params string[] abbreviations)
|
||||||
=> new(name, abbreviations, isSupply: true, isTime: true);
|
=> new Province(name, abbreviations, isSupply: true, isTime: true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new land location in this province.
|
/// Create a new land location in this province.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Province AddLandLocation()
|
public Province AddLandLocation()
|
||||||
{
|
{
|
||||||
Location location = new(this, "land", "l", LocationType.Land);
|
Location location = new Location(this, name: null, abbreviation: null, LocationType.Land);
|
||||||
this.LocationList.Add(location);
|
this.LocationList.Add(location);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,19 @@ public class Province
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Province AddOceanLocation()
|
public Province AddOceanLocation()
|
||||||
{
|
{
|
||||||
Location location = new(this, "water", "w", LocationType.Water);
|
Location location = new Location(this, name: null, abbreviation: null, LocationType.Water);
|
||||||
|
this.LocationList.Add(location);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new coastal location. Coastal locations must have names to disambiguate them
|
||||||
|
/// from the single land location in coastal provinces.
|
||||||
|
/// </summary>
|
||||||
|
public Province AddCoastLocation()
|
||||||
|
{
|
||||||
|
// Use a default name for provinces with only one coastal location
|
||||||
|
Location location = new Location(this, "coast", "c", LocationType.Water);
|
||||||
this.LocationList.Add(location);
|
this.LocationList.Add(location);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +101,7 @@ public class Province
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Province AddCoastLocation(string name, string abbreviation)
|
public Province AddCoastLocation(string name, string abbreviation)
|
||||||
{
|
{
|
||||||
Location location = new(this, name, abbreviation, LocationType.Water);
|
Location location = new Location(this, name, abbreviation, LocationType.Water);
|
||||||
this.LocationList.Add(location);
|
this.LocationList.Add(location);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace MultiversalDiplomacy.Model;
|
namespace MultiversalDiplomacy.Model;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,12 +10,18 @@ public class Unit
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The previous iteration of a unit. This is null if the unit was just built.
|
/// The previous iteration of a unit. This is null if the unit was just built.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Past { get; }
|
public Unit? Past { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location on the map where the unit is.
|
/// The location on the map where the unit is.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Location { get; }
|
public Location Location { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The province where the unit is.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public Province Province => this.Location.Province;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The season in time when the unit is.
|
/// The season in time when the unit is.
|
||||||
|
@ -31,11 +39,11 @@ public class Unit
|
||||||
public UnitType Type { get; }
|
public UnitType Type { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A unique designation for this unit.
|
/// The unit's spatiotemporal location as a province-season tuple.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Designation => $"{Type.ToShort()} {Season.Timeline}-{Location}@{Season.Turn}";
|
public (Province province, Season season) Point => (this.Province, this.Season);
|
||||||
|
|
||||||
private Unit(string? past, string location, Season season, Power power, UnitType type)
|
private Unit(Unit? past, Location location, Season season, Power power, UnitType type)
|
||||||
{
|
{
|
||||||
this.Past = past;
|
this.Past = past;
|
||||||
this.Location = location;
|
this.Location = location;
|
||||||
|
@ -45,18 +53,20 @@ public class Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
=> $"{Power.Name[0]} {Type.ToShort()} {Season.Timeline}-{Location}@{Season.Turn}";
|
{
|
||||||
|
return $"{this.Power.Name[0]} {this.Type.ToShort()} {(this.Province, this.Season).ToShort()}";
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new unit. No validation is performed; the adjudicator should only call this
|
/// Create a new unit. No validation is performed; the adjudicator should only call this
|
||||||
/// method after accepting a build order.
|
/// method after accepting a build order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Unit Build(string location, Season season, Power power, UnitType type)
|
public static Unit Build(Location location, Season season, Power power, UnitType type)
|
||||||
=> new(past: null, location, season, power, type);
|
=> new(past: null, location, season, power, type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Advance this unit's timeline to a new location and season.
|
/// Advance this unit's timeline to a new location and season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Unit Next(string location, Season season)
|
public Unit Next(Location location, Season season)
|
||||||
=> new(past: this.Designation, location, season, this.Power, this.Type);
|
=> new(past: this, location, season, this.Power, this.Type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace MultiversalDiplomacy.Model;
|
namespace MultiversalDiplomacy.Model;
|
||||||
|
@ -204,7 +205,7 @@ public class World
|
||||||
: splits.Length == 3
|
: splits.Length == 3
|
||||||
? Map.GetWater(splits[2])
|
? Map.GetWater(splits[2])
|
||||||
: Map.GetWater(splits[2], splits[3]);
|
: Map.GetWater(splits[2], splits[3]);
|
||||||
Unit unit = Unit.Build(location.Designation, this.RootSeason, power, type);
|
Unit unit = Unit.Build(location, this.RootSeason, power, type);
|
||||||
return unit;
|
return unit;
|
||||||
});
|
});
|
||||||
return this.Update(units: units);
|
return this.Update(units: units);
|
||||||
|
@ -327,13 +328,9 @@ public class World
|
||||||
Province province = Map.GetProvince(provinceName);
|
Province province = Map.GetProvince(provinceName);
|
||||||
season ??= RootSeason;
|
season ??= RootSeason;
|
||||||
Unit? foundUnit = this.Units.SingleOrDefault(
|
Unit? foundUnit = this.Units.SingleOrDefault(
|
||||||
u => Map.GetLocation(u!).Province == province && u!.Season == season,
|
u => u!.Province == province && u.Season == season,
|
||||||
null)
|
null)
|
||||||
?? throw new KeyNotFoundException($"Unit at {province} at {season} not found");
|
?? throw new KeyNotFoundException($"Unit at {province} at {season} not found");
|
||||||
return foundUnit;
|
return foundUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unit GetUnitByDesignation(string designation)
|
|
||||||
=> Units.SingleOrDefault(u => u!.Designation == designation, null)
|
|
||||||
?? throw new KeyNotFoundException($"Unit {designation} not found");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ public class MoveOrder : UnitOrder
|
||||||
return $"{this.Unit} -> {(this.Province, this.Season).ToShort()}";
|
return $"{this.Unit} -> {(this.Province, this.Season).ToShort()}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether another move order is in a head-to-head battle with this order.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsOpposing(MoveOrder other)
|
||||||
|
=> this.Season == other.Unit.Season
|
||||||
|
&& other.Season == this.Unit.Season
|
||||||
|
&& this.Province == other.Unit.Province
|
||||||
|
&& other.Province == this.Unit.Province;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns whether another move order has the same destination as this order.
|
/// Returns whether another move order has the same destination as this order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -16,4 +16,12 @@ public abstract class UnitOrder : Order
|
||||||
{
|
{
|
||||||
this.Unit = unit;
|
this.Unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether a move order is moving into this order's unit's province.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsIncoming(MoveOrder other)
|
||||||
|
=> this != other
|
||||||
|
&& other.Season == this.Unit.Season
|
||||||
|
&& other.Province == this.Unit.Province;
|
||||||
}
|
}
|
|
@ -46,12 +46,12 @@ public class TimeTravelTest
|
||||||
Unit originalUnit = world.GetUnitAt("Mun", s0);
|
Unit originalUnit = world.GetUnitAt("Mun", s0);
|
||||||
Unit aMun0 = world.GetUnitAt("Mun", s1);
|
Unit aMun0 = world.GetUnitAt("Mun", s1);
|
||||||
Unit aTyr = world.GetUnitAt("Tyr", fork);
|
Unit aTyr = world.GetUnitAt("Tyr", fork);
|
||||||
Assert.That(aTyr.Past, Is.EqualTo(mun1.Order.Unit.Designation));
|
Assert.That(aTyr.Past, Is.EqualTo(mun1.Order.Unit));
|
||||||
Assert.That(world.GetUnitByDesignation(aTyr.Past!).Past, Is.EqualTo(mun0.Order.Unit.Designation));
|
Assert.That(aTyr.Past?.Past, Is.EqualTo(mun0.Order.Unit));
|
||||||
|
|
||||||
// Confirm that there is a unit in Mun b1 originating from Mun a0
|
// Confirm that there is a unit in Mun b1 originating from Mun a0
|
||||||
Unit aMun1 = world.GetUnitAt("Mun", fork);
|
Unit aMun1 = world.GetUnitAt("Mun", fork);
|
||||||
Assert.That(aMun1.Past, Is.EqualTo(originalUnit.Designation));
|
Assert.That(aMun1.Past, Is.EqualTo(originalUnit));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -95,7 +95,7 @@ public class TimeTravelTest
|
||||||
Unit tyr1 = world.GetUnitAt("Tyr", fork);
|
Unit tyr1 = world.GetUnitAt("Tyr", fork);
|
||||||
Assert.That(
|
Assert.That(
|
||||||
tyr1.Past,
|
tyr1.Past,
|
||||||
Is.EqualTo(mun0.Order.Unit.Designation),
|
Is.EqualTo(mun0.Order.Unit),
|
||||||
"Expected A Mun a0 to advance to Tyr b1");
|
"Expected A Mun a0 to advance to Tyr b1");
|
||||||
Assert.That(
|
Assert.That(
|
||||||
world.RetreatingUnits.Count,
|
world.RetreatingUnits.Count,
|
||||||
|
|
|
@ -209,7 +209,7 @@ public class MovementAdjudicatorTest
|
||||||
Unit u2 = updated.GetUnitAt("Mun", s2);
|
Unit u2 = updated.GetUnitAt("Mun", s2);
|
||||||
Assert.That(updated.Units.Count, Is.EqualTo(2));
|
Assert.That(updated.Units.Count, Is.EqualTo(2));
|
||||||
Assert.That(u2, Is.Not.EqualTo(mun1.Order.Unit));
|
Assert.That(u2, Is.Not.EqualTo(mun1.Order.Unit));
|
||||||
Assert.That(u2.Past, Is.EqualTo(mun1.Order.Unit.Designation));
|
Assert.That(u2.Past, Is.EqualTo(mun1.Order.Unit));
|
||||||
Assert.That(u2.Season, Is.EqualTo(s2));
|
Assert.That(u2.Season, Is.EqualTo(s2));
|
||||||
|
|
||||||
setup[("a", 1)]
|
setup[("a", 1)]
|
||||||
|
@ -229,7 +229,7 @@ public class MovementAdjudicatorTest
|
||||||
updated = setup.UpdateWorld();
|
updated = setup.UpdateWorld();
|
||||||
Season s3 = updated.GetSeason(s2.Timeline, s2.Turn + 1);
|
Season s3 = updated.GetSeason(s2.Timeline, s2.Turn + 1);
|
||||||
Unit u3 = updated.GetUnitAt("Mun", s3);
|
Unit u3 = updated.GetUnitAt("Mun", s3);
|
||||||
Assert.That(u3.Past, Is.EqualTo(mun2.Order.Unit.Designation));
|
Assert.That(u3.Past, Is.EqualTo(mun2.Order.Unit));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -259,7 +259,7 @@ public class MovementAdjudicatorTest
|
||||||
Unit u2 = updated.GetUnitAt("Tyr", s2);
|
Unit u2 = updated.GetUnitAt("Tyr", s2);
|
||||||
Assert.That(updated.Units.Count, Is.EqualTo(2));
|
Assert.That(updated.Units.Count, Is.EqualTo(2));
|
||||||
Assert.That(u2, Is.Not.EqualTo(mun1.Order.Unit));
|
Assert.That(u2, Is.Not.EqualTo(mun1.Order.Unit));
|
||||||
Assert.That(u2.Past, Is.EqualTo(mun1.Order.Unit.Designation));
|
Assert.That(u2.Past, Is.EqualTo(mun1.Order.Unit));
|
||||||
Assert.That(u2.Season, Is.EqualTo(s2));
|
Assert.That(u2.Season, Is.EqualTo(s2));
|
||||||
|
|
||||||
setup[("a", 1)]
|
setup[("a", 1)]
|
||||||
|
@ -279,6 +279,6 @@ public class MovementAdjudicatorTest
|
||||||
updated = setup.UpdateWorld();
|
updated = setup.UpdateWorld();
|
||||||
Season s3 = updated.GetSeason(s2.Timeline, s2.Turn + 1);
|
Season s3 = updated.GetSeason(s2.Timeline, s2.Turn + 1);
|
||||||
Unit u3 = updated.GetUnitAt("Mun", s3);
|
Unit u3 = updated.GetUnitAt("Mun", s3);
|
||||||
Assert.That(u3.Past, Is.EqualTo(u2.Designation));
|
Assert.That(u3.Past, Is.EqualTo(u2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,8 @@ public abstract class OrderReference
|
||||||
DefendStrength defend => defend.Order == this.Order,
|
DefendStrength defend => defend.Order == this.Order,
|
||||||
PreventStrength prevent => prevent.Order == this.Order,
|
PreventStrength prevent => prevent.Order == this.Order,
|
||||||
HoldStrength hold => this.Order is UnitOrder unitOrder
|
HoldStrength hold => this.Order is UnitOrder unitOrder
|
||||||
&& hold.Province == Builder.World.Map.GetLocation(unitOrder.Unit).Province,
|
? hold.Province == unitOrder.Unit.Province
|
||||||
|
: false,
|
||||||
_ => false,
|
_ => false,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
return adjudications;
|
return adjudications;
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class SerializationTest
|
||||||
Unit tyr1 = world.GetUnitAt("Tyr", fork);
|
Unit tyr1 = world.GetUnitAt("Tyr", fork);
|
||||||
Assert.That(
|
Assert.That(
|
||||||
tyr1.Past,
|
tyr1.Past,
|
||||||
Is.EqualTo(mun0.Order.Unit.Designation),
|
Is.EqualTo(mun0.Order.Unit),
|
||||||
"Expected A Mun a0 to advance to Tyr b1");
|
"Expected A Mun a0 to advance to Tyr b1");
|
||||||
Assert.That(
|
Assert.That(
|
||||||
world.RetreatingUnits.Count,
|
world.RetreatingUnits.Count,
|
||||||
|
|
|
@ -262,7 +262,7 @@ public class TestCaseBuilder
|
||||||
foreach (Unit unit in this.World.Units)
|
foreach (Unit unit in this.World.Units)
|
||||||
{
|
{
|
||||||
if (unit.Power == power
|
if (unit.Power == power
|
||||||
&& World.Map.GetLocation(unit).Province == location.Province
|
&& unit.Province == location.Province
|
||||||
&& unit.Season == season)
|
&& unit.Season == season)
|
||||||
{
|
{
|
||||||
return unit;
|
return unit;
|
||||||
|
@ -270,7 +270,7 @@ public class TestCaseBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not found
|
// Not found
|
||||||
Unit newUnit = Unit.Build(location.Designation, season, power, type);
|
Unit newUnit = Unit.Build(location, season, power, type);
|
||||||
this.World = this.World.Update(units: this.World.Units.Append(newUnit));
|
this.World = this.World.Update(units: this.World.Units.Append(newUnit));
|
||||||
return newUnit;
|
return newUnit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ class TestCaseBuilderTest
|
||||||
Assert.That(fleetSTP.Type, Is.EqualTo(UnitType.Fleet), "Unit created with wrong type");
|
Assert.That(fleetSTP.Type, Is.EqualTo(UnitType.Fleet), "Unit created with wrong type");
|
||||||
Assert.That(
|
Assert.That(
|
||||||
fleetSTP.Location,
|
fleetSTP.Location,
|
||||||
Is.EqualTo(setup.World.Map.GetWater("STP", "wc").Designation),
|
Is.EqualTo(setup.World.Map.GetWater("STP", "wc")),
|
||||||
"Unit created on wrong coast");
|
"Unit created on wrong coast");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class TestCaseBuilderTest
|
||||||
List<UnitOrder> orders = setup.Orders.OfType<UnitOrder>().ToList();
|
List<UnitOrder> orders = setup.Orders.OfType<UnitOrder>().ToList();
|
||||||
|
|
||||||
Func<UnitOrder, bool> OrderForProvince(string name)
|
Func<UnitOrder, bool> OrderForProvince(string name)
|
||||||
=> order => setup.World.Map.GetLocation(order.Unit).Province.Name == name;
|
=> order => order.Unit.Province.Name == name;
|
||||||
|
|
||||||
UnitOrder orderBer = orders.Single(OrderForProvince("Berlin"));
|
UnitOrder orderBer = orders.Single(OrderForProvince("Berlin"));
|
||||||
Assert.That(orderBer, Is.InstanceOf<MoveOrder>(), "Unexpected order type");
|
Assert.That(orderBer, Is.InstanceOf<MoveOrder>(), "Unexpected order type");
|
||||||
|
@ -128,7 +128,7 @@ class TestCaseBuilderTest
|
||||||
"Wrong power");
|
"Wrong power");
|
||||||
Assert.That(
|
Assert.That(
|
||||||
orderMun.Order.Unit.Location,
|
orderMun.Order.Unit.Location,
|
||||||
Is.EqualTo(setup.World.Map.GetLand("Mun").Designation),
|
Is.EqualTo(setup.World.Map.GetLand("Mun")),
|
||||||
"Wrong unit");
|
"Wrong unit");
|
||||||
|
|
||||||
Assert.That(
|
Assert.That(
|
||||||
|
|
|
@ -15,24 +15,24 @@ public class UnitTests
|
||||||
Tyr = world.Map.GetLand("Tyr");
|
Tyr = world.Map.GetLand("Tyr");
|
||||||
Power pw1 = world.Map.GetPower("Austria");
|
Power pw1 = world.Map.GetPower("Austria");
|
||||||
Season a0 = world.RootSeason;
|
Season a0 = world.RootSeason;
|
||||||
Unit u1 = Unit.Build(Mun.Designation, a0, pw1, UnitType.Army);
|
Unit u1 = Unit.Build(Mun, a0, pw1, UnitType.Army);
|
||||||
|
|
||||||
world = world.ContinueOrFork(a0, out Season a1);
|
world = world.ContinueOrFork(a0, out Season a1);
|
||||||
Unit u2 = u1.Next(Boh.Designation, a1);
|
Unit u2 = u1.Next(Boh, a1);
|
||||||
|
|
||||||
_ = world.ContinueOrFork(a1, out Season a2);
|
_ = world.ContinueOrFork(a1, out Season a2);
|
||||||
Unit u3 = u2.Next(Tyr.Designation, a2);
|
Unit u3 = u2.Next(Tyr, a2);
|
||||||
|
|
||||||
Assert.That(u3.Past, Is.EqualTo(u2.Designation), "Missing unit past");
|
Assert.That(u3.Past, Is.EqualTo(u2), "Missing unit past");
|
||||||
Assert.That(u2.Past, Is.EqualTo(u1.Designation), "Missing unit past");
|
Assert.That(u2.Past, Is.EqualTo(u1), "Missing unit past");
|
||||||
Assert.That(u1.Past, Is.Null, "Unexpected unit past");
|
Assert.That(u1.Past, Is.Null, "Unexpected unit past");
|
||||||
|
|
||||||
Assert.That(u1.Season, Is.EqualTo(a0), "Unexpected unit season");
|
Assert.That(u1.Season, Is.EqualTo(a0), "Unexpected unit season");
|
||||||
Assert.That(u2.Season, Is.EqualTo(a1), "Unexpected unit season");
|
Assert.That(u2.Season, Is.EqualTo(a1), "Unexpected unit season");
|
||||||
Assert.That(u3.Season, Is.EqualTo(a2), "Unexpected unit season");
|
Assert.That(u3.Season, Is.EqualTo(a2), "Unexpected unit season");
|
||||||
|
|
||||||
Assert.That(u1.Location, Is.EqualTo(Mun.Designation), "Unexpected unit location");
|
Assert.That(u1.Location, Is.EqualTo(Mun), "Unexpected unit location");
|
||||||
Assert.That(u2.Location, Is.EqualTo(Boh.Designation), "Unexpected unit location");
|
Assert.That(u2.Location, Is.EqualTo(Boh), "Unexpected unit location");
|
||||||
Assert.That(u3.Location, Is.EqualTo(Tyr.Designation), "Unexpected unit location");
|
Assert.That(u3.Location, Is.EqualTo(Tyr), "Unexpected unit location");
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue