using static Hexapawn.Pawn; namespace Hexapawn { /// /// Represents a move which may, or may not, be legal. /// internal class Move { private readonly Cell _from; private readonly Cell _to; private readonly int _metric; public Move(Cell from, Cell to) { _from = from; _to = to; _metric = _from - _to; } public void Deconstruct(out Cell from, out Cell to) { from = _from; to = _to; } public Cell From => _from; // Produces the mirror image of the current moved, reflected around the central column of the board. public Move Reflected => (_from.Reflected, _to.Reflected); // Allows a tuple of two ints to be implicitly converted to a Move. public static implicit operator Move((int From, int To) value) => new(value.From, value.To); // Takes floating point coordinates, presumably from keyboard input, and attempts to create a Move object. public static bool TryCreate(float input1, float input2, out Move move) { if (Cell.TryCreate(input1, out var from) && Cell.TryCreate(input2, out var to)) { move = (from, to); return true; } move = default; return false; } public static Move Right(Cell from) => (from, from - 2); public static Move Straight(Cell from) => (from, from - 3); public static Move Left(Cell from) => (from, from - 4); public bool IsStraightMoveToEmptySpace(Board board) => _metric == 3 && board[_to] == None; public bool IsLeftDiagonalToCapture(Board board) => _metric == 4 && _from != 7 && board[_to] == Black; public bool IsRightDiagonalToCapture(Board board) => _metric == 2 && _from != 9 && _from != 6 && board[_to] == Black; public void Execute(Board board) { board[_to] = board[_from]; board[_from] = None; } public override string ToString() => $"from {_from} to {_to}"; } }