Dreamhack-Solitaire-Medici
view release on metacpan or search on metacpan
lib/Dreamhack/Solitaire/Medici.pm view on Meta::CPAN
package Dreamhack::Solitaire::Medici;
use 5.008001;
use strict;
use warnings;
no warnings 'recursion';
use base 'Dreamhack::Solitaire';
use Dreamhack::Solitaire;
our $VERSION = "0.01";
sub process {
my ($self, %args) = @_;
my $imax = (exists $args{'attempts'}) && ($args{'attempts'} =~ m/^[1-9]\d*$/) ? $args{'attempts'} : $self->_iterations(1+$#{$self->{'leftcards'}});
for my $i (1..$imax) {
my @layout = $self->add_rnd_layout();
my @save = @layout;
my @work = ();
my $cardno = 0;
while (@layout) {
my $el = shift @layout;
push @work, $el;
@work = $self->_pass(0, \@work, $cardno++);
}
$self->{'attempts'} = $i;
if ($#work <= 1) {
$self->{'layout'} = \@save;
return $self;
}
$self->{'convolution'} = [];
}
return undef;
}
sub _pass {
my ($self, $offset, $work, $cardno) = @_;
my @work = @$work;
if (($offset >=0) && ($#work - $offset >= 2)) {
my ($vr, $sr) = $self->extract($work[$#work - $offset]);
my ($vl, $sl) = $self->extract($work[$#work - $offset - 2]);
if (($vl eq $vr) or ($sl eq $sr)) {
$work[$#work - $offset - 2] = $work[$#work - $offset - 1];
splice @work, $#work - $offset - 1, 1;
if ($cardno) {
push @{$self->{'convolution'}}, $cardno;
}
@work = $self->_pass($#work-2, \@work);
}
else {
@work = $self->_pass(--$offset, \@work);
}
}
else {
return @work
}
return @work
}
sub _iterations {
my ($self, $cardscount) = @_;
my $imax = 0;
if ($cardscount <= 1) {
$imax = 1;
}
else {
$imax = 100_000;
}
return $imax
}
1;
__END__
=encoding utf-8
=head1 NAME
Dreamhack::Solitaire::Medici - Kit for Solitaire Medici
=head1 SYNOPSIS
use Dreamhack::Solitaire::Medici;
my $sol = Dreamhack::Solitaire::Medici->new();
$sol->init_layout([qw(Jh ? Ac 10s ? ? Kd)]);
$sol->process() or die 'Cannot build solitaire, attempts count: ', $sol->{'attempts'};
print $sol->format();
print "Attempts count: ", $sol->{'attempts'}, "\n";
or, for empty starting layout:
print Dreamhack::Solitaire::Medici->new()->process()->format();
or, for russian programmers:
print Dreamhack::Solitaire::Medici->new(lang=>'ru_RU.utf8')->process()->format();
In this case you mast use cyrrilic cards abbr for init layout.
=head1 DESCRIPTION
The Solitaire Medici, particular using by dreamhackers/stalkers for reality management.
Chain creation carried out by bruteforce method with max attempts count one hundred thousand (default) or your own value.
Starting layout between 0 and 36 cards.
=head1 ABBR FOR DECK
=over
=item Suits
s - Spades
c - Clubs
d - Diamonds
h - Hearts
( run in 0.750 second using v1.01-cache-2.11-cpan-71847e10f99 )