use v5.14; package TheGame { use Moo; use POSIX qw(floor ceil); has in => (is => 'ro', default => sub { \*STDIN }); has out => (is => 'ro', default => sub { \*STDOUT }); has lower_bound => (is => 'rw'); has upper_bound => (is => 'rw'); has guess_count => (is => 'rw', default => sub { 0 }); has guess_technique => (is => 'ro', default => sub { 'random' }); sub play { my $self = shift->new(@_); printf {$self->out} ( "Choose a number between %d and %d!\n", $self->lower_bound, $self->upper_bound, ); sleep(2); GUESS: { my $guess = $self->make_guess; my $wrong = $self->analyse_guess($guess); if ($wrong and $self->upper_bound <= $self->lower_bound) { die "stop cheating!"; } if ($wrong > 0) { # too high $self->upper_bound($guess - 1); redo GUESS; } if ($wrong < 0) { # too low $self->lower_bound($guess + 1); redo GUESS; } } printf {$self->out} ( "Got it in %d guesses!\n", $self->guess_count, ); } sub make_guess { my $self = shift; state $toggle = 0; my $guess; if ($self->guess_technique =~ /good/) { my $diff = $self->upper_bound - $self->lower_bound; $guess = floor( + ($self->upper_bound / 2) + ($self->lower_bound / 2) + ($diff / 10) -rand($diff / 5) ); } elsif ($self->guess_technique =~ /halves/) { $guess = floor( + ($self->upper_bound / 2) + ($self->lower_bound / 2) ); } elsif ($self->guess_technique =~ /thirds/) { my $upper_or_lower = (++$toggle % 2) ? $self->upper_bound : $self->lower_bound; $guess = floor( + ($self->upper_bound / 3) + ($self->lower_bound / 3) + ($upper_or_lower / 3) ); } else # random number in the range { $guess = floor( + $self->lower_bound + rand($self->upper_bound - $self->lower_bound) ); } $guess++ while $guess < $self->lower_bound; $guess-- while $guess > $self->upper_bound; $self->guess_count( $self->guess_count + 1 ); return $guess; } sub analyse_guess { my ($self, $guess) = @_; printf {$self->out} ( "My guess is %d. Am I 'too high', 'too low' or 'right'? " +, $guess, ); ANSWER: { my $in = $self->in; my $answer = <$in>; return 0 if $answer =~ m{ (right) | (correct) }x; return 1 if $answer =~ m{ (too \s* high) | (lower) }x; return -1 if $answer =~ m{ (too \s* low) | (higher) }x; print {$self->out} "Sorry... what was that? "; redo ANSWER; } } } TheGame->play(lower_bound => 1, upper_bound => 1000, guess_technique = +> 'good');
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

In reply to Re: Number Guessing Game by tobyink
in thread Number Guessing Game by randomhero1270

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.