>> И вы упорно не отвечаете, что, по-вашему, делает написание компиляторов на плюсах более удобным, и стоит ли мне на всякий случай переписывать (или в будущем писать) свои язычки на плюсах.
С фронтэндами языков лично я знаком лишь шапошно, но вот как написать бэкэнд на Хаскеле представляю крайне слабо (ну да сейчас всё в LLVM заворачивают):
На бэкэнде же ну не знаю 90% преобразований подпадают под один или оба паттерна:
— проанализировать граф и что-то в нём преобразовать (воможно транзитивно)
— заменить одно представление CFG-узла другим (идти «сверху вниз» по куску графа, храня какое-то очень большое состояние и меняя операции, в соответствии с состоянием — распределение регистров, IceBreaker, ...).
По-моему и то и то на Хаскеле писать больно (ну или не менее больно чем на условной Java).
Т.е. ваш implicit посыл понятен: у новичков меньше ошибок вида true negative: если задали новое — новичёк лезет в интернет.
Но вы упускаете ошибки типа false positive: новичёк в интернете интересуется, но промышленно программировать на этом не будет.
Однако общий вопрос так и остался: какая-то тула является «рекомендуемой» (по любой причине: например более поддерживаемой \ более «идеоматической»....) или выбор полностью за пользователем?
>> разумеется граничные случаи, когда тупики самосоздаются — возможны, ну с ними вероятно надо будет побороться.
Хм разве не очевидно, что имелось в виду, что есть конфигурация, где при разрешении тупика «самосоздаётся» другой тупик. И так циклически \ часто (как с livelock в многопоточном программировании).
Вроде бы у вас в статье нет доказательств, что ваш метод от такого уберегает. Разрешили тупик, а он (в той же конфигурации) снова создался.
ПС
Хотя по-видимому вытянутые объекты ещё долго не научатся хорошо обрабатывать, см следующий коммент, так что даже если потратится на реализацию «отталкивания по всему контуру» — кардинально это не спасёт.
Вообще я там нашёл ещё одну проблему с «некруглыми» юнитами.
Насколько я понимаю все алгоритмы поиска путей на плоскости (графе некоторого специального частного представления) на такие крайне плохо заточены.
И если для «круглых» ~> «квадратных» квадратных ~> круглых юнитов эта проблема разрешима без замедления и без усложнения рассчётов (но с раздуванием памяти), то для прямоугольных юнитов я пока не вижу как её решать без кратного усложнения алгоритма.
В общем пока получается: или делайте квадратных юнитов или ваши игроки будут «визуально страдать».
>> То есть вы предлагаете динамически постоянно пересчитывать путь?
В целом да.
Изначальный профит был в не наезжании юнитов друг-на друга углами.
>> Это дорого
Можно не весь путь, а сделать performance- эвристику. И при первичном проссчитывании пути ставть «контрольные точки». А при необходимости перерассчитать путь — перерассчитывать её только до ближайшей контрольной точки.
>> Да и профит не очевиден — т.к. постоянно будет маршрут менятся, что приведет к метанию юнитов в толпе.
Изначальный профит очевиден — не наезжать «неквадратным» объектам друг-на друга.
По вашему же замечанию со сменой путь — ИМХО наоборот. Чем раньше вы обнаружите что путь неплохо бы пересчитать — тем меньше вы потеряете (разумеется граничные случаи, когда тупики самосоздаются — возможны, ну с ними вероятно надо будет побороться).
>> Добавляем поле потенциалов в «цену» одного шага алгоритма нахождения пути (тут надо подумать как добавлять — локально для движущихся объектов, менее локально для стоящих).
>> Считаем как выбраться (т.е. производим поиск пути до конечной точки с учётом взвешенных стоимостей прохода)
> Дайте последовательность шагов по расчету.
Не понял что ещё вам нужно уточнить. Расписать алгоритм поиска пути в графе — думаю вы лучше меня их знаете (как минимум знания свежее).
Добавляем поле потенциалов в «цену» одного шага алгоритма нахождения пути (тут надо подумать как добавлять — локально для движущихся объектов, менее локально для стоящих).
Считаем как выбраться.
1. >> Для поля потенциалов это не имеет смысла.
2. >> А вот где усложнение формы имеет смысл — это для алгоритма отталкивания.
Ещё как имеет смысл — перекрытие юнитов в «спокойной» обстановке режет глаз.
Но основное — А почему бы эти алгоритмы не совместить?
1. Потенциалы:
Конструируете поле максимальной интенсивности по периметру объекта. Потом, по тем же правилам что и для окружности, рассчитываем потенциал поля (можно закэшировать пред-рассчёты для разных углов поворота).
2. Отталкивание:
В качестве отталкивания выбираем вектор, идущий в сторону максимального ослабления поля потенциалов.
>> Каждое динамическое препятствие (юнит) записывает в сетку в своём положении окружность с меняющимся значением от 1 до 0…
А вы пробовали записывать не окружность, а «визуальную проекцию» объекта?
Выглядит так, что вычислений у вас и так достаточно, но можно было бы приблизить физ.движок к его графическому отображению.
Выглядит так, что Rust не какая-нибудь «заумная фигня», а язык, решающий те же актуальные вопросы, что и С++ за zero-cost (разумеется несколько по-другому, это же не D / C++++, а другой язык).
С одной стороны интересно, с другой стороны размер rust book говорит, что на rust надо будет десятки часов потратить…
Подскажите ещё момент: а в Rust для трэйтов есть имплементации-функций по умолчанию (как в Haskell для тайпклассов)?
Т.е. двусвязный список на Rust можно реализовать или неоптимально или через Unsafe, так?
А на сколько это будет неоптимально, в сравнении с условным C, разумеется примерно, в 1.5 \ 3 \ 10 раз?
(я просто сначала подумал, что варианта «немного неоптимально» нет, и есть только вариант «через unsafe»)
А почему та же техника не подойдёт для двусвязного списка:
— прямая дуга, та которая next — владение (или Rc ссылка) на элемент.
— обратная дуга, та которая prev — Weak ссылка?
Следует ли вас понимать так, что описанных вами проблем в Rust на односвязном списке возникнуть не может (разумеется если не использовать unsafe и ф-ии его экспортирующие)?
ПС
А что позволит Rust «запретить» утечку памяти, связанную с забыванием удаления элемента при самописаном листе и сигнатуре:
fn extract_from_list(list: tlist, key: int8) -> &mut tlist
//извините не знаю Rust, но смысл в том, что удаляемый элемент будем возвращать из ф-ии по ссылке и тогда автоудаления при выходе из scoupe не произойдёт.
Но ведь все те же самые доводы применимы к тезису «односвязный список вещь небезопасная».
Но ведь односвязный список, если я правильно понимаю, в Rust реализуется.
И тогда получается странное:
двусвязный список реализовать нельзя, потому, что он опасен, тем что проблемы№1,2,3…
в односвязном списке те же проблемы №1,2,3… но его реализовать можно.
А как на Rust реализуется граф?
Пусть для определённости будет Control Flow Graph IR программы (сильно разряженный, направленный граф с циклами, без необходимости многопоточного использования)?
Всё-таки структуры данный с циклическими ссылками вещь весьма частая в использовании и весьма эффективная при реализации «в лоб» на указателях.
С фронтэндами языков лично я знаком лишь шапошно, но вот как написать бэкэнд на Хаскеле представляю крайне слабо (ну да сейчас всё в LLVM заворачивают):
На бэкэнде же ну не знаю 90% преобразований подпадают под один или оба паттерна:
— проанализировать граф и что-то в нём преобразовать (воможно транзитивно)
— заменить одно представление CFG-узла другим (идти «сверху вниз» по куску графа, храня какое-то очень большое состояние и меняя операции, в соответствии с состоянием — распределение регистров, IceBreaker, ...).
По-моему и то и то на Хаскеле писать больно (ну или не менее больно чем на условной Java).
Т.е. ваш implicit посыл понятен: у новичков меньше ошибок вида true negative: если задали новое — новичёк лезет в интернет.
Но вы упускаете ошибки типа false positive: новичёк в интернете интересуется, но промышленно программировать на этом не будет.
В это смысле именно эти лекции отличные (сам их смотрю).
К 4й лекции есть 4 непонятных момента (и все они связаны с примерами кода).
прошу прощения — всё-таки Stack нужен ((
Однако общий вопрос так и остался: какая-то тула является «рекомендуемой» (по любой причине: например более поддерживаемой \ более «идеоматической»....) или выбор полностью за пользователем?
ПС
Поиграться поставил себе stack.
Но плагин к IDEA, например, требует от меня haskell platform.
Хм разве не очевидно, что имелось в виду, что есть конфигурация, где при разрешении тупика «самосоздаётся» другой тупик. И так циклически \ часто (как с livelock в многопоточном программировании).
Вроде бы у вас в статье нет доказательств, что ваш метод от такого уберегает. Разрешили тупик, а он (в той же конфигурации) снова создался.
ПС
Хотя по-видимому вытянутые объекты ещё долго не научатся хорошо обрабатывать, см следующий коммент, так что даже если потратится на реализацию «отталкивания по всему контуру» — кардинально это не спасёт.
Насколько я понимаю все алгоритмы поиска путей на плоскости (графе некоторого специального частного представления) на такие крайне плохо заточены.
И если для
«круглых» ~> «квадратных»квадратных ~> круглых юнитов эта проблема разрешима без замедления и без усложнения рассчётов (но с раздуванием памяти), то для прямоугольных юнитов я пока не вижу как её решать без кратного усложнения алгоритма.В общем пока получается: или делайте квадратных юнитов или ваши игроки будут «визуально страдать».
В целом да.
Изначальный профит был в не наезжании юнитов друг-на друга углами.
>> Это дорого
Можно не весь путь, а сделать performance- эвристику. И при первичном проссчитывании пути ставть «контрольные точки». А при необходимости перерассчитать путь — перерассчитывать её только до ближайшей контрольной точки.
>> Да и профит не очевиден — т.к. постоянно будет маршрут менятся, что приведет к метанию юнитов в толпе.
Изначальный профит очевиден — не наезжать «неквадратным» объектам друг-на друга.
По вашему же замечанию со сменой путь — ИМХО наоборот. Чем раньше вы обнаружите что путь неплохо бы пересчитать — тем меньше вы потеряете (разумеется граничные случаи, когда тупики самосоздаются — возможны, ну с ними вероятно надо будет побороться).
>> Считаем как выбраться (т.е. производим поиск пути до конечной точки с учётом взвешенных стоимостей прохода)
> Дайте последовательность шагов по расчету.
Не понял что ещё вам нужно уточнить. Расписать алгоритм поиска пути в графе — думаю вы лучше меня их знаете (как минимум знания свежее).
Добавляем поле потенциалов в «цену» одного шага алгоритма нахождения пути (тут надо подумать как добавлять — локально для движущихся объектов, менее локально для стоящих).
Считаем как выбраться.
>> А теперь попробуйте добавить сюда свои правки.2. >> А вот где усложнение формы имеет смысл — это для алгоритма отталкивания.
Ещё как имеет смысл — перекрытие юнитов в «спокойной» обстановке режет глаз.
Но основное — А почему бы эти алгоритмы не совместить?
1. Потенциалы:
Конструируете поле максимальной интенсивности по периметру объекта. Потом, по тем же правилам что и для окружности, рассчитываем потенциал поля (можно закэшировать пред-рассчёты для разных углов поворота).
2. Отталкивание:
В качестве отталкивания выбираем вектор, идущий в сторону максимального ослабления поля потенциалов.
А вы пробовали записывать не окружность, а «визуальную проекцию» объекта?
Выглядит так, что вычислений у вас и так достаточно, но можно было бы приблизить физ.движок к его графическому отображению.
Выглядит так, что Rust не какая-нибудь «заумная фигня», а язык, решающий те же актуальные вопросы, что и С++ за zero-cost (разумеется несколько по-другому, это же не D / C++++, а другой язык).
С одной стороны интересно, с другой стороны размер rust book говорит, что на rust надо будет десятки часов потратить…
Подскажите ещё момент: а в Rust для трэйтов есть имплементации-функций по умолчанию (как в Haskell для тайпклассов)?
А на сколько это будет неоптимально, в сравнении с условным C, разумеется примерно, в 1.5 \ 3 \ 10 раз?
(я просто сначала подумал, что варианта «немного неоптимально» нет, и есть только вариант «через unsafe»)
— прямая дуга, та которая next — владение (или Rc ссылка) на элемент.
— обратная дуга, та которая prev — Weak ссылка?
П
ПС
А что позволит Rust «запретить» утечку памяти, связанную с забыванием удаления элемента при самописаном листе и сигнатуре:
fn extract_from_list(list: tlist, key: int8) -> &mut tlist
//извините не знаю Rust, но смысл в том, что удаляемый элемент будем возвращать из ф-ии по ссылке и тогда автоудаления при выходе из scoupe не произойдёт.
Но ведь односвязный список, если я правильно понимаю, в Rust реализуется.
И тогда получается странное:
двусвязный список реализовать нельзя, потому, что он опасен, тем что проблемы№1,2,3…
в односвязном списке те же проблемы №1,2,3… но его реализовать можно.
Пусть для определённости будет Control Flow Graph IR программы (сильно разряженный, направленный граф с циклами, без необходимости многопоточного использования)?
Всё-таки структуры данный с циклическими ссылками вещь весьма частая в использовании и весьма эффективная при реализации «в лоб» на указателях.
Аналоги неотличимые по качеству (правда по чужим словам — я брал именно эрготрон, хороших аналогов в тот момент ещё не было) стоят от 6к рублей.
Поэтому выставлять на показ качество подставки под дорогой монитор — просто непрофессионально, уж извините.