Ответы пользователя по тегу Алгоритмы
  • Как реализовать поиск маршрута в плиточном мире?

    @MarkusD
    все время мелю чепуху :)
    Плиточное поле принято называть дискретным пространством.
    В таком пространстве перемещение измеряется дискретными шагами, между которыми и может быть изменено.

    Для поиска пути в таком дискретном пространстве стоит обратить внимание на алгоритмы поиска в ширину и в глубину.
    Начать стоит с поиска в глубину. Его легко сделать и так же легко понять его неоптимальность. От поиска в глубину довольно легко перейти к поиску в ширину.
    Алгоритмы поиска в ширину и в глубину дадут первичное понимание теории построения маршрута.

    От поиска в ширину можно перейти к эвристическим алгоритмам поиска: A* или поиску по наилучшему совпадению.
    На этом этапе еще полезно познакомиться с алгоритмом JPS. Он может стать даже выгоднее обычного A*.

    A* должен стать для тебя основным инструментом поиска в дискретном пространстве. Но у A* есть проблема большой сложности поиска прямого маршрута.
    При поиске пути по прямой лучше всего использовать алгоритм Брезенхама.
    Этот алгоритм используется для рисования пиксельных примитивов. В частности - прямых.
    И суть должна быть в том, чтобы сперва путь искать через Брезенхама по прямой от точки старта до точки финиша, а если Брезенхам наткнется на препятствие, то уже перейти к поиску через A*.

    Для очень больших дискретных пространств есть варианты иерархического A*: HPA* и HAA*. Они применяются на иерархических дискретных пространствах вида открытого мира. В освоении они являются самыми сложными и самыми интересными.
    Ответ написан
    3 комментария
  • Как программно рассчитать коллайдеры для спрайтов?

    @MarkusD
    все время мелю чепуху :)
    Существует семейство алгоритмов под названием Convex Hulling, позволяющих с требуемой точностью обернуть изображение в примитив.
    Полученный контур примитива уже можно использовать для заполнения коллайдерами, тоже с требуемой точностью.
    Для заполнения примитива коллайдерами может подойти алгоритм из семейства Bin Packing. Они позволяют учитывать перекрытие и неточность заполнения контура.
    В результате, при подборе реализаций и при подстройке критериев ты можешь получить результат, сравнимый с приведенными на изображениях.

    Однако, лично я рекомендовал бы остановиться уже на контуре примитива изображения. Если это все действительно коллайдеры, то проверка одного замкнутого многоугольника будет дешевле проверки потенциально бесконечной коллекции окружностей.
    Ответ написан
    1 комментарий
  • Как построить наименьшую траекторию перемещения по клеткам, имея возможность переставлять препятствия?

    @MarkusD
    все время мелю чепуху :)
    Ответ относится к стандартным алгоритмам поиска пути.

    Литература:
    algolist.manual.ru/games/wavealg.php
    algolist.manual.ru/games/smartmove.php
    www.gamedev.ru/code/articles/?id=4246

    Любой алгоритм удачно усложняется за счет использования потенциальных полей.
    https://habrahabr.ru/post/262181/
    Ответ написан
    7 комментариев
  • Как сделать поиск элементов массива по цепочке (поиск оптимального пути)?

    @MarkusD
    все время мелю чепуху :)
    Уж не карту ли для EVE Online ты решил своими руками сделать? Все предпосылки, включая картинку, говорят об этом. :)

    Любой алгоритм поиска пути тебе в помощь. Смотри в сторону A*, его реализация существует, наверное, даже на бреинфаке, поэтому код попросту неуместен.

    Поиск маршрута делается один раз для самого безопасного маршрута и еще один раз для самого короткого.
    В первом случае весовым коэффициентом узла будет сек-уровень звезды. Эвристика - средний сек-уровень на число прыжков до цели.
    Во втором случае весом будет уже число самих прыжков, а эвристику надо будет считать из числа прыжков до цели.
    Ответ написан
    1 комментарий
  • Как бы вы реализовали принятие решений программой в pick'n'point игре?

    @MarkusD
    все время мелю чепуху :)
    Классами это все решать - это бросок самого себя через свое бедро... Убьешься, в общем.

    Читай Шампандара, тебе нужен раздел деревьев поведения (Behavour Tree) и планировщика решений (Goal Planning).
    Любое действие игрока - это триггер. Скапливаясь, или каждый сам по себе, триггеры влияют на внутреннюю память автомата. Автомат просто выполняет то действие, которое соответствует его текущей внутренней памяти.
    Описание автомата лучше всего делать на скриптовом языке (LUA/Python embedded).
    Каждый уровень - это лишь описание автомата в скрипте.
    Сами действия. Куда то перейти итд... Это уже смотря как твоя сцена сделана. Это можно сделать как жесткой анимацией с именем (которую будет запускать автомат), так и с помощью подсистемы AI (в которую и будет отдавать указания все тот же автомат).

    С такой организацией ты себе гору времени и нервов убережешь.
    Ответ написан
    1 комментарий
  • Какой проект начать разрабатывать, чтобы продемонстрировать свои знания "работадателю"?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    У разработчиков часто руки чешутся что-нибудь свое накатать. И не всегда это прямо какие-то практические проекты. Чаще это просто примеры работы какого-либо подхода, какие-либо тесты, какие-нибудь наброски. И часто это все сваливается в личном пространстве гитхаба.

    мое личное мнение:
    Для меня имеют значение именно такие проекты. Всегда считаю плюсом если человек сам при первом контакте сразу дал ссылку на свой публичный репозиторий. В этом случае я предпочту занять себя чтением этой свалки кода, нежели давать тестовое и терзать кандидата. Хотя везде есть исключения.

    Именно такая свалка произвольного кода, созданная с творческим подходом, созданная чисто для себя (а не для собеседований), без ограничений в решениях свыше, дает лучшее представление о знаниях и способностях человека.

    Советую выбрать проект именно из своих желаний. Из того, за что руки чешутся взяться.
    А если хочется не для себя, а для собеседований, то лично я советую сразу начать стыдиться такого проекта и никому его не показывать.
    И еще советую прочитать вот это: blog.gamedeff.com/?p=64 Актуальность текста лежит далеко за пределами геймдева.
    Ответ написан
    Комментировать
  • Как реализовать вычисление булевой функции на Java?

    @MarkusD
    все время мелю чепуху :)
    Тебе поможет польская нотация, синтаксическое дерево и синтаксический анализ.

    Я бы сделал так.
    Прохожу по входной строке слева направо, разбивая ее на лексемы (токены, символы). Правило разбиения такое: если символ под кареткой просмотра является буквой - это операнд, иначе пробуем распознать оператор.
    Далее, получив список лексем, я прошелся бы по нему с целью построения дерева операций (польская нотаця, не забывай!). Этот шаг даст мне список операций и операндов. Дерево всегда будет бинарным, даже если там будет унарная операция, это все равно лишь один узел дерева.
    Далее я бы составил таблицу значений операндов и вычислил бы по ней значение получившегося дерева операций.

    Тебе может помочь вот этот репозиторий:
    https://github.com/FrankStain/c-script

    И, в частоности, вот этот код:
    https://github.com/FrankStain/c-script/blob/master...

    Это Object Pascal, но не стоит его чураться. Почитай, покури.

    Вноси уточнения в комментах, я буду дополнять свой ответ.
    Ответ написан
    1 комментарий
  • Какой вариант оптимальней?

    @MarkusD
    все время мелю чепуху :)
    По первому блоку:
    switch( b )
    {
    case 4:
    	GiveMe();
    case 3:
    	CallMe();
    	break;
    };

    А вообще, это не вопрос оптимальности. Это вопрос подхода реализации. Легко можно придумать ситуацию, в которой разработчик огребает со всеми подобным подходами, кроме одного или пары.

    Касательно второго блока: предлагаю самостоятельно собрать в дебаге и релизе следующий код, да убедиться в сомнениях самому.
    class A
    {
    public:
    	inline size_t begin()
    	{
    		printf( "begin();\n" );
    		return 0;
    	};
    	
    	inline size_t end()
    	{
    		printf( "end();\n" );
    		return 10;
    	};
    };
    
    A cont;
    for( size_t iter = cont.begin(); cont.end() > iter; ++iter )
    {
    	printf( "%d\n", iter );
    };


    Но тут всегда надо понимать, на какие траты допустимо идти ради удобства. Не стоит увлекаться вторыми переменными в объявлении for если тот же "end()" является легкой и оптимизируемой компилятором конструкцией. В этой связи советую уделить куда большее внимание области инкремента в "for".
    Постфиксная форма всегда приводит к созданию временной переменной, префиксная - нет. Префиксные формы для счетчиков циклов в Google Code Style помечены как хорошая практика.
    Ответ написан
    Комментировать