package GridFiller;
use Moose;
use namespace::autoclean;
use GridFiller::Types qw(GridT WordListT );
use MooseX::Types::Moose qw(CodeRef);
use GridFiller::Status;
use GridFiller::Result::Text;
use GridFiller::Chooser::Smarter;
use Carp;
use Class::MOP;
with 'MooseX::Log::Log4perl';
has words => (
isa => WordListT,
required => 1,
is => 'ro',
);
has grid => (
isa => GridT,
required => 1,
is => 'ro',
);
has status => (
isa => 'GridFiller::Status',
is => 'ro',
writer => '_status',
lazy_build => 1,
);
sub _build_status {
my ($self) = @_;
return GridFiller::Status->new({
words => $self->words,
grid => $self->grid,
});
}
has chooser => (
isa => 'GridFiller::Chooser',
is => 'rw',
lazy_build => 1,
);
sub _build_chooser {
my ($self) = @_;
return GridFiller::Chooser::Smarter->new({
status => $self->status,
});
}
has result => (
isa => 'GridFiller::Result',
is => 'rw',
lazy_build => 1,
);
sub _build_result {
my ($self) = @_;
return GridFiller::Result::Text->new({
source_grid => $self->grid,
});
}
sub fill {
my ($self) = @_;
my $status=$self->status;
my $result=$self->result;
my $chooser=$self->chooser;
$status->reset;
$result->reset;
while ($status->unfilled() && $status->has_next_word()) {
my $word = $status->get_next_word();
$self->log->debug("Placing $word");
my ($x,$y,$dir) = $chooser->find_place_for($word);
if (! defined $x) {
$self->log->debug("No place for $word");
$result->mark_leftover($word);
next;
};
$result->place_word_at($word,$x,$y,$dir);
$status->place_word_at($word,$x,$y,$dir);
if ($self->log->is_debug) {
$self->log->debug($status->to_string);
$self->log->debug($result->to_string);
}
}
return;
}
1;