diff --git a/MultiversalDiplomacy/Model/RetreatingUnit.cs b/MultiversalDiplomacy/Model/RetreatingUnit.cs
new file mode 100644
index 0000000..8e3d221
--- /dev/null
+++ b/MultiversalDiplomacy/Model/RetreatingUnit.cs
@@ -0,0 +1,32 @@
+using System.Collections.ObjectModel;
+
+namespace MultiversalDiplomacy.Model;
+
+///
+/// Represents a unit that was dislodged and must retreat to another province.
+///
+public class RetreatingUnit
+{
+ ///
+ /// The unit that was dislodged.
+ ///
+ public Unit Unit { get; }
+
+ ///
+ /// Locations to which the dislodged unit may retreat. A dislodged unit may not retreat into
+ /// a province contested or held by another unit, nor into the province from which originated
+ /// the dislodging unit.
+ ///
+ public ReadOnlyCollection<(Season season, Location location)> ValidRetreats { get; }
+
+ public RetreatingUnit(Unit unit, List<(Season season, Location location)> validRetreats)
+ {
+ this.Unit = unit;
+ this.ValidRetreats = new(validRetreats);
+ }
+
+ public override string ToString()
+ {
+ return $"{this.Unit} (retreating)";
+ }
+}
diff --git a/MultiversalDiplomacy/Model/World.cs b/MultiversalDiplomacy/Model/World.cs
index febe2f0..88b1f3c 100644
--- a/MultiversalDiplomacy/Model/World.cs
+++ b/MultiversalDiplomacy/Model/World.cs
@@ -27,6 +27,11 @@ public class World
///
public ReadOnlyCollection Units { get; }
+ ///
+ /// All retreating units in the multiverse.
+ ///
+ public ReadOnlyCollection RetreatingUnits { get; }
+
///
/// Immutable game options.
///
@@ -37,12 +42,14 @@ public class World
ReadOnlyCollection powers,
ReadOnlyCollection seasons,
ReadOnlyCollection units,
+ ReadOnlyCollection retreatingUnits,
Options options)
{
this.Provinces = provinces;
this.Powers = powers;
this.Seasons = seasons;
this.Units = units;
+ this.RetreatingUnits = retreatingUnits;
this.Options = options;
}
@@ -55,6 +62,7 @@ public class World
new(powers.ToList()),
new(new List()),
new(new List()),
+ new(new List()),
new Options());
///
@@ -67,7 +75,13 @@ public class World
/// Create a new world with new seasons.
///
public World WithSeasons(IEnumerable seasons)
- => new World(this.Provinces, this.Powers, new(seasons.ToList()), this.Units, this.Options);
+ => new World(
+ this.Provinces,
+ this.Powers,
+ new(seasons.ToList()),
+ this.Units,
+ this.RetreatingUnits,
+ this.Options);
///
/// Create a new world with an initial season.
@@ -79,7 +93,13 @@ public class World
/// Create a new world with new units.
///
public World WithUnits(IEnumerable units)
- => new World(this.Provinces, this.Powers, this.Seasons, new(units.ToList()), this.Options);
+ => new World(
+ this.Provinces,
+ this.Powers,
+ this.Seasons,
+ new(units.ToList()),
+ this.RetreatingUnits,
+ this.Options);
///
/// Create a new world with new units created from unit specs. Units specs are in the format
@@ -140,6 +160,15 @@ public class World
);
}
+ public World WithRetreats(IEnumerable retreatingUnits)
+ => new World(
+ this.Provinces,
+ this.Powers,
+ this.Seasons,
+ this.Units,
+ new(retreatingUnits.ToList()),
+ this.Options);
+
///
/// A standard Diplomacy game setup.
///