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