// function ONLINE-DFS-AGENT(s') returns an action // inputs: s', a percept that identifies the current state public override IAction Execute(IPercept psPrimed) { S sPrimed = ptsFn(psPrimed); // if GOAL-TEST(s') then return stop if (problem.testGoal(sPrimed)) { a = default(A); } else { // if s' is a new state (not in untried) then untried[s'] <- // ACTIONS(s') if (!untried.ContainsKey(sPrimed)) { untried.Put(sPrimed, problem.getActions(sPrimed)); } // 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 (!(sPrimed.Equals(result.Get(s, a)))) { // result[s, a] <- s' result.Put(s, a, sPrimed); // Ensure the unbacktracked always has a list for s' if (!unbacktracked.ContainsKey(sPrimed)) { unbacktracked.Put(sPrimed, CollectionFactory.CreateQueue <S>()); } // add s to the front of the unbacktracked[s'] unbacktracked.Get(sPrimed).Insert(0, s); } } // if untried[s'] is empty then if (untried.Get(sPrimed).IsEmpty()) { // if unbacktracked[s'] is empty then return stop if (unbacktracked.Get(sPrimed).IsEmpty()) { a = default(A); } else { // else a <- an action b such that result[s', b] = // POP(unbacktracked[s']) S popped = unbacktracked.Get(sPrimed).Pop(); foreach (Pair <S, A> sa in result.GetKeys()) { if (sa.GetFirst().Equals(sPrimed) && result.Get(sa).Equals(popped)) { a = sa.getSecond(); break; } } } } else { // else a <- POP(untried[s']) a = untried.Get(sPrimed).Pop(); } } if (a == null) { // 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 = sPrimed; // return a return(a); }