Acme-Wabby

 view release on metacpan or  search on metacpan

Wabby.pm  view on Meta::CPAN

        # sentence starting points.  Thus, let's grab a random entry out of the
        # 0th element in the list and start there.
        $start = ${${$self->{'data'}{'list'}}[0]{'num'}}[int rand scalar @{${$self->{'data'}{'list'}}[0]{'num'}}];
        $text = ${$self->{'data'}{'list'}}[$start]{'word'};
    }

    # Since we're dealing with randomness, we can't always be sure that we'll
    # be able to make a sentence of min_len, so we just keep retrying up to
    # max_attempts times, relying on sheer dumb luck to help us out.  On a
    # reasonably-sized body of text, this works perfectly fine.
    my $attempts = 0;
    my $count = 0;
    my $final = "";
    my $next = $start;

    while ($count < $self->{'conf'}{'min_len'} &&
            $attempts < $self->{'conf'}{'max_attempts'}) {

        # We start out with one word, and uppercase the first character in our
        # starting text.
        $count = 1;
        $final = "\u$text";
        $next = $start;

        # Keep adding new words to this sentence until we hit an sentence end
        # mark, or we hit max_len
        while ($next != -1 && ($count < $self->{'conf'}{'max_len'})) {

            # If the word we're on has no transitions, count this as a stopping
            # point, since we can't go any further.
            if (scalar(@{${$self->{'data'}{'list'}}[$next]{'num'}}) < 1) {
                $next = -1;
            }
            # Otherwise, randomly pick the word we'll visit next out of the
            # list of possible transitions from our current word.
            else {
                $next = ${${$self->{'data'}{'list'}}[$next]{'num'}}[int rand scalar @{${$self->{'data'}{'list'}}[$next]{'num'}}];
            }

            # If we're not at the end yet, add this word to our collected
            # string, increment our word count, and do it all again. 
            if ($next != -1) {
                $final .= " " . ${$self->{'data'}{'list'}}[$next]{'word'};
                $count++;
            }
        }

        # If we failed to make a long enough sentence, we need to do something.
        if ($count < $self->{'conf'}{'min_len'}) {

            # If we haven't yet passed our max number of attempts, try again.
            if ($attempts < $self->{'conf'}{'max_attempts'}) {
                $attempts++;
                next;
            }
            # If we passed our max number of attempts, we can take one of two
            # course of action.
            else {
                # If we're trying to talk about something in particular, we're
                # always going to be stuck with the same starting point.  Thus,
                # there's not the best chance for continued success, so just
                # give up and bail.
                if ($directed) {
                    return undef;
                }
                # If we're talking about random things, we likely just got
                # a bad starting point, so we'll pick a new random starting
                # point, and do the whole thing over again.
                else {
                    $attempts = 0;
                    $start = ${${$self->{'data'}{'list'}}[0]{'num'}}[int rand scalar @{${$self->{'data'}{'list'}}[0]{'num'}}];
                    $text = ${$self->{'data'}{'list'}}[$start]{'word'};
                    next;
                }
            }
        }
    }

    # If we're not case sensitive, make sure any I's by themselves are
    # capitalized, for aesthetic purposes.  If we are, they probably want
    # things to come out the way they are.
    # FIXME - Need to be able to configure this so that persons with
    # non-english texts can pick values that make sense.
    unless ($self->{'conf'}{'case_sensitive'}) {
        $final =~ s/(^|[^\w-])i($|[^\w-])/$1I$2/g
    }

    # Pick a random piece of punctuation to add to the end of the sentence.
    $final .= ${$self->{'conf'}{'punctuation'}}[int rand scalar @{$self->{'conf'}{'punctuation'}}];

    return $final;
}

# A method for getting some basic information about the current state.
# Arguments: None.
# Returns:   In a scalar context, this function returns a string describing the
#            current state.  In a list context, this function returns a list
#            containing two numbers -- the first one is the number of words
#            that this object knows about, and the second one is the average
#            number of transitions between words.
sub stats {
    my $self = shift;
    die "Invalid object" unless (ref($self) eq __PACKAGE__);

    # Get the number of words in our hash.
    my $word_count = scalar keys %{$self->{'data'}{'hash'}};

    # If we've got no words, just quit now.
    if ($word_count == 0) {
        return wantarray ? (0,0) : "I don't know anything!";
    }

    # Iterate over the list, adding up the number of transitions for each word.
    my $average = 0;
    foreach (@{$self->{'data'}{'list'}}) {
        $average += scalar @{$_->{'num'}} if defined($_->{'num'});
    }

    # Calculate an average, trim it to two decimal points, and return it.
    $average /= $word_count;
    $average = sprintf "%.2f", $average;



( run in 1.321 second using v1.01-cache-2.11-cpan-7f9471e7e0a )