代码之家  ›  专栏  ›  技术社区  ›  shuttle87 Bhargav Boda

基于c语言的大型决策树人工智能设计模式++

  •  12
  • shuttle87 Bhargav Boda  · 技术社区  · 14 年前

    目前我在prolog(100+)中有一些事实和规则。很多东西都是以形式表达的,如果游戏状态那么就做动作xyz。大多数规则都相当简单,有些则相当复杂。我研究了一种有限状态机方法,但它似乎不能很好地适应更大的情况。 我第一次尝试用c++编写这个代码是if-then-else case语句的噩梦。我到处都能看到这样的代码:

        if( this->current_game_state->some_condition == true ){
            if( this->current_game_state->some_other_condition == false ){      
                    //some code
            }else{
                return do_default_action();
            }
        }else if( this->current_game->another_condition ){
            //more code
        }
    

    如果有一个很好的方法来用c++编写这类问题的代码?有什么好的设计模式来处理这种情况吗?不要求逻辑必须包含在源代码中,它只需要从c++访问即可。唯一真正的要求是速度相当快。

    我还研究了规则引擎,如果足够快,它们可能是合适的。你知道有没有合适的开源c++规则引擎吗?

    6 回复  |  直到 14 年前
        1
  •  10
  •   xscott    14 年前

    一种可能是采用Prolog规则,以最直接的方式将它们转换为数据结构。也许你可以设计一个简单的表格,比如:

    struct {
        State coming_from;
        Event event;
        void (*func)(some, args);
        State going_to;
    } rules[] = {
        { WANDERING_AROUND, HEAR_SOUND, look_around, ENEMY_SEEN },
        { ENEMY_SEEN,       GUN_LOADED, fire_gun,    SNEEK_AWAY },
        { next, rule, goes, here },
        etc... 
    }
    

    类似地,函数调用可以以类似于原始Prolog的方式填充数据结构:

    void init_rules () {
        rule("Parent", "Bill", "John");
        rule("Parent", "Paul", "Bill");
        // 99 more rules go here...
    }
    

        2
  •  5
  •   Puppy    14 年前

    你可以使用多态性。调用一个虚拟函数实际上是一个大的开关/案例,编译器为您完成并优化了它。

    class GameState {
        virtual void do_something() { std::cout << "GameState!"; }
        // some functions
        virtual ~GameState() {}
    };
    class SomeOtherState : public GameState {
        // some other functions
        virtual void do_something() { std::cout << "SomeOtherState!"; }
    };
    class MyFinalState : public GameState {
        virtual void do_something() { std::cout << "MyOtherState!"; }
    };
    class StateMachine {
        std::auto_ptr<GameState> curr_state;
    public:
        StateMachine()
            : curr_state(NULL) {}
        void DoSomething() { curr_state->DoSomething(); }
        void SetState(GameState* ptr) { curr_state = ptr; }
        template<typename T> void SetState() { curr_state = new T; }
    };
    int main() {
        StateMachine sm;
        sm.SetState(new SomeOtherState());
        sm.SetState<SomeOtherState>();
        sm.DoSomething(); // prints "SomeOtherState!"
        sm.SetState<MyFinalState>();
        sm.DoSomething(); // prints "MyFinalState!"
    }
    

        3
  •  3
  •   kod kristoff    14 年前

    如果要将prolog代码转换为c++代码, http://www.mpprogramming.com/Cpp/Default.aspx

    我自己也没试过,所以我对它的性能一无所知。

        4
  •  2
  •   InsertNickHere    14 年前

    我真的不明白为什么有限状态机不适合你的游戏。这是做你想做的事的常见方法。您可以使它成为数据驱动的,以使您的代码不受具体操作的影响。有限状态m.在“游戏开发的AI”O'Reilly中也有描述(davidm.Bourg&glennseemann) 您可能希望将规则拆分为几个较小的规则集,以保持机器的小型化和可理解性。

        5
  •  1
  •   oadams    14 年前

    用水银怎么样?它基本上是为与C代码接口而构建的。

        6
  •  0
  •   codie    14 年前

    试图将Prolog的表达能力与状态机相匹配,就像试图用自行车跑过汽车一样。

    http://www.mpprogramming.com/cpp