我正在编写代码来自动模拟忒修斯和牛头怪的动作,如这个逻辑游戏所示;http://www.logicmazes.com/theseus.html
对于每个迷宫,我为其提供迷宫的位置,以及哪些位置可用,例如从位置 0 开始,下一个状态是 1,2 或保持在 0。我运行一个 QLearning 实例化,它计算出忒修斯逃离迷宫的最佳路径假设没有牛头怪。然后介绍牛头怪。忒修斯向出口迈出第一步,不可避免地被抓住,导致重新调整最佳路径。在游戏中使用迷宫 3 作为测试,这种方法导致忒修斯在中间线上上下移动,因为这是唯一没有杀死它的移动。
根据最近几天在这里收到的建议,我调整了我的代码以将状态视为在给定时间的忒修斯和牛头怪的位置。当忒修斯移动时,状态将被添加到“访问状态”列表中。通过将建议移动产生的状态与访问状态列表进行比较,我能够确保忒修斯不会做出会导致以前的状态。
问题是我需要能够在某些情况下重新访问。例如,以迷宫 3 为例,牛头怪每移动一次忒修斯移动 2 倍。忒修斯移动 4 -> 5,添加状态(t5,m1)。米诺移动1-> 5。忒修斯抓住了,重置。4-> 5 是一个糟糕的举动,所以忒修斯移动 4-> 3,mino 轮到他了。现在(t5,m1)和(t3 m1)都在访问列表中
发生的情况是将初始状态中的所有可能状态添加到不访问列表中,这意味着我的代码无限循环并且无法提供解决方案。
public void move()
{
int randomness =10;
State tempState = new State();
boolean rejectMove = true;
int keepCurrent = currentPosition;
int keepMinotaur = minotaurPosition;
previousPosition = currentPosition;
do
{
minotaurPosition = keepMinotaur;
currentPosition = keepCurrent;
rejectMove = false;
if (states.size() > 10)
{
states.clear();
}
if(this.policy(currentPosition) == this.minotaurPosition )
{
randomness = 100;
}
if(Math.random()*100 <= randomness)
{
System.out.println("Random move");
int[] actionsFromState = actions[currentPosition];
int max = actionsFromState.length;
Random r = new Random();
int s = r.nextInt(max);
previousPosition = currentPosition;
currentPosition = actions[currentPosition][s];
}
else
{
previousPosition = currentPosition;
currentPosition = policy(currentPosition);
}
tempState.setAttributes(minotaurPosition, currentPosition);
randomness = 10;
for(int i=0; i<states.size(); i++)
{
if(states.get(i).getMinotaurPosition() == tempState.getMinotaurPosition() && states.get(i).theseusPosition == tempState.getTheseusPosition())
{
rejectMove = true;
changeReward(100);
}
}
}
while(rejectMove == true);
states.add(tempState);
}
以上是忒修斯的移动方法;偶尔显示它暗示随机移动