private IEnumerable <Move[]> FindMoves(Side side, BoardSquare pos, Direction dir, HashSet <BoardSquare> visited = null, bool capture = false) { visited ??= new HashSet <BoardSquare>(); var square = pos.Shift(dir); if (!square.IsValid || visited.Contains(square)) { return(Array.Empty <Move[]>()); } var piece = GetPiece(square); if (piece is null) { return(capture ? Array.Empty <Move[]>() : new[] { new [] { new Move(pos, square, null) } }); } if (piece.Side != side) { var jump = square.Shift(dir); if (jump.IsValid && GetPiece(jump) is null) { var move = new Move(pos, jump, piece); visited.Add(square); var paths = new List <Move[]>(); paths.AddRange(FindMoves(side, jump, Direction.UpperLeft, visited, true)); paths.AddRange(FindMoves(side, jump, Direction.UpperRight, visited, true)); paths.AddRange(FindMoves(side, jump, Direction.LowerLeft, visited, true)); paths.AddRange(FindMoves(side, jump, Direction.LowerRight, visited, true)); visited.Remove(square); if (!paths.Any()) { return(new[] { new[] { move } }); } var maxLength = paths.Max(x => x.Length); return(paths.Where(x => x.Length == maxLength).Select(path => { var moves = new List <Move> { move }; moves.AddRange(path); return moves.ToArray(); })); } } return(Array.Empty <Move[]>()); }