# $final_position = depth_first( $position )
sub depth_first {
    my @positions = shift;

    while ( my $position = pop( @positions ) ) {
        return $position if $position->is_answer;

        # If this was not the final answer, try each position that
        # can be reached from this one.
        $position->prepare_moves;
        my $move;
        while ( $move = $position->next_move ) {
            push ( @positions, $position->make_move($move) );
        }
    }
    # No answer found.
    return undef;
}

# $final_position = breadth_first( $position )
sub breadth_first {
    my @positions = shift;

    while ( my $position = shift( @positions ) ) {
        return $position if $position->is_answer;

        # If this was not the final answer, try each position that
        # can be reached from this one.
        $position->prepare_moves;
        my $move;
        while ( $move = $position->next_move ) {
            push ( @positions, $position->make_move($move) );
        }
    }
    # No answer found.
    return undef;
}
