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;