diff --git a/MultiversalDiplomacy/Adjudicate/Decision/AdjudicationDecision.cs b/MultiversalDiplomacy/Adjudicate/Decision/AdjudicationDecision.cs
new file mode 100644
index 0000000..2e365e1
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/AdjudicationDecision.cs
@@ -0,0 +1,12 @@
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+///
+/// Base class for adjudication decisions. The decision-based adjudication algorithm is based
+/// on DATC section 5 and "The Math of Adjudication" by Lucas Kruijswijk, respectively found at
+/// http://web.inter.nl.net/users/L.B.Kruijswijk/#5 and
+/// http://uk.diplom.org/pouch/Zine/S2009M/Kruijswijk/DipMath_Chp1.htm
+///
+public abstract class AdjudicationDecision
+{
+ public abstract bool Resolved { get; }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/AttackStrength.cs b/MultiversalDiplomacy/Adjudicate/Decision/AttackStrength.cs
new file mode 100644
index 0000000..ca9dc9d
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/AttackStrength.cs
@@ -0,0 +1,17 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class AttackStrength : NumericAdjudicationDecision
+{
+ public MoveOrder Order { get; }
+ public List Supports { get; }
+ public MoveOrder? OpposingMove { get; }
+
+ public AttackStrength(MoveOrder order, IEnumerable supports, MoveOrder? opposingMove = null)
+ {
+ this.Order = order;
+ this.Supports = supports.ToList();
+ this.OpposingMove = opposingMove;
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/BinaryAdjudicationDecision.cs b/MultiversalDiplomacy/Adjudicate/Decision/BinaryAdjudicationDecision.cs
new file mode 100644
index 0000000..65e6084
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/BinaryAdjudicationDecision.cs
@@ -0,0 +1,24 @@
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public abstract class BinaryAdjudicationDecision : AdjudicationDecision
+{
+ public bool? Outcome { get; private set; } = null;
+
+ public override bool Resolved => this.Outcome != null;
+
+ public bool Update(bool outcome)
+ {
+ if (this.Outcome == null)
+ {
+ this.Outcome = outcome;
+ return true;
+ }
+ if (this.Outcome != outcome)
+ {
+ string name = this.GetType().Name;
+ throw new ArgumentException(
+ $"Cannot reverse adjudication of {name} from {this.Outcome} to {outcome}");
+ }
+ return false;
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/DefendStrength.cs b/MultiversalDiplomacy/Adjudicate/Decision/DefendStrength.cs
new file mode 100644
index 0000000..b51532f
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/DefendStrength.cs
@@ -0,0 +1,15 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class DefendStrength : NumericAdjudicationDecision
+{
+ public MoveOrder Order { get; }
+ public List Supports { get; }
+
+ public DefendStrength(MoveOrder order, IEnumerable supports)
+ {
+ this.Order = order;
+ this.Supports = supports.ToList();
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/DoesMove.cs b/MultiversalDiplomacy/Adjudicate/Decision/DoesMove.cs
new file mode 100644
index 0000000..c093871
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/DoesMove.cs
@@ -0,0 +1,17 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class DoesMove : BinaryAdjudicationDecision
+{
+ public MoveOrder Order { get; }
+ public MoveOrder? OpposingMove { get; }
+ public List Competing { get; }
+
+ public DoesMove(MoveOrder order, MoveOrder? opposingMove, IEnumerable competing)
+ {
+ this.Order = order;
+ this.OpposingMove = opposingMove;
+ this.Competing = competing.ToList();
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/GivesSupport.cs b/MultiversalDiplomacy/Adjudicate/Decision/GivesSupport.cs
new file mode 100644
index 0000000..d0095f5
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/GivesSupport.cs
@@ -0,0 +1,15 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class GivesSupport : BinaryAdjudicationDecision
+{
+ public SupportOrder Order { get; }
+ public List Cuts { get; }
+
+ public GivesSupport(SupportOrder order, IEnumerable cuts)
+ {
+ this.Order = order;
+ this.Cuts = cuts.ToList();
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/HasPath.cs b/MultiversalDiplomacy/Adjudicate/Decision/HasPath.cs
new file mode 100644
index 0000000..71f49fe
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/HasPath.cs
@@ -0,0 +1,13 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class HasPath : BinaryAdjudicationDecision
+{
+ public MoveOrder Order { get; }
+
+ public HasPath(MoveOrder order)
+ {
+ this.Order = order;
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/HoldStrength.cs b/MultiversalDiplomacy/Adjudicate/Decision/HoldStrength.cs
new file mode 100644
index 0000000..35d1d46
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/HoldStrength.cs
@@ -0,0 +1,18 @@
+using MultiversalDiplomacy.Model;
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class HoldStrength : NumericAdjudicationDecision
+{
+ public Province Province { get; }
+ public UnitOrder? Order { get; }
+ public List Supports { get; }
+
+ public HoldStrength(Province province, UnitOrder? order = null)
+ {
+ this.Province = province;
+ this.Order = order;
+ this.Supports = new();
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/IsDislodged.cs b/MultiversalDiplomacy/Adjudicate/Decision/IsDislodged.cs
new file mode 100644
index 0000000..f5cdf62
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/IsDislodged.cs
@@ -0,0 +1,15 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class IsDislodged : BinaryAdjudicationDecision
+{
+ public UnitOrder Order { get; }
+ public List Incoming { get; }
+
+ public IsDislodged(UnitOrder order, IEnumerable incoming)
+ {
+ this.Order = order;
+ this.Incoming = incoming.ToList();
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/NumericAdjudicationDecision.cs b/MultiversalDiplomacy/Adjudicate/Decision/NumericAdjudicationDecision.cs
new file mode 100644
index 0000000..05e0681
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/NumericAdjudicationDecision.cs
@@ -0,0 +1,24 @@
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public abstract class NumericAdjudicationDecision : AdjudicationDecision
+{
+ public int MinValue { get; private set; } = 0;
+ public int MaxValue { get; private set; } = 99;
+
+ public override bool Resolved => this.MinValue == this.MaxValue;
+
+ public bool Update(int min, int max)
+ {
+ if (min < this.MinValue || max > this.MaxValue)
+ {
+ string name = this.GetType().Name;
+ throw new ArgumentException(
+ $"Cannot reverse adjudication of {name} from ({this.MinValue},{this.MaxValue})"
+ + $" to ({min},{max})");
+ }
+ bool updated = this.MinValue != min || this.MaxValue != max;
+ this.MinValue = min;
+ this.MaxValue = max;
+ return updated;
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/Decision/PreventStrength.cs b/MultiversalDiplomacy/Adjudicate/Decision/PreventStrength.cs
new file mode 100644
index 0000000..4a5ed2e
--- /dev/null
+++ b/MultiversalDiplomacy/Adjudicate/Decision/PreventStrength.cs
@@ -0,0 +1,17 @@
+using MultiversalDiplomacy.Orders;
+
+namespace MultiversalDiplomacy.Adjudicate.Decision;
+
+public class PreventStrength : NumericAdjudicationDecision
+{
+ public MoveOrder Order { get; }
+ public List Supports { get; }
+ public MoveOrder? OpposingMove { get; }
+
+ public PreventStrength(MoveOrder order, IEnumerable supports, MoveOrder? opposingMove = null)
+ {
+ this.Order = order;
+ this.Supports = supports.ToList();
+ this.OpposingMove = opposingMove;
+ }
+}
diff --git a/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs b/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs
index 4d5411a..0799d0a 100644
--- a/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs
+++ b/MultiversalDiplomacy/Adjudicate/MovementPhaseAdjudicator.cs
@@ -1,3 +1,4 @@
+using MultiversalDiplomacy.Adjudicate.Decision;
using MultiversalDiplomacy.Model;
using MultiversalDiplomacy.Orders;
@@ -8,165 +9,6 @@ namespace MultiversalDiplomacy.Adjudicate;
///
public class MovementPhaseAdjudicator : IPhaseAdjudicator
{
- ///
- /// Base class for adjudication decisions. The decision-based adjudication algorithm is based
- /// on DATC section 5 and "The Math of Adjudication" by Lucas Kruijswijk, respectively found at
- /// http://web.inter.nl.net/users/L.B.Kruijswijk/#5 and
- /// http://uk.diplom.org/pouch/Zine/S2009M/Kruijswijk/DipMath_Chp1.htm
- ///
- private abstract class AdjudicationDecision
- {
- public abstract bool Resolved { get; }
- }
-
- private abstract class BinaryAdjudicationDecision : AdjudicationDecision
- {
- public bool? Outcome { get; private set; } = null;
-
- public override bool Resolved => this.Outcome != null;
-
- public bool Update(bool outcome)
- {
- if (this.Outcome == null)
- {
- this.Outcome = outcome;
- return true;
- }
- if (this.Outcome != outcome)
- {
- string name = this.GetType().Name;
- throw new ArgumentException(
- $"Cannot reverse adjudication of {name} from {this.Outcome} to {outcome}");
- }
- return false;
- }
- }
-
- private abstract class NumericAdjudicationDecision : AdjudicationDecision
- {
- public int MinValue { get; private set; } = 0;
- public int MaxValue { get; private set; } = 99;
-
- public override bool Resolved => this.MinValue == this.MaxValue;
-
- public bool Update(int min, int max)
- {
- if (min < this.MinValue || max > this.MaxValue)
- {
- string name = this.GetType().Name;
- throw new ArgumentException(
- $"Cannot reverse adjudication of {name} from ({this.MinValue},{this.MaxValue})"
- + $" to ({min},{max})");
- }
- bool updated = this.MinValue != min || this.MaxValue != max;
- this.MinValue = min;
- this.MaxValue = max;
- return updated;
- }
- }
-
- private class IsDislodged : BinaryAdjudicationDecision
- {
- public UnitOrder Order { get; }
- public List Incoming { get; }
-
- public IsDislodged(UnitOrder order, IEnumerable incoming)
- {
- this.Order = order;
- this.Incoming = incoming.ToList();
- }
- }
-
- private class HasPath : BinaryAdjudicationDecision
- {
- public MoveOrder Order { get; }
-
- public HasPath(MoveOrder order)
- {
- this.Order = order;
- }
- }
-
- private class GivesSupport : BinaryAdjudicationDecision
- {
- public SupportOrder Order { get; }
- public List Cuts { get; }
-
- public GivesSupport(SupportOrder order, IEnumerable cuts)
- {
- this.Order = order;
- this.Cuts = cuts.ToList();
- }
- }
-
- private class HoldStrength : NumericAdjudicationDecision
- {
- public Province Province { get; }
- public UnitOrder? Order { get; }
- public List Supports { get; }
-
- public HoldStrength(Province province, UnitOrder? order = null)
- {
- this.Province = province;
- this.Order = order;
- this.Supports = new();
- }
- }
-
- private class AttackStrength : NumericAdjudicationDecision
- {
- public MoveOrder Order { get; }
- public List Supports { get; }
- public MoveOrder? OpposingMove { get; }
-
- public AttackStrength(MoveOrder order, IEnumerable supports, MoveOrder? opposingMove = null)
- {
- this.Order = order;
- this.Supports = supports.ToList();
- this.OpposingMove = opposingMove;
- }
- }
-
- private class DefendStrength : NumericAdjudicationDecision
- {
- public MoveOrder Order { get; }
- public List Supports { get; }
-
- public DefendStrength(MoveOrder order, IEnumerable supports)
- {
- this.Order = order;
- this.Supports = supports.ToList();
- }
- }
-
- private class PreventStrength : NumericAdjudicationDecision
- {
- public MoveOrder Order { get; }
- public List Supports { get; }
- public MoveOrder? OpposingMove { get; }
-
- public PreventStrength(MoveOrder order, IEnumerable supports, MoveOrder? opposingMove = null)
- {
- this.Order = order;
- this.Supports = supports.ToList();
- this.OpposingMove = opposingMove;
- }
- }
-
- private class DoesMove : BinaryAdjudicationDecision
- {
- public MoveOrder Order { get; }
- public MoveOrder? OpposingMove { get; }
- public List Competing { get; }
-
- public DoesMove(MoveOrder order, MoveOrder? opposingMove, IEnumerable competing)
- {
- this.Order = order;
- this.OpposingMove = opposingMove;
- this.Competing = competing.ToList();
- }
- }
-
private class Decisions
{
public Dictionary IsDislodged { get; }