Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 成员变量为简单游戏保留指向其他成员变量/递归AI的指针_C++_Pointers_Tree_Copy Constructor - Fatal编程技术网

C++ 成员变量为简单游戏保留指向其他成员变量/递归AI的指针

C++ 成员变量为简单游戏保留指向其他成员变量/递归AI的指针,c++,pointers,tree,copy-constructor,C++,Pointers,Tree,Copy Constructor,我正在为一个游戏实现一个简单的AI。 基本思想是: 在游戏的每个状态下,确定可能的行动列表 将操作存储在某种集合中 在游戏中前进/移动,同时向状态树递归添加新节点(游戏状态) 如果无法确定进一步的操作,则完成树的分支,并检查赢/输条件(尚未实施,但非常简单) 我不确定该构造函数(请参阅下面的完整代码表): 其思想是确定更高层次递归的后续步骤列表,并将AI指令存储在“动作”的通用列表中,该列表存储两个指针:一个指向源游戏对象,另一个指向目标对象。然后可以批量执行操作 下面的代码几乎是完整的,应该给

我正在为一个游戏实现一个简单的AI。 基本思想是:

  • 在游戏的每个状态下,确定可能的行动列表
  • 将操作存储在某种集合中
  • 在游戏中前进/移动,同时向状态树递归添加新节点(游戏状态)
  • 如果无法确定进一步的操作,则完成树的分支,并检查赢/输条件(尚未实施,但非常简单)
  • 我不确定该构造函数(请参阅下面的完整代码表):

    其思想是确定更高层次递归的后续步骤列表,并将AI指令存储在“动作”的通用列表中,该列表存储两个指针:一个指向源游戏对象,另一个指向目标对象。然后可以批量执行操作

    下面的代码几乎是完整的,应该给出我想做什么的想法

    <>我比较有经验,java C++已经实现过类似的逻辑,但是这个任务应该在C++中解决,目前我遇到了一些技术上的困难。 补充: 1.如果我提到的构造函数方法不正确/设计不好,那么正确的实现方法是什么?我想要游戏状态,它“知道”是什么动作创造了它们。由于我的动作是在父游戏状态中创建的,并存储指向该状态数据结构的指针,因此在构造函数中复制它们之后,它们仍然指向相同的对象。所以这种逻辑似乎是错误的。实现我所描述的行为的正确方法是什么?例如,它可以帮助我在保持相同游戏状态的同时反转动作。 2.对我的代码有什么共同的建议吗?有什么建议让它更优雅吗?有没有我根本不认识的明显错误

    // class GameState.h:
    class GameState {
    
    private:
        // The "Foos" are some sort of collection: vector, deque, whatever
        Foo f1;
        Foo f2;
        Action ownAction;
        std::vector<Action> nextActions;
    
        // Pointer to the previous GameState
        GameState * prevState;
        // Collection of pointers to the next GameStates
        vector<GameState*> nextStates;
    
    public:
        GameState(GameState * parent, Action & action);
        GameState(const GameState & obj);
        void prepare();
        void advance();
        ...
    }
    
    // GameState.cpp
    GameState::GameState(GameState * parent, Action & action)
    {
        this->prevState = parent; // pointer to previous GameState
        this->f1 = parent->f1; // game data container
        this->f2 = parent->f2; // game data container
        this->nextActions = std::vector<Action>(); // we'll determine new next actions in this GameState
    
        // !!! PROBLEM: pointers stored in the action are still pointing to the game containers of the parent state!
        // What is the proper way to pass an action to the next GameState?
        this->ownAction = action;
        this->visited = parent->visited;
    }
    
    GameState::prepare()
    {
        // Check game conditions 
        // and create a list of next possible Actions
        if (condition1) {
            nextActions.push_back(Action(&f1, &f2));
        }
    
        ...
    
        // there are different kinds of actions
        // which all inherit from the same parent class
        // so I just write "Action" for simplicity
    }
    
    GameState::advance()
    {
        ownAction.execute(); // execute own action -> alter own state
        prepare(); // prepare a list of next actions
    
        for(size_t i = o; nextActions.size(); ++i) {
            if (!nextActions.at(i).inverted(ownAction)) { // no steps back are allowed!
                // passing the copy of the altered state and the action to the next level
                GameState * nextState = new GameState(this, nextActions.at(i));
                nextState->advance();
                nextStates.push_back(nextState); // storing the pointer to the next GameState
            }
        }
    }
    
    // Action.h
    class Action {
    
    private:
        Foo * src;
        Foo * tgt;
    
    public:
        Action(Foo * src, Foo * tgt);
        Action(const Action & obj);
        ~Action();
        void execute();
        bool inverted(Action & other);
    }
    
    // Action.cpp    
    Action::Action(Foo * src, Foo * tgt)
    {
        this->src = src;
        this->tgt = tgt;
    }
    
    Action::Action(const Action & obj)
    {
        this->src = obj.src;
        this->tgt = obj.tgt;
    }
    
    Action::execute()
    {
        // something like this:
        tgt.push_back(src.top());
        src.pop();
        // moving values from the one referenced container
        // into another referenced container
    }
    
    //类GameState.h:
    类配子态{
    私人:
    //“Foos”是某种集合:vector,deque,随便什么
    富f1;
    Foo-f2;
    行动自己行动;
    std::向量nextActions;
    //指向上一个游戏状态的指针
    游戏状态*prevState;
    //指向下一个游戏状态的指针集合
    向量nextStates;
    公众:
    游戏状态(游戏状态*父项、动作和动作);
    配子状态(const配子状态和obj);
    无效准备();
    作废预付款();
    ...
    }
    //GameState.cpp
    游戏状态::游戏状态(游戏状态*父、操作和操作)
    {
    此->prevState=parent;//指向上一个游戏状态的指针
    此->f1=父->f1;//游戏数据容器
    此->f2=父->f2;//游戏数据容器
    this->nextActions=std::vector();//我们将在此游戏状态下确定新的下一步操作
    //!!!问题:操作中存储的指针仍然指向父状态的游戏容器!
    //将动作传递到下一个游戏状态的正确方式是什么?
    这个->ownAction=动作;
    此->已访问=父->已访问;
    }
    游戏状态::准备()
    {
    //检查游戏条件
    //并创建下一步可能操作的列表
    如果(条件1){
    下一个动作。推回(动作(&f1和f2));
    }
    ...
    //有不同种类的行为
    //它们都继承自同一父类
    //为了简单起见,我只写了“动作”
    }
    GameState::advance()
    {
    ownAction.execute();//执行自己的操作->改变自己的状态
    prepare();//准备下一步操作的列表
    对于(size_t i=o;nextActions.size();++i){
    如果(!nextActions.at(i).inversed(ownAction)){//不允许后退!
    //将已更改状态和操作的副本传递到下一级别
    GameState*nextState=新的游戏状态(这个,nextActions.at(i));
    nextState->advance();
    nextStates.push_back(nextState);//存储指向下一个游戏状态的指针
    }
    }
    }
    //行动.h
    集体诉讼{
    私人:
    Foo*src;
    Foo*tgt;
    公众:
    行动(Foo*src,Foo*tgt);
    行动(施工行动和obj);
    ~Action();
    void execute();
    bool倒置(动作和其他);
    }
    //Action.cpp
    动作::动作(Foo*src,Foo*tgt)
    {
    这->src=src;
    这->tgt=tgt;
    }
    动作::动作(const动作和obj)
    {
    此->src=obj.src;
    这->tgt=obj.tgt;
    }
    动作::执行()
    {
    //大概是这样的:
    tgt.push_back(src.top());
    src.pop();
    //从一个引用的容器中移动值
    //放入另一个引用的容器中
    }
    

    编辑了代码,删除了不必要的部分。

    你的问题是什么?我想补充一点,我在帖子中提到的构造函数方法应该采取行动,这样每个游戏状态都会“知道”是哪个行动造成了它。请描述你的“技术困难”并删除所有与这些困难不直接相关的代码。然后这样做。一种方法:复制操作后,更新指针。或者有一个新的方法
    复制给新的所有者
    。怎么做取决于你自己。如果你对java更熟悉,你可以先找出如何在java中解决这个问题,然后将解决方案翻译成C++。
    // class GameState.h:
    class GameState {
    
    private:
        // The "Foos" are some sort of collection: vector, deque, whatever
        Foo f1;
        Foo f2;
        Action ownAction;
        std::vector<Action> nextActions;
    
        // Pointer to the previous GameState
        GameState * prevState;
        // Collection of pointers to the next GameStates
        vector<GameState*> nextStates;
    
    public:
        GameState(GameState * parent, Action & action);
        GameState(const GameState & obj);
        void prepare();
        void advance();
        ...
    }
    
    // GameState.cpp
    GameState::GameState(GameState * parent, Action & action)
    {
        this->prevState = parent; // pointer to previous GameState
        this->f1 = parent->f1; // game data container
        this->f2 = parent->f2; // game data container
        this->nextActions = std::vector<Action>(); // we'll determine new next actions in this GameState
    
        // !!! PROBLEM: pointers stored in the action are still pointing to the game containers of the parent state!
        // What is the proper way to pass an action to the next GameState?
        this->ownAction = action;
        this->visited = parent->visited;
    }
    
    GameState::prepare()
    {
        // Check game conditions 
        // and create a list of next possible Actions
        if (condition1) {
            nextActions.push_back(Action(&f1, &f2));
        }
    
        ...
    
        // there are different kinds of actions
        // which all inherit from the same parent class
        // so I just write "Action" for simplicity
    }
    
    GameState::advance()
    {
        ownAction.execute(); // execute own action -> alter own state
        prepare(); // prepare a list of next actions
    
        for(size_t i = o; nextActions.size(); ++i) {
            if (!nextActions.at(i).inverted(ownAction)) { // no steps back are allowed!
                // passing the copy of the altered state and the action to the next level
                GameState * nextState = new GameState(this, nextActions.at(i));
                nextState->advance();
                nextStates.push_back(nextState); // storing the pointer to the next GameState
            }
        }
    }
    
    // Action.h
    class Action {
    
    private:
        Foo * src;
        Foo * tgt;
    
    public:
        Action(Foo * src, Foo * tgt);
        Action(const Action & obj);
        ~Action();
        void execute();
        bool inverted(Action & other);
    }
    
    // Action.cpp    
    Action::Action(Foo * src, Foo * tgt)
    {
        this->src = src;
        this->tgt = tgt;
    }
    
    Action::Action(const Action & obj)
    {
        this->src = obj.src;
        this->tgt = obj.tgt;
    }
    
    Action::execute()
    {
        // something like this:
        tgt.push_back(src.top());
        src.pop();
        // moving values from the one referenced container
        // into another referenced container
    }