Refactor map definitions into World
This commit is contained in:
parent
8a7e90b949
commit
18c5435c96
@ -1,35 +0,0 @@
|
||||
using MultiversalDiplomacy.Model;
|
||||
|
||||
namespace MultiversalDiplomacy.Map;
|
||||
|
||||
/// <summary>
|
||||
/// A collection of provinces. Provides shortcut functions for referencing provinces.
|
||||
/// </summary>
|
||||
public abstract class Map
|
||||
{
|
||||
public abstract IEnumerable<Province> Provinces { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sole army-accessible location of a province.
|
||||
/// </summary>
|
||||
public Location Land(string provinceName)
|
||||
=> Provinces
|
||||
.Single(p => p.Name == provinceName || p.Abbreviations.Contains(provinceName))
|
||||
.Locations.Single(l => l.Type == LocationType.Land);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sole fleet-accessible location of a province.
|
||||
/// </summary>
|
||||
public Location Water(string provinceName)
|
||||
=> Provinces
|
||||
.Single(p => p.Name == provinceName || p.Abbreviations.Contains(provinceName))
|
||||
.Locations.Single(l => l.Type == LocationType.Water);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the specified fleet-accessible location of a province with distinct coasts.
|
||||
/// </summary>
|
||||
public Location Coast(string provinceName, string coastName)
|
||||
=> Provinces
|
||||
.Single(p => p.Name == provinceName || p.Abbreviations.Contains(provinceName))
|
||||
.Locations.Single(l => l.Name == coastName || l.Abbreviation == coastName);
|
||||
}
|
@ -1,311 +0,0 @@
|
||||
using System.Reflection;
|
||||
|
||||
using MultiversalDiplomacy.Model;
|
||||
|
||||
namespace MultiversalDiplomacy.Map;
|
||||
|
||||
/// <summary>
|
||||
/// The standard Diplomacy map.
|
||||
/// </summary>
|
||||
public class StandardMap : Map
|
||||
{
|
||||
public override IEnumerable<Province> Provinces { get; }
|
||||
|
||||
public static StandardMap Instance { get; } = new StandardMap();
|
||||
|
||||
private StandardMap()
|
||||
{
|
||||
this.Provinces = new List<Province>()
|
||||
{
|
||||
Province.Empty("North Africa", "NAF")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Tunis", "TUN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Bohemia", "BOH")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Budapest", "BUD")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Galacia", "GAL")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Trieste", "TRI")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Tyrolia", "TYR")
|
||||
.AddLandLocation(),
|
||||
Province.Time("Vienna", "VIE")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Albania", "ALB")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Bulgaria", "BUL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation("east coast", "ec")
|
||||
.AddCoastLocation("south coast", "sc"),
|
||||
Province.Supply("Greece", "GRE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Rumania", "RUM", "RMA")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Serbia", "SER")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Clyde", "CLY")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Edinburgh", "EDI")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Liverpool", "LVP", "LPL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("London", "LON")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Wales", "WAL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Yorkshire", "YOR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Brest", "BRE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Burgundy", "BUR")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Gascony", "GAS")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Marseilles", "MAR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Paris", "PAR")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Picardy", "PIC")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Berlin", "BER")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Kiel", "KIE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Munich", "MUN")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Prussia", "PRU")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Ruhr", "RUH", "RHR")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Silesia", "SIL")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Spain", "SPA")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation("north coast", "nc")
|
||||
.AddCoastLocation("south coast", "sc"),
|
||||
Province.Supply("Portugal", "POR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Apulia", "APU")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Naples", "NAP")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Piedmont", "PIE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Rome", "ROM", "RME")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Tuscany", "TUS")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Venice", "VEN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Belgium", "BEL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Holland", "HOL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Finland", "FIN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Livonia", "LVN", "LVA")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Moscow", "MOS")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Sevastopol", "SEV")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Saint Petersburg", "STP")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation("north coast", "nc")
|
||||
.AddCoastLocation("west coast", "wc"),
|
||||
Province.Empty("Ukraine", "UKR")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Warsaw", "WAR")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Denmark", "DEN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Norway", "NWY")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Sweden", "SWE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Ankara", "ANK")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Armenia", "ARM")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Constantinople", "CON")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Smyrna", "SMY")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Syria", "SYR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Barents Sea", "BAR")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("English Channel", "ENC", "ECH")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Heligoland Bight", "HEL", "HGB")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Irish Sea", "IRS", "IRI")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Mid-Atlantic Ocean", "MAO", "MID")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("North Atlantic Ocean", "NAO", "NAT")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("North Sea", "NTH", "NTS")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Norwegian Sea", "NWS", "NWG")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Skagerrak", "SKA", "SKG")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Baltic Sea", "BAL")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Guld of Bothnia", "GOB", "BOT")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Adriatic Sea", "ADS", "ADR")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Aegean Sea", "AEG")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Black Sea", "BLA")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Eastern Mediterranean Sea", "EMS", "EAS")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Gulf of Lyons", "GOL", "LYO")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Ionian Sea", "IOS", "ION", "INS")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Tyrrhenian Sea", "TYS", "TYN")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Western Mediterranean Sea", "WMS", "WES")
|
||||
.AddOceanLocation(),
|
||||
};
|
||||
|
||||
Land("NAF").AddBorder(Land("TUN"));
|
||||
Water("NAF").AddBorder(Water("MAO"));
|
||||
Water("NAF").AddBorder(Water("WES"));
|
||||
Water("NAF").AddBorder(Water("TUN"));
|
||||
|
||||
Land("TUN").AddBorder(Land("NAF"));
|
||||
Water("TUN").AddBorder(Water("NAF"));
|
||||
Water("TUN").AddBorder(Water("WES"));
|
||||
Water("TUN").AddBorder(Water("TYS"));
|
||||
Water("TUN").AddBorder(Water("ION"));
|
||||
|
||||
Land("BOH").AddBorder(Land("MUN"));
|
||||
Land("BOH").AddBorder(Land("SIL"));
|
||||
Land("BOH").AddBorder(Land("GAL"));
|
||||
Land("BOH").AddBorder(Land("VIE"));
|
||||
Land("BOH").AddBorder(Land("TYR"));
|
||||
|
||||
Land("BUD").AddBorder(Land("VIE"));
|
||||
Land("BUD").AddBorder(Land("GAL"));
|
||||
Land("BUD").AddBorder(Land("RUM"));
|
||||
Land("BUD").AddBorder(Land("SER"));
|
||||
Land("BUD").AddBorder(Land("TRI"));
|
||||
|
||||
Land("GAL").AddBorder(Land("BOH"));
|
||||
Land("GAL").AddBorder(Land("SIL"));
|
||||
Land("GAL").AddBorder(Land("WAR"));
|
||||
Land("GAL").AddBorder(Land("UKR"));
|
||||
Land("GAL").AddBorder(Land("RUM"));
|
||||
Land("GAL").AddBorder(Land("BUD"));
|
||||
Land("GAL").AddBorder(Land("VIE"));
|
||||
|
||||
Land("TRI").AddBorder(Land("VEN"));
|
||||
Land("TRI").AddBorder(Land("TYR"));
|
||||
Land("TRI").AddBorder(Land("VIE"));
|
||||
Land("TRI").AddBorder(Land("BUD"));
|
||||
Land("TRI").AddBorder(Land("SER"));
|
||||
Land("TRI").AddBorder(Land("ALB"));
|
||||
Water("TRI").AddBorder(Water("ALB"));
|
||||
Water("TRI").AddBorder(Water("ADR"));
|
||||
Water("TRI").AddBorder(Water("VEN"));
|
||||
|
||||
Land("TYR").AddBorder(Land("MUN"));
|
||||
Land("TYR").AddBorder(Land("BOH"));
|
||||
Land("TYR").AddBorder(Land("VIE"));
|
||||
Land("TYR").AddBorder(Land("TRI"));
|
||||
Land("TYR").AddBorder(Land("VEN"));
|
||||
Land("TYR").AddBorder(Land("PIE"));
|
||||
|
||||
Land("VIE").AddBorder(Land("TYR"));
|
||||
Land("VIE").AddBorder(Land("BOH"));
|
||||
Land("VIE").AddBorder(Land("GAL"));
|
||||
Land("VIE").AddBorder(Land("BUD"));
|
||||
Land("VIE").AddBorder(Land("TRI"));
|
||||
|
||||
Land("ALB").AddBorder(Land("TRI"));
|
||||
Land("ALB").AddBorder(Land("SER"));
|
||||
Land("ALB").AddBorder(Land("GRE"));
|
||||
Water("ALB").AddBorder(Water("TRI"));
|
||||
Water("ALB").AddBorder(Water("ADR"));
|
||||
Water("ALB").AddBorder(Water("ION"));
|
||||
Water("ALB").AddBorder(Water("GRE"));
|
||||
|
||||
Land("BUL").AddBorder(Land("GRE"));
|
||||
Land("BUL").AddBorder(Land("SER"));
|
||||
Land("BUL").AddBorder(Land("RUM"));
|
||||
Land("BUL").AddBorder(Land("CON"));
|
||||
Coast("BUL", "ec").AddBorder(Water("BLA"));
|
||||
Coast("BUL", "ec").AddBorder(Water("CON"));
|
||||
Coast("BUL", "sc").AddBorder(Water("CON"));
|
||||
Coast("BUL", "sc").AddBorder(Water("AEG"));
|
||||
Coast("BUL", "sc").AddBorder(Water("GRE"));
|
||||
|
||||
Land("GRE").AddBorder(Land("ALB"));
|
||||
Land("GRE").AddBorder(Land("SER"));
|
||||
Land("GRE").AddBorder(Land("BUL"));
|
||||
Water("GRE").AddBorder(Water("ALB"));
|
||||
Water("GRE").AddBorder(Water("ION"));
|
||||
Water("GRE").AddBorder(Water("AEG"));
|
||||
Water("GRE").AddBorder(Coast("BUL", "sc"));
|
||||
|
||||
// TODO
|
||||
|
||||
Water("IOS").AddBorder(Water("TUN"));
|
||||
Water("IOS").AddBorder(Water("TYS"));
|
||||
Water("IOS").AddBorder(Water("NAP"));
|
||||
Water("IOS").AddBorder(Water("APU"));
|
||||
Water("IOS").AddBorder(Water("ADR"));
|
||||
Water("IOS").AddBorder(Water("ALB"));
|
||||
Water("IOS").AddBorder(Water("GRE"));
|
||||
Water("IOS").AddBorder(Water("AEG"));
|
||||
|
||||
// TODO
|
||||
}
|
||||
}
|
8
MultiversalDiplomacy/Model/Options.cs
Normal file
8
MultiversalDiplomacy/Model/Options.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace MultiversalDiplomacy.Model;
|
||||
|
||||
/// <summary>
|
||||
/// Object representing immutable configuration options about the game.
|
||||
/// </summary>
|
||||
public class Options
|
||||
{
|
||||
}
|
@ -25,15 +25,512 @@ public class World
|
||||
/// </summary>
|
||||
public IEnumerable<Unit> Units { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Immutable game options.
|
||||
/// </summary>
|
||||
public Options Options { get; }
|
||||
|
||||
public World(
|
||||
IEnumerable<Province> provinces,
|
||||
IEnumerable<Power> powers,
|
||||
IEnumerable<Season> seasons,
|
||||
IEnumerable<Unit> units)
|
||||
IEnumerable<Unit> units,
|
||||
Options options)
|
||||
{
|
||||
this.Provinces = provinces;
|
||||
this.Powers = powers;
|
||||
this.Seasons = seasons;
|
||||
this.Units = units;
|
||||
this.Options = options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world with no map, powers, or units, and a root season.
|
||||
/// </summary>
|
||||
public static World Empty => new World(
|
||||
new List<Province>(),
|
||||
new List<Power>(),
|
||||
new List<Season> { Season.MakeRoot() },
|
||||
new List<Unit>(),
|
||||
new Options());
|
||||
|
||||
/// <summary>
|
||||
/// Create a world with a standard map, powers, and initial unit placements.
|
||||
/// </summary>
|
||||
public static World Standard => Empty
|
||||
.WithStandardMap()
|
||||
.WithStandardPowers()
|
||||
.WithStandardUnits();
|
||||
|
||||
/// <summary>
|
||||
/// Get a province by name. Throws if the province is not found.
|
||||
/// </summary>
|
||||
private Province GetProvince(string provinceName)
|
||||
{
|
||||
string provinceNameUpper = provinceName.ToUpperInvariant();
|
||||
Province? foundProvince = this.Provinces.FirstOrDefault(
|
||||
p => p != null &&
|
||||
(p.Name.ToUpperInvariant() == provinceNameUpper
|
||||
|| p.Abbreviations.Any(a => a.ToUpperInvariant() == provinceNameUpper)),
|
||||
null);
|
||||
if (foundProvince == null) throw new ArgumentOutOfRangeException(
|
||||
$"Province {provinceName} not found");
|
||||
return foundProvince;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the location in a province matching a predicate. Throws if there is not exactly one
|
||||
/// such location.
|
||||
/// </summary>
|
||||
private Location GetLocation(string provinceName, Func<Location, bool> predicate)
|
||||
{
|
||||
Location? foundLocation = GetProvince(provinceName).Locations.SingleOrDefault(
|
||||
l => l != null && predicate(l), null);
|
||||
if (foundLocation == null) throw new ArgumentException(
|
||||
$"No such location in {provinceName}");
|
||||
return foundLocation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the sole land location of a province.
|
||||
/// </summary>
|
||||
public Location GetLand(string provinceName)
|
||||
=> GetLocation(provinceName, l => l.Type == LocationType.Land);
|
||||
|
||||
/// <summary>
|
||||
/// Get the sole water location of a province, optionally specifying a named coast.
|
||||
/// </summary>
|
||||
public Location GetWater(string provinceName, string? coastName = null)
|
||||
=> coastName == null
|
||||
? GetLocation(provinceName, l => l.Type == LocationType.Water)
|
||||
: GetLocation(provinceName, l => l.Name == coastName || l.Abbreviation == coastName);
|
||||
|
||||
/// <summary>
|
||||
/// Get a power by name. Throws if the power is not found.
|
||||
/// </summary>
|
||||
public Power GetPower(string powerName)
|
||||
{
|
||||
Power? foundPower = this.Powers.FirstOrDefault(
|
||||
p =>
|
||||
p != null
|
||||
&& (p.Name == powerName || p.Name.StartsWith(powerName)),
|
||||
null);
|
||||
if (foundPower == null) throw new ArgumentOutOfRangeException(
|
||||
$"Power {powerName} not found");
|
||||
return foundPower;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new provinces.
|
||||
/// </summary>
|
||||
public World WithMap(IEnumerable<Province> provinces)
|
||||
{
|
||||
if (this.Units.Any()) throw new InvalidOperationException(
|
||||
"Provinces cannot be changed once units have been placed on the map");
|
||||
return new World(provinces, this.Powers, this.Seasons, this.Units, this.Options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with the standard Diplomacy provinces.
|
||||
/// </summary>
|
||||
public World WithStandardMap()
|
||||
{
|
||||
// Define the provinces of the standard world map.
|
||||
List<Province> standardProvinces = new List<Province>
|
||||
{
|
||||
Province.Empty("North Africa", "NAF")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Tunis", "TUN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Bohemia", "BOH")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Budapest", "BUD")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Galacia", "GAL")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Trieste", "TRI")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Tyrolia", "TYR")
|
||||
.AddLandLocation(),
|
||||
Province.Time("Vienna", "VIE")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Albania", "ALB")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Bulgaria", "BUL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation("east coast", "ec")
|
||||
.AddCoastLocation("south coast", "sc"),
|
||||
Province.Supply("Greece", "GRE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Rumania", "RUM", "RMA")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Serbia", "SER")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Clyde", "CLY")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Edinburgh", "EDI")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Liverpool", "LVP", "LPL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("London", "LON")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Wales", "WAL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Yorkshire", "YOR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Brest", "BRE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Burgundy", "BUR")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Gascony", "GAS")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Marseilles", "MAR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Paris", "PAR")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Picardy", "PIC")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Berlin", "BER")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Kiel", "KIE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Munich", "MUN")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Prussia", "PRU")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Ruhr", "RUH", "RHR")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Silesia", "SIL")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Spain", "SPA")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation("north coast", "nc")
|
||||
.AddCoastLocation("south coast", "sc"),
|
||||
Province.Supply("Portugal", "POR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Apulia", "APU")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Naples", "NAP")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Piedmont", "PIE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Rome", "ROM", "RME")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Tuscany", "TUS")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Venice", "VEN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Belgium", "BEL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Holland", "HOL")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Finland", "FIN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Livonia", "LVN", "LVA")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Moscow", "MOS")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Sevastopol", "SEV")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Saint Petersburg", "STP")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation("north coast", "nc")
|
||||
.AddCoastLocation("west coast", "wc"),
|
||||
Province.Empty("Ukraine", "UKR")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Warsaw", "WAR")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Denmark", "DEN")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Norway", "NWY")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Sweden", "SWE")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Ankara", "ANK")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Armenia", "ARM")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Time("Constantinople", "CON")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Supply("Smyrna", "SMY")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Syria", "SYR")
|
||||
.AddLandLocation()
|
||||
.AddCoastLocation(),
|
||||
Province.Empty("Barents Sea", "BAR")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("English Channel", "ENC", "ECH")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Heligoland Bight", "HEL", "HGB")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Irish Sea", "IRS", "IRI")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Mid-Atlantic Ocean", "MAO", "MID")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("North Atlantic Ocean", "NAO", "NAT")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("North Sea", "NTH", "NTS")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Norwegian Sea", "NWS", "NWG")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Skagerrak", "SKA", "SKG")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Baltic Sea", "BAL")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Guld of Bothnia", "GOB", "BOT")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Adriatic Sea", "ADS", "ADR")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Aegean Sea", "AEG")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Black Sea", "BLA")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Eastern Mediterranean Sea", "EMS", "EAS")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Gulf of Lyons", "GOL", "LYO")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Ionian Sea", "IOS", "ION", "INS")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Tyrrhenian Sea", "TYS", "TYN")
|
||||
.AddOceanLocation(),
|
||||
Province.Empty("Western Mediterranean Sea", "WMS", "WES")
|
||||
.AddOceanLocation(),
|
||||
};
|
||||
|
||||
// Declare some helpers for border definitions
|
||||
Location Land(string provinceName) => standardProvinces
|
||||
.Single(p => p.Name == provinceName || p.Abbreviations.Contains(provinceName))
|
||||
.Locations.Single(l => l.Type == LocationType.Land);
|
||||
Location Water(string provinceName) => standardProvinces
|
||||
.Single(p => p.Name == provinceName || p.Abbreviations.Contains(provinceName))
|
||||
.Locations.Single(l => l.Type == LocationType.Water);
|
||||
Location Coast(string provinceName, string coastName) => standardProvinces
|
||||
.Single(p => p.Name == provinceName || p.Abbreviations.Contains(provinceName))
|
||||
.Locations.Single(l => l.Name == coastName || l.Abbreviation == coastName);
|
||||
|
||||
Land("NAF").AddBorder(Land("TUN"));
|
||||
Water("NAF").AddBorder(Water("MAO"));
|
||||
Water("NAF").AddBorder(Water("WES"));
|
||||
Water("NAF").AddBorder(Water("TUN"));
|
||||
|
||||
Land("TUN").AddBorder(Land("NAF"));
|
||||
Water("TUN").AddBorder(Water("NAF"));
|
||||
Water("TUN").AddBorder(Water("WES"));
|
||||
Water("TUN").AddBorder(Water("TYS"));
|
||||
Water("TUN").AddBorder(Water("ION"));
|
||||
|
||||
Land("BOH").AddBorder(Land("MUN"));
|
||||
Land("BOH").AddBorder(Land("SIL"));
|
||||
Land("BOH").AddBorder(Land("GAL"));
|
||||
Land("BOH").AddBorder(Land("VIE"));
|
||||
Land("BOH").AddBorder(Land("TYR"));
|
||||
|
||||
Land("BUD").AddBorder(Land("VIE"));
|
||||
Land("BUD").AddBorder(Land("GAL"));
|
||||
Land("BUD").AddBorder(Land("RUM"));
|
||||
Land("BUD").AddBorder(Land("SER"));
|
||||
Land("BUD").AddBorder(Land("TRI"));
|
||||
|
||||
Land("GAL").AddBorder(Land("BOH"));
|
||||
Land("GAL").AddBorder(Land("SIL"));
|
||||
Land("GAL").AddBorder(Land("WAR"));
|
||||
Land("GAL").AddBorder(Land("UKR"));
|
||||
Land("GAL").AddBorder(Land("RUM"));
|
||||
Land("GAL").AddBorder(Land("BUD"));
|
||||
Land("GAL").AddBorder(Land("VIE"));
|
||||
|
||||
Land("TRI").AddBorder(Land("VEN"));
|
||||
Land("TRI").AddBorder(Land("TYR"));
|
||||
Land("TRI").AddBorder(Land("VIE"));
|
||||
Land("TRI").AddBorder(Land("BUD"));
|
||||
Land("TRI").AddBorder(Land("SER"));
|
||||
Land("TRI").AddBorder(Land("ALB"));
|
||||
Water("TRI").AddBorder(Water("ALB"));
|
||||
Water("TRI").AddBorder(Water("ADR"));
|
||||
Water("TRI").AddBorder(Water("VEN"));
|
||||
|
||||
Land("TYR").AddBorder(Land("MUN"));
|
||||
Land("TYR").AddBorder(Land("BOH"));
|
||||
Land("TYR").AddBorder(Land("VIE"));
|
||||
Land("TYR").AddBorder(Land("TRI"));
|
||||
Land("TYR").AddBorder(Land("VEN"));
|
||||
Land("TYR").AddBorder(Land("PIE"));
|
||||
|
||||
Land("VIE").AddBorder(Land("TYR"));
|
||||
Land("VIE").AddBorder(Land("BOH"));
|
||||
Land("VIE").AddBorder(Land("GAL"));
|
||||
Land("VIE").AddBorder(Land("BUD"));
|
||||
Land("VIE").AddBorder(Land("TRI"));
|
||||
|
||||
Land("ALB").AddBorder(Land("TRI"));
|
||||
Land("ALB").AddBorder(Land("SER"));
|
||||
Land("ALB").AddBorder(Land("GRE"));
|
||||
Water("ALB").AddBorder(Water("TRI"));
|
||||
Water("ALB").AddBorder(Water("ADR"));
|
||||
Water("ALB").AddBorder(Water("ION"));
|
||||
Water("ALB").AddBorder(Water("GRE"));
|
||||
|
||||
Land("BUL").AddBorder(Land("GRE"));
|
||||
Land("BUL").AddBorder(Land("SER"));
|
||||
Land("BUL").AddBorder(Land("RUM"));
|
||||
Land("BUL").AddBorder(Land("CON"));
|
||||
Coast("BUL", "ec").AddBorder(Water("BLA"));
|
||||
Coast("BUL", "ec").AddBorder(Water("CON"));
|
||||
Coast("BUL", "sc").AddBorder(Water("CON"));
|
||||
Coast("BUL", "sc").AddBorder(Water("AEG"));
|
||||
Coast("BUL", "sc").AddBorder(Water("GRE"));
|
||||
|
||||
Land("GRE").AddBorder(Land("ALB"));
|
||||
Land("GRE").AddBorder(Land("SER"));
|
||||
Land("GRE").AddBorder(Land("BUL"));
|
||||
Water("GRE").AddBorder(Water("ALB"));
|
||||
Water("GRE").AddBorder(Water("ION"));
|
||||
Water("GRE").AddBorder(Water("AEG"));
|
||||
Water("GRE").AddBorder(Coast("BUL", "sc"));
|
||||
|
||||
// TODO
|
||||
|
||||
Water("IOS").AddBorder(Water("TUN"));
|
||||
Water("IOS").AddBorder(Water("TYS"));
|
||||
Water("IOS").AddBorder(Water("NAP"));
|
||||
Water("IOS").AddBorder(Water("APU"));
|
||||
Water("IOS").AddBorder(Water("ADR"));
|
||||
Water("IOS").AddBorder(Water("ALB"));
|
||||
Water("IOS").AddBorder(Water("GRE"));
|
||||
Water("IOS").AddBorder(Water("AEG"));
|
||||
|
||||
// TODO
|
||||
|
||||
return this.WithMap(standardProvinces);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new powers.
|
||||
/// </summary>
|
||||
public World WithPowers(IEnumerable<Power> powers)
|
||||
=> new World(this.Provinces, powers, this.Seasons, this.Units, this.Options);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new powers created with the given names.
|
||||
/// </summary>
|
||||
public World WithPowers(IEnumerable<string> powerNames)
|
||||
=> WithPowers(powerNames.Select(name => new Model.Power(name)));
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new powers created with the given names.
|
||||
/// </summary>
|
||||
public World WithPowers(params string[] powerNames)
|
||||
=> WithPowers(powerNames.AsEnumerable());
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with the standard Diplomacy powers.
|
||||
/// </summary>
|
||||
public World WithStandardPowers()
|
||||
=> WithPowers("Austria", "England", "France", "Germany", "Italy", "Russia", "Turkey");
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new units created from unit specs. Units specs are
|
||||
/// in the format "<power> <A/F> <province> [<coast>]". If the province or coast name has a
|
||||
/// space in it, the abbreviation should be used.
|
||||
/// </summary>
|
||||
public World WithUnits(IEnumerable<string> unitSpec)
|
||||
{
|
||||
IEnumerable<Unit> units = unitSpec.Select(spec =>
|
||||
{
|
||||
string[] splits = spec.Split(' ', 4);
|
||||
Power power = this.GetPower(splits[0]);
|
||||
UnitType type = splits[1] switch
|
||||
{
|
||||
"A" => UnitType.Army,
|
||||
"F" => UnitType.Fleet,
|
||||
_ => throw new ArgumentOutOfRangeException($"Unknown unit type {splits[1]}")
|
||||
};
|
||||
Location location = type == UnitType.Army
|
||||
? this.GetLand(splits[2])
|
||||
: splits.Length == 3
|
||||
? this.GetWater(splits[2])
|
||||
: this.GetWater(splits[2], splits[3]);
|
||||
Unit unit = Unit.Build(location, this.Seasons.First(), power, type);
|
||||
return unit;
|
||||
});
|
||||
return new World(this.Provinces, this.Powers, this.Seasons, units, this.Options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new units created from unit specs. Units specs are
|
||||
/// in the format "<power> <A/F> <province> [<coast>]".
|
||||
/// </summary>
|
||||
public World WithUnits(params string[] unitSpec)
|
||||
=> this.WithUnits(unitSpec.AsEnumerable());
|
||||
|
||||
/// <summary>
|
||||
/// Create a new world from this one with new units created according to the standard Diplomacy
|
||||
/// initial unit deployments.
|
||||
/// </summary>
|
||||
public World WithStandardUnits()
|
||||
{
|
||||
return this.WithUnits(
|
||||
"Austria A Bud",
|
||||
"Austria A Vir",
|
||||
"Austria F Tri",
|
||||
"England A Lvp",
|
||||
"England F Edi",
|
||||
"England F Lon",
|
||||
"France A Mar",
|
||||
"France A Par",
|
||||
"France F Bre",
|
||||
"Germany A Ber",
|
||||
"Germany A Mun",
|
||||
"Germany F Kie",
|
||||
"Italy A Rom",
|
||||
"Italy A Ven",
|
||||
"Italy F Nap",
|
||||
"Russia A Mos",
|
||||
"Russia A War",
|
||||
"Russia F Sev",
|
||||
"Russia F Stp wc",
|
||||
"Turkey A Con",
|
||||
"Turkey A Smy",
|
||||
"Turkey F Ank"
|
||||
);
|
||||
}
|
||||
}
|
@ -11,14 +11,16 @@ public class AdjudicatorTests
|
||||
[Test]
|
||||
public void OrderValidationTest()
|
||||
{
|
||||
IPhaseAdjudicator rubberStamp = new TestAdjudicator(orders => {
|
||||
return orders.Select(o => o.Validate(ValidationReason.Valid));
|
||||
IPhaseAdjudicator rubberStamp = new TestAdjudicator((world, orders) =>
|
||||
{
|
||||
return orders.Select(o => o.Validate(ValidationReason.Valid)).ToList();
|
||||
});
|
||||
Power power = new Power(nameof(Power));
|
||||
World world = World.Empty.WithPowers("Power");
|
||||
Power power = world.GetPower("Power");
|
||||
|
||||
Order order = new NullOrder(power);
|
||||
List<Order> orders = new List<Order> { order };
|
||||
IEnumerable<OrderValidation> results = rubberStamp.ValidateOrders(orders);
|
||||
IEnumerable<OrderValidation> results = rubberStamp.ValidateOrders(world, orders);
|
||||
|
||||
Assert.That(results.Count(), Is.EqualTo(1));
|
||||
Assert.That(results.First().Order, Is.EqualTo(order));
|
||||
|
@ -1,4 +1,3 @@
|
||||
using MultiversalDiplomacy.Map;
|
||||
using MultiversalDiplomacy.Model;
|
||||
|
||||
using NUnit.Framework;
|
||||
@ -51,8 +50,14 @@ public class MapTests
|
||||
[Test]
|
||||
public void LandAndSeaBorders()
|
||||
{
|
||||
Map map = StandardMap.Instance;
|
||||
Assert.That(map.Land("NAF").Adjacents.Count(), Is.EqualTo(1), "Expected 1 bordering land province");
|
||||
Assert.That(map.Water("NAF").Adjacents.Count(), Is.EqualTo(3), "Expected 3 bordering sea provinces");
|
||||
World map = World.Empty.WithStandardMap();
|
||||
Assert.That(
|
||||
map.GetLand("NAF").Adjacents.Count(),
|
||||
Is.EqualTo(1),
|
||||
"Expected 1 bordering land province");
|
||||
Assert.That(
|
||||
map.GetWater("NAF").Adjacents.Count(),
|
||||
Is.EqualTo(3),
|
||||
"Expected 3 bordering sea provinces");
|
||||
}
|
||||
}
|
@ -1,18 +1,19 @@
|
||||
using MultiversalDiplomacy.Adjudicate;
|
||||
using MultiversalDiplomacy.Model;
|
||||
using MultiversalDiplomacy.Orders;
|
||||
|
||||
namespace MultiversalDiplomacyTests;
|
||||
|
||||
public class TestAdjudicator : IPhaseAdjudicator
|
||||
{
|
||||
private Func<IEnumerable<Order>, IEnumerable<OrderValidation>> ValidateOrdersCallback;
|
||||
private Func<World, List<Order>, List<OrderValidation>> ValidateOrdersCallback;
|
||||
|
||||
public TestAdjudicator(
|
||||
Func<IEnumerable<Order>, IEnumerable<OrderValidation>> validateOrdersCallback)
|
||||
Func<World, List<Order>, List<OrderValidation>> validateOrdersCallback)
|
||||
{
|
||||
this.ValidateOrdersCallback = validateOrdersCallback;
|
||||
}
|
||||
|
||||
public IEnumerable<OrderValidation> ValidateOrders(IEnumerable<Order> orders)
|
||||
=> this.ValidateOrdersCallback.Invoke(orders);
|
||||
public List<OrderValidation> ValidateOrders(World world, List<Order> orders)
|
||||
=> this.ValidateOrdersCallback.Invoke(world, orders);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
using MultiversalDiplomacy.Map;
|
||||
using MultiversalDiplomacy.Model;
|
||||
|
||||
namespace MultiversalDiplomacyTests;
|
||||
|
||||
public class TestMap : Map
|
||||
{
|
||||
public override IEnumerable<Province> Provinces { get; }
|
||||
|
||||
public static TestMap Instance { get; } = new TestMap();
|
||||
|
||||
private TestMap()
|
||||
{
|
||||
Provinces = new List<Province>()
|
||||
{
|
||||
Province.Supply("Left", "LEF")
|
||||
.AddLandLocation(),
|
||||
Province.Supply("Right", "RIG")
|
||||
.AddLandLocation(),
|
||||
Province.Empty("Center", "CEN")
|
||||
.AddLandLocation(),
|
||||
};
|
||||
Land("LEF").AddBorder(Land("RIG"));
|
||||
Land("LEF").AddBorder(Land("CEN"));
|
||||
|
||||
Land("RIG").AddBorder(Land("LEF"));
|
||||
Land("RIG").AddBorder(Land("CEN"));
|
||||
|
||||
Land("CEN").AddBorder(Land("LEF"));
|
||||
Land("CEN").AddBorder(Land("RIG"));
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
using MultiversalDiplomacy.Map;
|
||||
using MultiversalDiplomacy.Model;
|
||||
|
||||
using NUnit.Framework;
|
||||
@ -10,17 +9,17 @@ public class UnitTests
|
||||
[Test]
|
||||
public void MovementTest()
|
||||
{
|
||||
Map map = TestMap.Instance;
|
||||
Location left = map.Land("LEF"), right = map.Land("RIG"), center = map.Land("CEN");
|
||||
Power pw1 = new Power("First");
|
||||
Season s1 = Season.MakeRoot();
|
||||
Unit u1 = Unit.Build(left, s1, pw1, UnitType.Army);
|
||||
World world = World.Empty.WithStandardMap().WithPowers("First");
|
||||
Location Mun = world.GetLand("Mun"), Boh = world.GetLand("Boh"), Tyr = world.GetLand("Tyr");
|
||||
Power pw1 = world.GetPower("First");
|
||||
Season s1 = world.Seasons.First();
|
||||
Unit u1 = Unit.Build(Mun, s1, pw1, UnitType.Army);
|
||||
|
||||
Season s2 = s1.MakeNext();
|
||||
Unit u2 = u1.Next(right, s2);
|
||||
Unit u2 = u1.Next(Boh, s2);
|
||||
|
||||
Season s3 = s2.MakeNext();
|
||||
Unit u3 = u2.Next(center, s3);
|
||||
Unit u3 = u2.Next(Tyr, s3);
|
||||
|
||||
Assert.That(u3.Past, Is.EqualTo(u2), "Missing unit past");
|
||||
Assert.That(u2.Past, Is.EqualTo(u1), "Missing unit past");
|
||||
@ -30,8 +29,8 @@ public class UnitTests
|
||||
Assert.That(u2.Season, Is.EqualTo(s2), "Unexpected unit season");
|
||||
Assert.That(u3.Season, Is.EqualTo(s3), "Unexpected unit season");
|
||||
|
||||
Assert.That(u1.Location, Is.EqualTo(left), "Unexpected unit location");
|
||||
Assert.That(u2.Location, Is.EqualTo(right), "Unexpected unit location");
|
||||
Assert.That(u3.Location, Is.EqualTo(center), "Unexpected unit location");
|
||||
Assert.That(u1.Location, Is.EqualTo(Mun), "Unexpected unit location");
|
||||
Assert.That(u2.Location, Is.EqualTo(Boh), "Unexpected unit location");
|
||||
Assert.That(u3.Location, Is.EqualTo(Tyr), "Unexpected unit location");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user