private static (int, int) GetSlopeFrom(LogicalPiece origin, LogicalPiece direction) { // this works because we know that destination and adjacent will always be at most one step apart int GetDirectionFrom(int start, int end) => start < end ? 1 : end == start ? 0 : -1; return(GetDirectionFrom(origin.X, direction.X), GetDirectionFrom(origin.Z, direction.Z)); }
private static List <Move> GetMovesFrom(LogicalPiece bound, List <LogicalPiece> directions, IReadOnlyList <LogicalPiece> state) { List <Move> moves = new List <Move>(); foreach (LogicalPiece direction in directions) { var(possiblePieceForMove, flippedPieces) = GetPieceAtEndOfLineAndDistanceFrom(bound, direction, state); if (!state.Contains(possiblePieceForMove) && InsideBounds(possiblePieceForMove)) { moves.Add(new Move(possiblePieceForMove, bound, flippedPieces)); } } return(moves); }
public override List <Move> GetNextMove() { if (!_nextX.HasValue || !_nextZ.HasValue) { return(new List <Move>()); } LogicalPiece selected = new LogicalPiece(_nextX.Value, _nextZ.Value, Color); _nextX = null; _nextZ = null; // This is a bold assumption: For we check if the field exists in the tile, we know that we should only // get selected pieces that are actually in the set of potentialMoves return(MyMoves .Where(move => move.Played.Equals(selected)) .ToList()); }
private static List <LogicalPiece> GetOpposingAdjacentsOf(LogicalPiece existingPiece, IReadOnlyList <LogicalPiece> state) { IEnumerable <int> Range(int pos) => Enumerable.Range(pos - 1, 3); LogicalPiece OpposingPieceAt(int x, int z) => new LogicalPiece(x, z, existingPiece.Color.Opposing()); List <LogicalPiece> adjacents = new List <LogicalPiece>(8); foreach (var row in Range(existingPiece.X)) { foreach (var column in Range(existingPiece.Z)) { var enemyPieceAsDirection = OpposingPieceAt(row, column); if (state.Contains(enemyPieceAsDirection)) { adjacents.Add(enemyPieceAsDirection); } } } return(adjacents); }
private static (LogicalPiece, int) GetPieceAtEndOfLineAndDistanceFrom( LogicalPiece origin, LogicalPiece direction, IReadOnlyList <LogicalPiece> state) { int AdvanceOneStepFrom(int i) => i + (i < 0 ? -1 : i == 0 ? 0 : 1); // increment or decrement depending on the direction LogicalPiece NewLogicalPieceAt(int row, int column) => new LogicalPiece(origin.X + row, origin.Z + column, origin.Color.Opposing()); var(rowDirection, colDirection) = GetSlopeFrom(origin, direction); int flipped = 0; LogicalPiece next = NewLogicalPieceAt(rowDirection, colDirection); while (state.Contains(next)) { rowDirection = AdvanceOneStepFrom(rowDirection); colDirection = AdvanceOneStepFrom(colDirection); next = NewLogicalPieceAt(rowDirection, colDirection); flipped++; } return(new LogicalPiece(next.X, next.Z, origin.Color), flipped); }
public Move(LogicalPiece played, LogicalPiece bound, int flipped) { Played = played; Bound = bound; Flipped = flipped; }
private static bool InsideBounds(LogicalPiece piece) { bool InsideBounds(int pos) => pos >= 0 && pos < Game.Instance.BoardLength; return(InsideBounds(piece.X) && InsideBounds(piece.Z)); }