Игровая архитектура и стратегия дизайна для многопользовательской карточной игры
-
03-07-2019 - |
Вопрос
Я относительно новичок в разработке игр, поэтому решил создать хобби-проект с нуля как для получения опыта, так и для развлечения.Конкретная игра похожа на покер, известный как Хвастовство тремя Картами.В эту игру играют в фильме Карты, деньги, два ствола.
Я читал некоторые темы на SO, касающиеся разработки игр, хотя в основном этот вопрос.Это помогло мне изменить первоначальный способ создания объектов.
Одна конкретная проблема, с которой я сталкиваюсь, - это определение состояния игры.Мой первоначальный подход состоял в том, чтобы разделить все (напримерхранение стопок фишек внутри Player
класс), но после прочтения ответов на вопрос Я упоминал ранее, кажется, что все возможные состояния игры должны поддерживаться в пределах GameState
объект.То, что я придумал, по сути, таково:
abstract class CardGameState
{
protected List<Player> _Players;
protected Player _CurrentPlayer;
protected Dictionary<Player, int> _Chips;
protected Dictionary<Player, Hand> _CurrentHand;
protected Dictionary<Player, PlayerStatuses> _PlayerStatus; // PlayerStatuses.InHand, PlayerStatuses.Folded, PlayerStatuses.SittingOut, etc.
/* etc. */
где каждый CardGameState
изменяется каким-либо действием:
public interface IAction
{
string Name { get; }
CardGameState Apply(CardGameState state);
bool IsLegal(CardGameState state);
}
Теперь я очень сильно чувствую, что это противоречит цели объектно-ориентированного программирования, потому что данные, конкретно относящиеся к игроку (в данном случае, его стек фишек, рука и текущее состояние), не инкапсулируются Player
объект.
С другой стороны, если бы игрок увеличил ставку, я бы создал RaiseAction
это реализует IAction
, но тот IAction
интерфейс принимает только текущее состояние игры, что, по моему мнению, не было бы идеальным, если бы стеки фишек хранились внутри Player
класс.
По сути, мой вопрос заключается в следующем:могу ли я получить лучшее из обоих миров, чтобы иметь точное представление о состоянии игры, одновременно сохраняя все данные, относящиеся конкретно к объекту в пределах состояния игры, внутри данного объекта?
Решение
В онлайн-играх, использующих командный шаблон (your IAction) - стандартный и проверенный способ сделать это.Он не объектно-ориентирован в смысле игрока, но действия объектно-ориентированы, так что, я думаю, с чисто теоретической точки зрения это надежный шаблон проектирования.И на практике именно так это реализуется в каждой успешной онлайн-игре, которую я видел, но обратите внимание, что экшн-игры обычно используют очень маленькие незаметные действия / пакеты, пока это практически не превращается в своего рода поток.
Редактировать:
Спустя долгое время после того, как я ответил на этот вопрос, я вернулся сюда и понял, что другим решением этой проблемы является внедрение игроков GameState, колод и т.д...как производное от ИСтейт класс с Применить (действие IAction) Участник.Таким образом, объекты применяют действия к самим себе, вместо того, чтобы приложение применяло действия к объектам, это сопоставило бы действия и состояние с шаблон посетителя вместо шаблона команды.Любое решение будет работать, где у visitor больше накладных расходов и больше инкапсуляции, в то время как command является более простым решением с меньшей инкапсуляцией.
Другие советы
Похоже, вы, возможно, объектно-ориентируете его ради объектно-ориентированности...
Похоже на классику Боба Мартина игра в боулинг проблема.
Редактировать:-Краткое содержание-
Это долгое чтение, но в основном, благодаря TDD и рефакторингу, приложение для подсчета очков в боулинге превратилось из огромного кластера с множеством классов и полиморфизмом в 20 или 30 элегантных строк кода.Почему?Потому что на самом деле им вообще не нужно было там быть