static bool CanMoveQueen(Game board, Position position, out List <Move> moves) { moves = new List <Move>(); var tile = board.GetTile(position); if (tile != Tile.QueenBlack && tile != Tile.QueenWhite) { return(true); } var moveDirections = new[] { Tuple.Create(1, 1), Tuple.Create(1, -1), Tuple.Create(-1, -1), Tuple.Create(-1, 1) }; foreach (var direction in moveDirections) { var rowDirection = direction.Item1; var columnDirection = direction.Item2; var steps = 1; while (true) { bool pieceInsideTheBoard = Position.Try(position.Row + steps * rowDirection, position.Column + steps * columnDirection, out Position toMovePosition); if (pieceInsideTheBoard && board.GetTile(toMovePosition) == Tile.Empty) { moves.Add(new Move { From = position, To = toMovePosition }); } else if ( pieceInsideTheBoard && EnemyTile(tile, board.GetTile(toMovePosition)) && Position.Try(position.Row + (steps + 1) * rowDirection, position.Column + (steps + 1) * columnDirection, out Position toMoveAfterEat) && board.GetTile(toMoveAfterEat) == Tile.Empty ) { var eatMove = new Eat { From = position, To = toMoveAfterEat, Eaten = new List <Position>() { toMovePosition } }; var gameAfterMove = board.Move(eatMove); if (CanMoveQueen(gameAfterMove, toMoveAfterEat, out List <Move> newMoves)) { var eatMoves = newMoves.OfType <Eat>().Select(x => { eatMove.Eaten.AddRange(from ne in x.Eaten where !eatMove.Eaten.Any(bl => bl.Number == ne.Number) select ne); eatMove.To = x.To; return(eatMove); }); if (eatMoves.Any()) { moves.AddRange(eatMoves); } else { moves.Add(eatMove); } } break; } else { break; } steps++; } } return(true); }
static List <Eat> CanPieceEat(Game board, Position position) { var moves = new List <Eat>(); var tile = board.GetTile(position); if (tile == Tile.Empty) { return(moves); } var moveDirections = new[] { Tuple.Create(1, 1), Tuple.Create(1, -1), Tuple.Create(-1, -1), Tuple.Create(-1, 1) }; foreach (var direction in moveDirections) { var rowDirection = direction.Item1; var columnDirection = direction.Item2; bool pieceInsideTheBoard = Position.Try(position.Row + rowDirection, position.Column + columnDirection, out Position toEatPosition); bool isAEnemyTile = pieceInsideTheBoard && EnemyTile(board.GetTile(toEatPosition), tile); bool positionIsValidAfterMove = Position.IsCoordValid(position.Row + (rowDirection * 2), position.Column + (columnDirection * 2)); bool thePositionAfterMoveIsEmpty = positionIsValidAfterMove && board.GetTile(Position.FromCoors(position.Row + (rowDirection * 2), position.Column + (columnDirection * 2))) == Tile.Empty; if (pieceInsideTheBoard && isAEnemyTile && positionIsValidAfterMove && thePositionAfterMoveIsEmpty) { var to = Position.FromCoors(position.Row + (rowDirection * 2), position.Column + (columnDirection * 2)); var from = position; var eatMove = new Eat { Eaten = new List <Position> { toEatPosition }, From = from, To = to }; var newBoard = board.Move(eatMove); var eatMoves = CanPieceEat(newBoard, to); if (eatMoves.Any()) { moves.AddRange(eatMoves.Select(m => { var list = new List <Position>() { toEatPosition }; list.AddRange(m.Eaten); return(new Eat { From = from, To = m.To, Eaten = list }); })); } else { moves.Add(eatMove); } } } return(moves); }