Algorithm-MasterMind

 view release on metacpan or  search on metacpan

lib/Algorithm/MasterMind.pm  view on Meta::CPAN

package Algorithm::MasterMind;

use warnings;
use strict;
use Carp;

use version; our $VERSION = qv("v0.4.5");  #Quest for non-failing tests

use Algorithm::Combinatorics qw(variations_with_repetition);

#use Memoize;
#memoize( "check_rule" );

our @ISA = qw(Exporter);

our @EXPORT_OK = qw( check_combination partitions entropy random_string 
		     response_as_string);

use lib qw( ../../lib ../lib ../../../lib );

# Module implementation here

sub new {

  my $class = shift;
  my $options = shift || croak "Need options here in Algorithm::MasterMind::New\n";

  my $self =  { _rules => [],
		_evaluated => 0,
		_hash_rules => {} };

  bless $self, $class;
  $self->initialize( $options );
  return $self;
}

sub random_combination {
  my $self = shift;
  return random_string( $self->{'_alphabet'}, $self->{'_length'});
}

sub random_string {
  my $alphabet = shift;
  my $length = shift;
  my $string;
  my @alphabet = @{$alphabet};
  for (my $i = 0; $i <  $length; $i++ ) {
    $string .= $alphabet[ rand( @alphabet) ];
  }
  return $string;
}

sub issue_first { #Default implementation
  my $self = shift;
  return $self->{'_last'} = $self->random_combination;
}

sub start_from {
  my $class = shift;
  my $options = shift || croak "Options needed to start!";

  my $self = {};
  bless $self, $class;
  for my $o ( qw( consistent alphabet rules evaluated ) ) {
    $self->{"_$o"} = $options->{$o};
  }
  return $self;
}

sub issue_first_Knuth {
  my $self = shift;
  my $string;
  my @alphabet = @{ $self->{'_alphabet'}};
  my $half = @alphabet/2;
  for ( my $i = 0; $i < $self->{'_length'}; $i ++ ) {
    $string .= $alphabet[ $i % $half ]; # Recommendation Knuth
  }
  $self->{'_first'} = 1; # Flag to know when the second is due
  return $self->{'_last_string'} = $string;
}

sub issue_next {
  croak "To be reimplemented in derived classes";
}

sub add_rule {
  my $self = shift;
  my ($combination, $result) = @_;
  my %new_rule = %$result;
  $new_rule{'combination'} = $combination;
  push @{ $self->{'_rules'} }, \%new_rule;

}

sub feedback {
  my $self = shift;
  my ($result) = @_;
  $self->add_rule( $self->{'_last'}, $result );
}

sub number_of_rules {
  my $self= shift;
  return scalar @{ $self->{'_rules'}};
}

sub rules {
  my $self= shift;
  return   $self->{'_rules'};
}

sub evaluated {
  my $self=shift;
  return $self->{'_evaluated'};
}

sub matches {

  my $self = shift;
  my $string = shift || croak "No string\n";
  my @rules = @{$self->{'_rules'}};
  my $result = { matches => 0,
		 result => [] };
#  print "Checking $string, ", $self->{'_evaluated'}, "\n";



( run in 0.355 second using v1.01-cache-2.11-cpan-39bf76dae61 )