godmode-as3 icon indicating copy to clipboard operation
godmode-as3 copied to clipboard

IterateSelector

Open mikecann opened this issue 11 years ago • 4 comments

I have a need for a selector that iterates over each child regardless that it passed or fails, it will still wait if the Task returns RUNNING however.

Its basically just a modified version of the SequenceSelector, not sure if this is the best way to do this or not:

   public class IterateSelector extends SequenceSelector
{
    override protected function updateTask (dt :Number) :int {
        while (_childIdx < _children.length) {
            _curChild = _children[_childIdx];
            var childStatus :int = _curChild.update(dt);
            if (childStatus == SUCCESS || childStatus==FAIL) {
                // the child completed. Move on to the next.
                _curChild = null;
                _childIdx++;
            } else {
                // RUNNING return immediately
                return childStatus;
            }
        }

        // all our children have completed successfully
        return SUCCESS;
    }
}

mikecann avatar Apr 11 '13 13:04 mikecann

Hmm, perhaps a better way to do this is with a "StatusInvertingDecorator" that converts a FAIL to a SUCCESS of the task that it decorates.

mikecann avatar Apr 11 '13 13:04 mikecann

Either of these approaches seems reasonable to me! Your IterateSelector will end up allocating fewer nodes in the tree, so it's probably the direction I'd go (since I'm developing a mobile game where memory is scarce).

What's the particular scenario that you're modeling here, out of curiosity?

tconkling avatar Apr 11 '13 17:04 tconkling

Great, ye I like simpler trees, makes it easier to understand too. Without any sort of visual editor these trees can get complex pretty quick.

Im developing a prototype of a turn based RTS game. You can play an early version of it here (http://mikecann.co.uk/projects/acunningplan/)

The behavior I need the IterateSelector selector for is the potential moves that an AI unit can make. Take the queen for example it could build then move or it could move then build. I need a way to ensure that a build fail doesnt block the queen from potentially making a move.

mikecann avatar Apr 12 '13 10:04 mikecann

Ah just found a need for another type of Selector a "Success" selector that only returns when one of the children is successful (or it runs out of children to run).

public class SuccessSelector extends SequenceSelector { override protected function updateTask (dt :Number) :int { while (_childIdx < _children.length) { _curChild = _children[_childIdx]; var childStatus :int = _curChild.update(dt); if (childStatus==FAIL) { // the child completed. Move on to the next. _curChild = null; _childIdx++; } else { // RUNNING return immediately return childStatus; } }

        // all our children have completed successfully
        return SUCCESS;
    }
}

I guess I should probably make this more generic and parameterise it like you have done with the ParallellSelector.

mikecann avatar Apr 12 '13 12:04 mikecann