Factor out common subject parsing logic
This commit is contained in:
parent
14a493d95c
commit
f77cc60185
|
@ -223,73 +223,77 @@ public class OrderParser(World world)
|
|||
} else if (re.Move.Match(command) is Match moveMatch && moveMatch.Success) {
|
||||
return TryParseMoveOrder(world, power, moveMatch, out order);
|
||||
} else if (re.SupportHold.Match(command) is Match sholdMatch && sholdMatch.Success) {
|
||||
// DATC 4.B.4: coast specification in support orders
|
||||
throw new NotImplementedException();
|
||||
return TryParseSupportHoldOrder(world, power, sholdMatch, out order);
|
||||
} else if (re.SupportMove.Match(command) is Match smoveMatch && smoveMatch.Success) {
|
||||
throw new NotImplementedException();
|
||||
return TryParseSupportMoveOrder(world, power, smoveMatch, out order);
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryParseHoldOrder(World world, string power, Match match, [NotNullWhen(true)] out Order? order)
|
||||
public static bool TryParseOrderSubject(
|
||||
World world,
|
||||
string parsedTimeline,
|
||||
string parsedTurn,
|
||||
string parsedProvince,
|
||||
[NotNullWhen(true)] out Unit? subject)
|
||||
{
|
||||
order = null;
|
||||
var hold = ParseHold(match);
|
||||
|
||||
string timeline = hold.timeline.Length > 0
|
||||
? hold.timeline
|
||||
subject = null;
|
||||
|
||||
string timeline = parsedTimeline.Length > 0
|
||||
? parsedTimeline
|
||||
// If timeline is unspecified, use the root timeline
|
||||
: Season.First.Timeline;
|
||||
var seasonsInTimeline = world.Timelines.Seasons.Where(season => season.Timeline == timeline);
|
||||
if (!seasonsInTimeline.Any()) return false;
|
||||
|
||||
int turn = hold.turn.Length > 0
|
||||
? int.Parse(hold.turn)
|
||||
int turn = parsedTurn.Length > 0
|
||||
? int.Parse(parsedTurn)
|
||||
// If turn is unspecified, use the latest turn in the timeline
|
||||
: seasonsInTimeline.Max(season => season.Turn);
|
||||
|
||||
Province province = world.Map.Provinces.Single(province => province.Is(hold.province));
|
||||
Province province = world.Map.Provinces.Single(province => province.Is(parsedProvince));
|
||||
|
||||
Unit? subject = world.Units.FirstOrDefault(unit
|
||||
// Because only one unit can be in a province at a time, the province is sufficient to identify the subject
|
||||
// and the location is ignored. This also satisfies DATC 4.B.5, which requires that a wrong coast for the
|
||||
// subject be ignored.
|
||||
subject = world.Units.FirstOrDefault(unit
|
||||
=> world.Map.GetLocation(unit!.Location).ProvinceName == province.Name
|
||||
&& unit!.Season.Timeline == timeline
|
||||
&& unit!.Season.Turn == turn,
|
||||
null);
|
||||
if (subject is null) return false;
|
||||
return subject is not null;
|
||||
}
|
||||
|
||||
public static bool TryParseHoldOrder(
|
||||
World world,
|
||||
string power,
|
||||
Match match,
|
||||
[NotNullWhen(true)] out Order? order)
|
||||
{
|
||||
order = null;
|
||||
var hold = ParseHold(match);
|
||||
|
||||
if (!TryParseOrderSubject(world, hold.timeline, hold.turn, hold.province, out Unit? subject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
order = new HoldOrder(power, subject);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryParseMoveOrder(World world, string power, Match match, [NotNullWhen(true)] out Order? order)
|
||||
public static bool TryParseMoveOrder(
|
||||
World world,
|
||||
string power,
|
||||
Match match,
|
||||
[NotNullWhen(true)] out Order? order)
|
||||
{
|
||||
order = null;
|
||||
var move = ParseMove(match);
|
||||
|
||||
string timeline = move.timeline.Length > 0
|
||||
? move.timeline
|
||||
// If timeline is unspecified, use the root timeline
|
||||
: Season.First.Timeline;
|
||||
var seasonsInTimeline = world.Timelines.Seasons.Where(season => season.Timeline == timeline);
|
||||
if (!seasonsInTimeline.Any()) return false;
|
||||
|
||||
int turn = move.turn.Length > 0
|
||||
? int.Parse(move.turn)
|
||||
// If turn is unspecified, use the latest turn in the timeline
|
||||
: seasonsInTimeline.Max(season => season.Turn);
|
||||
|
||||
Province province = world.Map.Provinces.Single(province => province.Is(move.province));
|
||||
|
||||
// Because only one unit can be in a province at a time, the province is sufficient to identify the subject
|
||||
// and the location is ignored. This also satisfies DATC 4.B.5, which requires that a wrong coast for the
|
||||
// subject be ignored.
|
||||
Unit? subject = world.Units.FirstOrDefault(unit
|
||||
=> world.Map.GetLocation(unit!.Location).ProvinceName == province.Name
|
||||
&& unit!.Season.Timeline == timeline
|
||||
&& unit!.Season.Turn == turn,
|
||||
null);
|
||||
if (subject is null) return false;
|
||||
if (!TryParseOrderSubject(world, move.timeline, move.turn, move.province, out Unit? subject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string destTimeline = move.destTimeline.Length > 0
|
||||
? move.destTimeline
|
||||
|
@ -333,4 +337,29 @@ public class OrderParser(World world)
|
|||
order = new MoveOrder(power, subject, new(destTimeline, destTurn), destLocationKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryParseSupportHoldOrder(
|
||||
World world,
|
||||
string power,
|
||||
Match match,
|
||||
[NotNullWhen(true)] out Order? order)
|
||||
{
|
||||
order = null;
|
||||
var support = ParseSupportHold(match);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static bool TryParseSupportMoveOrder(
|
||||
World world,
|
||||
string power,
|
||||
Match match,
|
||||
[NotNullWhen(true)] out Order? order)
|
||||
{
|
||||
order = null;
|
||||
var support = ParseSupportMove(match);
|
||||
throw new NotImplementedException();
|
||||
|
||||
// It is possible to support a move to an inaccessible coast if another coast is accessible to the subject.
|
||||
// DATC 4.B.4 prefers that automatic adjudicators strictly require matching coasts in supports.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue