package GridFiller::Status; use Moose; use namespace::autoclean; use List::Util qw(shuffle); use List::MoreUtils qw(uniq); use GridFiller::Types qw(WordListT GridStatusT); use GridFiller::Constants ':all'; use Carp; with 'MooseX::Log::Log4perl'; has words_to_use => ( isa => WordListT, traits => ['Array'], handles => { has_next_word => 'count', get_next_word => 'shift', }, is => 'rw', required => 1, ); has grid_status => ( isa => GridStatusT, is => 'rw', required => 1, ); around BUILDARGS => sub { my ($orig, $class, $args, @rest) = @_; if (exists $args->{words} && exists $args->{grid}) { $args->{words_to_use} = _munge_words_to_use(delete $args->{words}); $args->{grid_status} = _munge_grid_status(delete $args->{grid}); } return $class->$orig($args,@rest); }; sub _munge_words_to_use { my $words=shift; # clone initial word list return [ shuffle uniq @$words ]; } sub _munge_grid_status { my $grid=shift; return [ map { [ map { $_ eq '*' ? $BLACK : $WHITE } @$_ ] } @$grid ]; } sub place_word_at { my ($self, $word, $x, $y, $dir) = @_; $self->log->debug("Marking <$word> occupied at ${x}:${y} ($dir)"); if ($dir == $HORIZONTAL) { for my $i (0..length($word)-1) { $self->_mark_occupied($x+$i,$y); } } elsif ($dir == $VERTICAL) { for my $i (0..length($word)-1) { $self->_mark_occupied($x,$y+$i); } } else { croak "What dir $dir?"; } } sub _mark_occupied { my ($self,$x,$y) = @_; $self->grid_status->[$y][$x]=$NOTHING; return; } sub unfilled { my ($self) = @_; for my $row (@{$self->grid_status}) { for my $cell (@$row) { return 1 if $cell != $NOTHING; } } return 0; } { my %symbols=( $NOTHING => ' ', $BLACK => 'X', $WHITE => 'O', ); sub to_string { my ($self) = @_; my $rows = scalar @{$self->grid_status}; my $str; for my $row (0..$rows-1) { for my $cell (@{$self->grid_status->[$row]}) { $str .= $symbols{$cell}; } $str .= "\n"; } return $str; } } 1;