diff --git a/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs b/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs
index 3e048f2..308985a 100644
--- a/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs
+++ b/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs
@@ -286,7 +286,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (AdjudicationDecision decision in decisions.Values)
{
// This will noop without progress if the decision is already resolved
- progress |= ResolveDecision(decision, world, decisions);
+ progress |= ResolveDecision(decision, world, decisions, depth: 0);
}
} while (progress);
@@ -384,27 +384,37 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
return updated;
}
+ ///
+ /// Attempt to resolve an adjudication decision.
+ ///
+ ///
+ /// If any adjudication was further determined, returns true. If nothing was further determined, returns false.
+ ///
private bool ResolveDecision(
AdjudicationDecision decision,
World world,
- MovementDecisions decisions)
- => decision.Resolved ? false : decision switch
+ MovementDecisions decisions,
+ int depth)
+ {
+ return decision.Resolved ? false : decision switch
{
- IsDislodged d => ResolveIsUnitDislodged(d, world, decisions),
- HasPath d => ResolveDoesMoveHavePath(d, world, decisions),
- GivesSupport d => ResolveIsSupportGiven(d, world, decisions),
- HoldStrength d => ResolveHoldStrength(d, world, decisions),
- AttackStrength d => ResolveAttackStrength(d, world, decisions),
- DefendStrength d => ResolveDefendStrength(d, world, decisions),
- PreventStrength d => ResolvePreventStrength(d, world, decisions),
- DoesMove d => ResolveDoesUnitMove(d, world, decisions),
+ IsDislodged d => ResolveIsUnitDislodged(d, world, decisions, depth + 1),
+ HasPath d => ResolveDoesMoveHavePath(d, world, decisions, depth + 1),
+ GivesSupport d => ResolveIsSupportGiven(d, world, decisions, depth + 1),
+ HoldStrength d => ResolveHoldStrength(d, world, decisions, depth + 1),
+ AttackStrength d => ResolveAttackStrength(d, world, decisions, depth + 1),
+ DefendStrength d => ResolveDefendStrength(d, world, decisions, depth + 1),
+ PreventStrength d => ResolvePreventStrength(d, world, decisions, depth + 1),
+ DoesMove d => ResolveDoesUnitMove(d, world, decisions, depth + 1),
_ => throw new NotSupportedException($"Unknown decision type: {decision.GetType()}")
};
+ }
private bool ResolveIsUnitDislodged(
IsDislodged decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
@@ -413,7 +423,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
if (decision.Order is MoveOrder moveOrder)
{
DoesMove move = decisions.DoesMove[moveOrder];
- progress |= ResolveDecision(move, world, decisions);
+ progress |= ResolveDecision(move, world, decisions, depth + 1);
// If this unit received a move order and the move is successful, it cannot be
// dislodged.
@@ -437,7 +447,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (MoveOrder dislodger in decision.Incoming)
{
DoesMove move = decisions.DoesMove[dislodger];
- progress |= ResolveDecision(move, world, decisions);
+ progress |= ResolveDecision(move, world, decisions, depth + 1);
// If at least one invader will move, this unit is dislodged.
if (move.Outcome == true)
@@ -465,7 +475,8 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolveDoesMoveHavePath(
HasPath decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress= false;
@@ -494,7 +505,8 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolveIsSupportGiven(
GivesSupport decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
@@ -504,7 +516,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (MoveOrder cut in decision.Cuts)
{
AttackStrength attack = decisions.AttackStrength[cut];
- progress |= ResolveDecision(attack, world, decisions);
+ progress |= ResolveDecision(attack, world, decisions, depth + 1);
// If at least one attack has a nonzero minimum, the support decision can be resolved
// to false.
@@ -524,7 +536,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
// Support is also cut if the unit is dislodged.
IsDislodged dislodge = decisions.IsDislodged[decision.Order.Unit];
- progress |= ResolveDecision(dislodge, world, decisions);
+ progress |= ResolveDecision(dislodge, world, decisions, depth + 1);
if (dislodge.Outcome == true)
{
progress |= decision.Update(false);
@@ -546,7 +558,8 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolveHoldStrength(
HoldStrength decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
@@ -561,7 +574,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
if (decision.Order is MoveOrder move)
{
DoesMove moves = decisions.DoesMove[move];
- progress |= ResolveDecision(moves, world, decisions);
+ progress |= ResolveDecision(moves, world, decisions, depth + 1);
progress |= decision.Update(
moves.Outcome != false ? 0 : 1,
moves.Outcome == true ? 0 : 1);
@@ -575,7 +588,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (SupportHoldOrder support in decision.Supports)
{
GivesSupport givesSupport = decisions.GivesSupport[support];
- progress |= ResolveDecision(givesSupport, world, decisions);
+ progress |= ResolveDecision(givesSupport, world, decisions, depth + 1);
if (givesSupport.Outcome == true) min += 1;
if (givesSupport.Outcome != false) max += 1;
}
@@ -587,13 +600,14 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolveAttackStrength(
AttackStrength decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
// If there is no path, the attack strength is zero.
var hasPath = decisions.HasPath[decision.Order];
- progress |= ResolveDecision(hasPath, world, decisions);
+ progress |= ResolveDecision(hasPath, world, decisions, depth + 1);
if (hasPath.Outcome == false)
{
progress |= decision.Update(0, 0);
@@ -609,7 +623,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
: null;
if (destMoveAway != null)
{
- progress |= ResolveDecision(destMoveAway, world, decisions);
+ progress |= ResolveDecision(destMoveAway, world, decisions, depth + 1);
}
if (// In any case here, there will have to be a unit at the destination with an order,
// which means that destOrder will have to be populated. Including this in the if
@@ -638,7 +652,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
{
if (support.Unit.Power == destPower) continue;
GivesSupport givesSupport = decisions.GivesSupport[support];
- progress |= ResolveDecision(givesSupport, world, decisions);
+ progress |= ResolveDecision(givesSupport, world, decisions, depth + 1);
if (givesSupport.Outcome == true) min += 1;
if (givesSupport.Outcome != false) max += 1;
}
@@ -658,7 +672,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (SupportMoveOrder support in decision.Supports)
{
GivesSupport givesSupport = decisions.GivesSupport[support];
- progress |= ResolveDecision(givesSupport, world, decisions);
+ progress |= ResolveDecision(givesSupport, world, decisions, depth + 1);
if (support.Unit.Power != destPower && givesSupport.Outcome == true) min += 1;
if (givesSupport.Outcome != false) max += 1;
}
@@ -676,7 +690,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (SupportMoveOrder support in decision.Supports)
{
GivesSupport givesSupport = decisions.GivesSupport[support];
- progress |= ResolveDecision(givesSupport, world, decisions);
+ progress |= ResolveDecision(givesSupport, world, decisions, depth + 1);
if (givesSupport.Outcome == true) min += 1;
if (givesSupport.Outcome != false) max += 1;
}
@@ -688,7 +702,8 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolveDefendStrength(
DefendStrength decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
@@ -699,7 +714,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (SupportMoveOrder support in decision.Supports)
{
GivesSupport givesSupport = decisions.GivesSupport[support];
- progress |= ResolveDecision(givesSupport, world, decisions);
+ progress |= ResolveDecision(givesSupport, world, decisions, depth + 1);
if (givesSupport.Outcome == true) min += 1;
if (givesSupport.Outcome != false) max += 1;
}
@@ -711,13 +726,14 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolvePreventStrength(
PreventStrength decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
// If there is no path, the prevent strength is zero.
var hasPath = decisions.HasPath[decision.Order];
- progress |= ResolveDecision(hasPath, world, decisions);
+ progress |= ResolveDecision(hasPath, world, decisions, depth + 1);
if (hasPath.Outcome == false)
{
progress |= decision.Update(0, 0);
@@ -741,7 +757,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (SupportMoveOrder support in decision.Supports)
{
GivesSupport givesSupport = decisions.GivesSupport[support];
- progress |= ResolveDecision(givesSupport, world, decisions);
+ progress |= ResolveDecision(givesSupport, world, decisions, depth + 1);
if (givesSupport.Outcome == true) min += 1;
if (givesSupport.Outcome != false) max += 1;
}
@@ -763,13 +779,14 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
private bool ResolveDoesUnitMove(
DoesMove decision,
World world,
- MovementDecisions decisions)
+ MovementDecisions decisions,
+ int depth)
{
bool progress = false;
// Resolve the move's attack strength.
AttackStrength attack = decisions.AttackStrength[decision.Order];
- progress |= ResolveDecision(attack, world, decisions);
+ progress |= ResolveDecision(attack, world, decisions, depth + 1);
// In a head to head battle, the threshold for the attack strength to beat is the opposing
// defend strength. Outside a head to head battle, the threshold is the destination's hold
@@ -777,7 +794,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
NumericAdjudicationDecision defense = decision.OpposingMove != null
? decisions.DefendStrength[decision.OpposingMove]
: decisions.HoldStrength[decision.Order.Point];
- progress |= ResolveDecision(defense, world, decisions);
+ progress |= ResolveDecision(defense, world, decisions, depth + 1);
// If the attack doesn't beat the defense, resolve the move to false.
if (attack.MaxValue <= defense.MinValue)
@@ -791,7 +808,7 @@ public class MovementPhaseAdjudicator : IPhaseAdjudicator
foreach (MoveOrder order in decision.Competing)
{
PreventStrength prevent = decisions.PreventStrength[order];
- progress |= ResolveDecision(prevent, world, decisions);
+ progress |= ResolveDecision(prevent, world, decisions, depth + 1);
// If attack doesn't beat the prevent, resolve the move to false.
if (attack.MaxValue <= prevent.MinValue)
{