Compare commits
No commits in common. "128f5a4230a8a0c117a299aa06279b7b2e85f2c4" and "46b18eda33dfeaa5b2f20492db2b968095c417c0" have entirely different histories.
128f5a4230
...
46b18eda33
|
@ -194,21 +194,6 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
|
||||||
// unit can move to the destination.
|
// unit can move to the destination.
|
||||||
List<SupportMoveOrder> supportMoveOrders = unitOrders.OfType<SupportMoveOrder>().ToList();
|
List<SupportMoveOrder> supportMoveOrders = unitOrders.OfType<SupportMoveOrder>().ToList();
|
||||||
|
|
||||||
// Trivial check: armies cannot move to water and fleets cannot move to land.
|
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
|
||||||
order => (order.Target.Type == UnitType.Army && order.Location.Type == LocationType.Land)
|
|
||||||
|| (order.Target.Type == UnitType.Fleet && order.Location.Type == LocationType.Water),
|
|
||||||
ValidationReason.IllegalDestinationType,
|
|
||||||
ref supportMoveOrders,
|
|
||||||
ref validationResults);
|
|
||||||
|
|
||||||
// Trivial check: a unit cannot move to where it already is.
|
|
||||||
AdjudicatorHelpers.InvalidateIfNotMatching(
|
|
||||||
order => !(order.Location.Key == order.Target.Location && order.Season == order.Unit.Season),
|
|
||||||
ValidationReason.DestinationMatchesOrigin,
|
|
||||||
ref supportMoveOrders,
|
|
||||||
ref validationResults);
|
|
||||||
|
|
||||||
// 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(
|
||||||
|
|
|
@ -266,28 +266,15 @@ public class OrderParser(World world)
|
||||||
order = null;
|
order = null;
|
||||||
OrderParser re = new(world);
|
OrderParser re = new(world);
|
||||||
|
|
||||||
if (re.Hold.Match(command) is Match holdMatch && holdMatch.Success)
|
if (re.Hold.Match(command) is Match holdMatch && holdMatch.Success) {
|
||||||
{
|
|
||||||
return TryParseHoldOrder(world, power, holdMatch, out order);
|
return TryParseHoldOrder(world, power, holdMatch, out order);
|
||||||
}
|
} else if (re.Move.Match(command) is Match moveMatch && moveMatch.Success) {
|
||||||
else if (re.Move.Match(command) is Match moveMatch && moveMatch.Success)
|
|
||||||
{
|
|
||||||
return TryParseMoveOrder(world, power, moveMatch, out order);
|
return TryParseMoveOrder(world, power, moveMatch, out order);
|
||||||
}
|
} else if (re.SupportHold.Match(command) is Match sholdMatch && sholdMatch.Success) {
|
||||||
else if (re.SupportHold.Match(command) is Match sholdMatch && sholdMatch.Success)
|
|
||||||
{
|
|
||||||
return TryParseSupportHoldOrder(world, power, sholdMatch, out order);
|
return TryParseSupportHoldOrder(world, power, sholdMatch, out order);
|
||||||
}
|
} else if (re.SupportMove.Match(command) is Match smoveMatch && smoveMatch.Success) {
|
||||||
else if (re.SupportMove.Match(command) is Match smoveMatch && smoveMatch.Success)
|
|
||||||
{
|
|
||||||
return TryParseSupportMoveOrder(world, power, smoveMatch, out order);
|
return TryParseSupportMoveOrder(world, power, smoveMatch, out order);
|
||||||
}
|
} else {
|
||||||
else if (re.Convoy.Match(command) is Match convoyMatch && convoyMatch.Success)
|
|
||||||
{
|
|
||||||
return TryParseConvoyOrder(world, power, convoyMatch, out order);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,45 +495,4 @@ public class OrderParser(World world)
|
||||||
order = new SupportMoveOrder(power, subject, target, new(destTimeline, destTurn), destLocation);
|
order = new SupportMoveOrder(power, subject, target, new(destTimeline, destTurn), destLocation);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryParseConvoyOrder(
|
|
||||||
World world,
|
|
||||||
string power,
|
|
||||||
Match match,
|
|
||||||
[NotNullWhen(true)] out Order? order)
|
|
||||||
{
|
|
||||||
order = null;
|
|
||||||
var convoy = ParseConvoy(match);
|
|
||||||
|
|
||||||
if (!TryParseOrderSubject(world, convoy.timeline, convoy.turn, convoy.province, out Unit? subject)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TryParseOrderSubject(
|
|
||||||
world, convoy.targetTimeline, convoy.targetTurn, convoy.targetProvince, out Unit? target))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string destTimeline = convoy.destTimeline.Length > 0
|
|
||||||
? convoy.destTimeline
|
|
||||||
// If the destination is unspecified, use the target's
|
|
||||||
: target.Season.Timeline;
|
|
||||||
|
|
||||||
int destTurn = convoy.destTurn.Length > 0
|
|
||||||
? int.Parse(convoy.destTurn)
|
|
||||||
// If the destination is unspecified, use the unit's
|
|
||||||
: target.Season.Turn;
|
|
||||||
|
|
||||||
var destProvince = world.Map.Provinces.Single(province => province.Is(convoy.destProvince));
|
|
||||||
|
|
||||||
// Only armies can be convoyed, which means the destination location can only be land.
|
|
||||||
var landLocations = destProvince.Locations.Where(loc => loc.Type == LocationType.Land);
|
|
||||||
if (!landLocations.Any()) return false; // Can't convoy to water
|
|
||||||
string destLocationKey = landLocations.First().Key;
|
|
||||||
var destLocation = world.Map.GetLocation(destLocationKey);
|
|
||||||
|
|
||||||
order = new ConvoyOrder(power, subject, target, new(destTimeline, destTurn), destLocation);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,17 +373,4 @@ public class OrderParserTest
|
||||||
Is.False,
|
Is.False,
|
||||||
"Should not parse ambiguous coastal support");
|
"Should not parse ambiguous coastal support");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void DisambiguateConvoyDestination()
|
|
||||||
{
|
|
||||||
World world = World.WithStandardMap().AddUnits("France F MID", "France A Brest");
|
|
||||||
|
|
||||||
Assert.That(
|
|
||||||
OrderParser.TryParseOrder(world, "France", "MID C Brest - Spain", out Order? order),
|
|
||||||
"Failed to parse convoy order");
|
|
||||||
Assert.That(order, Is.TypeOf<ConvoyOrder>(), "Unexpected order type");
|
|
||||||
Location dest = ((ConvoyOrder)order!).Location;
|
|
||||||
Assert.That(dest.Name, Is.EqualTo("land"), "Unexpected destination location");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# 6.A.5. TEST CASE, MOVE TO OWN SECTOR WITH CONVOY
|
# 6.A.5. TEST CASE, MOVE TO OWN SECTOR WITH CONVOY
|
||||||
# Moving to the same sector is still illegal with convoy (2023 rulebook, page 7, "Note: An Army can move across water provinces from one coastal province to another...").
|
# Moving to the same sector is still illegal with convoy (2023 rulebook, page 7, "Note: An Army can move across water provinces from one coastal province to another...").
|
||||||
|
|
||||||
|
# TODO convoy order parsing
|
||||||
|
#test:skip
|
||||||
|
|
||||||
unit England F North Sea
|
unit England F North Sea
|
||||||
unit England A Yorkshire
|
unit England A Yorkshire
|
||||||
unit England A Liverpool
|
unit England A Liverpool
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# 6.A.7. TEST CASE, ONLY ARMIES CAN BE CONVOYED
|
# 6.A.7. TEST CASE, ONLY ARMIES CAN BE CONVOYED
|
||||||
# A fleet cannot be convoyed.
|
# A fleet cannot be convoyed.
|
||||||
|
|
||||||
|
# TODO convoy order parsing
|
||||||
|
#test:skip
|
||||||
|
|
||||||
unit England F London
|
unit England F London
|
||||||
unit England F North Sea
|
unit England F North Sea
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue