public Stream<String> placeFiguresOnBoards(Stream<String> boardsStream) {
        Set<String> initialBoardsWithoutAttackPlaces = boardsStream.collect(Collectors.toSet());

        Set<String> initialBoardsWithAttackPlaces = initialBoardsWithoutAttackPlaces
                .parallelStream()
                .filter(board -> board.contains(KING.getFigureAsString())
                              || board.contains(QUEEN.getFigureAsString())
                              || board.contains(BISHOP.getFigureAsString())
                              || board.contains(ROOK.getFigureAsString())
                              || board.contains(KNIGHT.getFigureAsString()))
                .filter(e -> !e.contains(FIELD_UNDER_ATTACK_STRING))
                .filter(e -> e.contains(EMPTY_FIELD_STRING))
                .map(this::calculateAttackPlaces)
                .collect(Collectors.collectingAndThen(Collectors.toSet(),
                        set -> set.isEmpty() ? initialBoardsWithoutAttackPlaces : set));

        Set<String> boardsWithNewFigureAndAttackPlaces = initialBoardsWithAttackPlaces
                .parallelStream()
                .filter(e -> e.contains(EMPTY_FIELD_STRING))
                .map(this::placeCertainFigureOnBoard)
                .flatMap(Set::stream)
                .map(this::calculateAttackPlaces)
                .collect(Collectors.collectingAndThen(Collectors.toSet(),
                        set -> set.isEmpty() ? initialBoardsWithAttackPlaces : set));

        return boardsWithNewFigureAndAttackPlaces.stream();
    }