Реализация шаблона состояния с помощью структуры данных Graph

В настоящее время я пытаюсь реализовать приложение, где есть около 10 государств. В отличие от традиционного шаблона состояний, когда существует только 1 ссылка на другое состояние из одного состояния, я хочу, чтобы он был больше похож на ориентированный граф, в котором одно состояние может иметь несколько ребер для разных состояний.

Пример: у меня есть состояния 1-10 (вершины). - это края. Это могут быть возможные переходы состояний.

1-2, 1-3, 1-6 2-3, 2-9 3-5 4-3 5-2, 5-3, 5-4 6-3, 6-4,6-7, 6-9... И так далее

Каждое состояние - это классы, а каждое ребро (-) - это методы. Например:

Class State1 { public void goToState2() ; public void goToState3() ; public void goToState6() ; }

Class State2 { public void goToState3() ; public void goToState9() ; }...

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

Любая помощь или руководство будут оценены!

0 ответов

Поскольку задействован граф переходов между состояниями, необходимо поддерживать смежность и определять критерии перехода. Этот критерий может быть общим для всех узлов (например, переход от одного узла к другому продиктован стоимостью перехода) или его можно настроить для каждого узла (например, на одном узле переход происходит на основе стоимости, в то время как для другого переход происходит на основе узла тип).

class ExecutionParameters;
class IState;
using SPState = std::shared_ptr<IState>;
using SPStates = std::list<SPState>;
class _declspec(novtable) IState
{
public:
    virtual void Execute(Context& context, const ExecutionParameters& params) = 0;
    virtual SPStates GetAdjacentStates() const noexcept = 0;
};

class _declspec(novtable) ITransitionCriteria
{
public:
    virtual SPState ComputeNextState() const = 0;
};

class CostBasedTransition : public ITransitionCriteria
{
public:
    SPState ComputeNextState() const override
    {
         // Find min transition cost adjacent node
    }
};
using SPTransitionCriteria = std::shared_ptr<ITransitionCriteria>;

class StateNode : public IState
{
public:
    StateNode(int id, SPTransitionCriteria spTransitionCriteria) :m_id(id), m_spTransitionCriteria(spTransitionCriteria)
    {}
    StateNode(int id) :StateNode(id, nullptr)//Choose default transition criteria//)
    {}

    void Execute(Context& context, const ExecutionParameters& params) override
    {
        // Perform action

        // Update context state
        context.SetState(m_spTransitionCriteria->GetNextState());
    }

    SPStates GetAdjacentStates() const noexcept
    {
        return m_spAdjacentStates;
    }

    void AddAjacentState(SPState spState)
    {
    }

    void RemoveAjacentState(int stateId)
    {
    }
private:
    int m_id;
    SPStates m_spAdjacentStates;
    SPTransitionCriteria m_spTransitionCriteria;
};

class Context
{
public:
    void Execute(const ExecutionParameters& params)
    {
        m_spState->Execute(*this, params);
    }

    void SetState(SPState& spState)
    {
        m_spState = spState;
    }
private:
    SPState m_spState;
};

Другие вопросы по тегам