public override Action execute(Percept psPrime)
{
Object sPrime = ptsFunction.getState(psPrime);
// if GOAL-TEST(s') then return stop
if (goalTest(sPrime))
{
a = NoOpAction.NO_OP;
}
else
{
// if s' is a new state (not in untried) then untried[s'] <-
// ACTIONS(s')
if (!untried.containsKey(sPrime))
{
untried.put(sPrime, actions(sPrime));
}
// if s is not null then do
if (null != s)
{
// Note: If I've already seen the result of this
// [s, a] then don't put it back on the unbacktracked
// list otherwise you can keep oscillating
// between the same states endlessly.
if (!(sPrime.Equals(result.get(s, a))))
{
// result[s, a] <- s'
result.put(s, a, sPrime);
// Ensure the unbacktracked always has a list for s'
if (!unbacktracked.containsKey(sPrime))
{
unbacktracked.put(sPrime, new List<Object>());
}
// add s to the front of the unbacktracked[s']
unbacktracked.get(sPrime).Add(0, s);
}
}
// if untried[s'] is empty then
if (untried.get(sPrime).isEmpty())
{
// if unbacktracked[s'] is empty then return stop
if (unbacktracked.get(sPrime).isEmpty())
{
a = NoOpAction.NO_OP;
}
else
{
// else a <- an action b such that result[s', b] =
// POP(unbacktracked[s'])
Object popped = unbacktracked.get(sPrime).remove(0);
foreach (Pair<Object, Action> sa in result.keySet())
{
if (sa.getFirst().Equals(sPrime)
&& result.get(sa).Equals(popped))
{
a = sa.getSecond();
break;
}
}
}
}
else
{
// else a <- POP(untried[s'])
a = untried.get(sPrime).remove(0);
}
}
if (a.isNoOp())
{
// I'm either at the Goal or can't get to it,
// which in either case I'm finished so just die.
setAlive(false);
}
// s <- s'
s = sPrime;
// return a
return a;
}