Add order model and adjudicator framework
This commit is contained in:
parent
031d1b60bd
commit
c4f5145320
|
@ -0,0 +1,22 @@
|
|||
using MultiversalDiplomacy.Orders;
|
||||
|
||||
namespace MultiversalDiplomacy.Adjudicate;
|
||||
|
||||
/// <summary>
|
||||
/// An input handler for game phases.
|
||||
/// </summary>
|
||||
public interface IPhaseAdjudicator
|
||||
{
|
||||
/// <summary>
|
||||
/// Given a list of orders, determine which orders are valid for this adjudicator and
|
||||
/// which should be rejected before adjudication. Adjudication should be performed on
|
||||
/// all orders in the output for which <see cref="OrderValidation.Valid"/> is true.
|
||||
/// </summary>
|
||||
/// <param name="orders">Orders to validate for adjudication.</param>
|
||||
/// <returns>
|
||||
/// A list of order validation results. Note that this list may be longer than the input
|
||||
/// list if illegal orders were replaced with hold orders, as there will be an invalid
|
||||
/// result for the illegal order and a valid result for the replacement order.
|
||||
/// </returns>
|
||||
public IEnumerable<OrderValidation> ValidateOrders(IEnumerable<Order> orders);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using MultiversalDiplomacy.Orders;
|
||||
|
||||
namespace MultiversalDiplomacy.Adjudicate;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of validating an order.
|
||||
/// </summary>
|
||||
public class OrderValidation
|
||||
{
|
||||
/// <summary>
|
||||
/// The order that was validated.
|
||||
/// </summary>
|
||||
public Order Order { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the order is valid.
|
||||
/// </summary>
|
||||
public bool Valid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The reason for the order validation result.
|
||||
/// </summary>
|
||||
public ValidationReason Reason { get; }
|
||||
|
||||
internal OrderValidation(Order order, bool valid, ValidationReason reason)
|
||||
{
|
||||
this.Order = order;
|
||||
this.Valid = valid;
|
||||
this.Reason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OrderValidationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an <see cref="OrderValidation"/> accepting this order.
|
||||
/// </summary>
|
||||
public static OrderValidation Validate(this Order order, ValidationReason reason)
|
||||
=> new OrderValidation(order, true, reason);
|
||||
|
||||
/// <summary>
|
||||
/// Create an <see cref="OrderValidation"/> rejecting this order.
|
||||
/// </summary>
|
||||
public static OrderValidation Invalidate(this Order order, ValidationReason reason)
|
||||
=> new OrderValidation(order, false, reason);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
namespace MultiversalDiplomacy.Adjudicate;
|
||||
|
||||
public enum ValidationReason
|
||||
{
|
||||
/// <summary>
|
||||
/// The order is valid.
|
||||
/// </summary>
|
||||
Valid = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The order type is not valid for the current phase of the game.
|
||||
/// </summary>
|
||||
InvalidOrderTypeForPhase = 1,
|
||||
|
||||
/// <summary>
|
||||
/// A hold order was created to replace an illegal order.
|
||||
/// </summary>
|
||||
IllegalOrderReplacedWithHold = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Another order was submitted that replaced this order.
|
||||
/// </summary>
|
||||
SupersededByLaterOrder = 3,
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using MultiversalDiplomacy.Model;
|
||||
|
||||
namespace MultiversalDiplomacy.Orders;
|
||||
|
||||
/// <summary>
|
||||
/// A submitted action by a power.
|
||||
/// </summary>
|
||||
public abstract class Order
|
||||
{
|
||||
/// <summary>
|
||||
/// The power that submitted this order.
|
||||
/// </summary>
|
||||
public Power Power { get; }
|
||||
|
||||
public Order(Power power)
|
||||
{
|
||||
this.Power = power;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using MultiversalDiplomacy.Adjudicate;
|
||||
using MultiversalDiplomacy.Model;
|
||||
using MultiversalDiplomacy.Orders;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace MultiversalDiplomacyTests;
|
||||
|
||||
public class AdjudicatorTests
|
||||
{
|
||||
[Test]
|
||||
public void OrderValidationTest()
|
||||
{
|
||||
IPhaseAdjudicator rubberStamp = new TestAdjudicator(orders => {
|
||||
return orders.Select(o => o.Validate(ValidationReason.Valid));
|
||||
});
|
||||
Power power = new Power(nameof(Power));
|
||||
|
||||
Order order = new NullOrder(power);
|
||||
List<Order> orders = new List<Order> { order };
|
||||
IEnumerable<OrderValidation> results = rubberStamp.ValidateOrders(orders);
|
||||
|
||||
Assert.That(results.Count(), Is.EqualTo(1));
|
||||
Assert.That(results.First().Order, Is.EqualTo(order));
|
||||
Assert.That(results.First().Reason, Is.EqualTo(ValidationReason.Valid));
|
||||
Assert.That(results.First().Valid, Is.True);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using MultiversalDiplomacy.Model;
|
||||
using MultiversalDiplomacy.Orders;
|
||||
|
||||
namespace MultiversalDiplomacyTests;
|
||||
|
||||
public class NullOrder : Order
|
||||
{
|
||||
public NullOrder(Power power) : base(power) {}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using MultiversalDiplomacy.Adjudicate;
|
||||
using MultiversalDiplomacy.Orders;
|
||||
|
||||
namespace MultiversalDiplomacyTests;
|
||||
|
||||
public class TestAdjudicator : IPhaseAdjudicator
|
||||
{
|
||||
private Func<IEnumerable<Order>, IEnumerable<OrderValidation>> ValidateOrdersCallback;
|
||||
|
||||
public TestAdjudicator(
|
||||
Func<IEnumerable<Order>, IEnumerable<OrderValidation>> validateOrdersCallback)
|
||||
{
|
||||
this.ValidateOrdersCallback = validateOrdersCallback;
|
||||
}
|
||||
|
||||
public IEnumerable<OrderValidation> ValidateOrders(IEnumerable<Order> orders)
|
||||
=> this.ValidateOrdersCallback.Invoke(orders);
|
||||
}
|
Loading…
Reference in New Issue