У меня есть механизм вариантов шахмат, который играет шахматы-самоубийцы и шахматы неудачников наряду с обычными шахматами. Со временем я мог бы добавить больше вариантов в мой двигатель. Движок полностью реализован на C ++ с правильным использованием ООП. Мой вопрос связан с дизайном такого варианта двигателя.
Первоначально проект начинался как самоубийственный движок, а со временем я добавил другие варианты. Для добавления новых вариантов я сначала экспериментировал с использованием полиморфизма в C ++. Например, у абстрактного класса MoveGenerator
есть два подкласса SuicideMoveGenerator
и NormalMoveGenerator
, и в зависимости от типа игры, выбранного пользователем, фабрика будет создавать правильный подкласс. Но я обнаружил, что это намного медленнее - очевидно, потому что создание экземпляров классов, содержащих виртуальные функции, и вызов виртуальных функций в узких циклах - оба совершенно неэффективны.
Но потом мне пришло в голову использовать шаблоны C ++ с шаблонной специализацией для разделения логики для разных вариантов с максимальным повторным использованием кода. Это также казалось очень логичным, потому что динамическое связывание на самом деле не является необходимым в контексте, поскольку, выбрав тип игры, вы в основном придерживаетесь его до конца игры. Специализация шаблонов C ++ обеспечивает именно это - статический полиморфизм. Параметр шаблона: либо SUICIDE
, либо LOSERS
, либо NORMAL
.
enum GameType { LOSERS, NORMAL, SUICIDE };
Таким образом, как только пользователь выбирает тип игры, создается соответствующий игровой объект, и все, что там вызывается, будет соответствующим образом шаблонизировано. Например, если пользователь выбирает шахматы-самоубийцы, скажем:
ComputerPlayer<SUICIDE>
объект создается, и это создание в основном статически связано со всем потоком управления. Функции в ComputerPlayer<SUICIDE>
будут работать с MoveGenerator<SUICIDE>
, Board<SUICIDE>
и т. Д., В то время как соответствующая NORMAL
будет работать соответствующим образом.
В целом, это позволяет мне создавать правильный шаблонизированный специализированный класс в начале и без каких-либо других условий if
в любом месте, все работает отлично. Лучше всего то, что производительности вообще не будет!
Однако основным недостатком этого подхода является то, что использование шаблонов делает ваш код немного сложнее для чтения. Кроме того, специализация шаблона, если она не обрабатывается надлежащим образом, может привести к серьезным ошибкам.
Интересно, что обычно делают другие разработчики движков для разделения логики (с хорошим повторным использованием кода) ?? Я нашел подходящее программирование на C ++, но если есть что-то лучшее, я был бы рад принять. В частности, я проверил движок Fairymax доктора Г. Г. Мюллера, но он использует файлы конфигурации для определения правил игры. Я не хочу этого делать, потому что многие из моих вариантов имеют разные расширения и, делая его общим для уровня config-файлов, движок может не стать сильным. Другой популярный движок Sjeng везде окружен if
условиями, и я лично считаю, что это не очень хороший дизайн.
Любые идеи нового дизайна были бы очень полезны.