diff options
author | dakkar <dakkar@thenautilus.net> | 2010-11-25 21:16:35 +0000 |
---|---|---|
committer | dakkar <dakkar@thenautilus.net> | 2010-11-25 21:16:35 +0000 |
commit | 26f864e4b84dfae2364b6e7f42818df2b4ec5f1e (patch) | |
tree | dafd3bddd139049acfb4eccdf56a015abc3bb3e4 /lib/GridFiller/Result.pm | |
parent | use the real data (diff) | |
download | qr-builder-26f864e4b84dfae2364b6e7f42818df2b4ec5f1e.tar.gz qr-builder-26f864e4b84dfae2364b6e7f42818df2b4ec5f1e.tar.bz2 qr-builder-26f864e4b84dfae2364b6e7f42818df2b4ec5f1e.zip |
big refactoring
Diffstat (limited to 'lib/GridFiller/Result.pm')
-rw-r--r-- | lib/GridFiller/Result.pm | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/GridFiller/Result.pm b/lib/GridFiller/Result.pm new file mode 100644 index 0000000..56ae3c2 --- /dev/null +++ b/lib/GridFiller/Result.pm @@ -0,0 +1,144 @@ +package GridFiller::Result; +use Moose; +use namespace::autoclean; +use GridFiller::Types qw(GridT ResultT WordListT); +use GridFiller::Constants ':directions'; +use Carp; + +with 'MooseX::Log::Log4perl'; + +has leftover_words => ( + isa => WordListT, + is => 'ro', + default => sub { [ ] }, + traits => ['Array'], + handles => { + mark_leftover => 'push', + }, +); + +has grid => ( + isa => ResultT, + is => 'ro', + lazy_build => 1, +); + +has source_grid => ( + isa => GridT, + is => 'ro', +); + +{ +my %colourmap = ( + '*' => { + $HORIZONTAL => { + 0 => 1, + 1 => 2, + }, + $VERTICAL => { + 0 => 3, + 1 => 4, + }, + }, + ' ' => { + $HORIZONTAL => { + 0 => 5, + 1 => 6, + }, + $VERTICAL => { + 0 => 7, + 1 => 8, + }, + }, +); + +sub _build_grid { + return [ + map { + [ + map { + [ $colourmap{$_}->{$HORIZONTAL}->{0}, ' ' ], + } @$_ + ] + } @{shift->source_grid} + ]; +} + +sub _find_colour_for { + my ($self,$x,$y,$dir) = @_; + + my $parity = ($dir == $HORIZONTAL) ? ($y % 2) : ($x % 2); + + my $chosen = $colourmap{$self->source_grid->[$y][$x]}->{$dir}->{$parity}; + + # avoid colour runs + if ( ( $x>0 && $dir == $HORIZONTAL && $self->grid->[$y][$x-1][0] == $chosen ) + or + ( $y>0 && $dir == $VERTICAL && $self->grid->[$y-1][$x][0] == $chosen ) + ) { + $chosen = $colourmap{$self->source_grid->[$y][$x]}->{$dir}->{1-$parity}; + } + + if (!defined $chosen) { + $self->log->warn(sprintf(q{Can't decide on colour for %d:%d (%s) direction %d}, + $x,$y,$self->source_grid->[$y][$x],$dir)); + } + + return $chosen; +} +} + +sub place_word_at { + my ($self, $word, $x, $y, $dir) = @_; + + my $colour = $self->_find_colour_for($x,$y,$dir); + + $self->log->debug("Placing $word at ${x}:${y} ($dir) in colour $colour"); + + if ($dir == $HORIZONTAL) { + for my $i (0..length($word)-1) { + $self->_put_letter_at(substr($word,$i,1), + $x+$i,$y, + $colour); + } + } + elsif ($dir == $VERTICAL) { + for my $i (0..length($word)-1) { + $self->_put_letter_at(substr($word,$i,1), + $x,$y+$i, + $colour); + } + } + else { + croak "What dir $dir?"; + } +} + +sub _put_letter_at { + my ($self,$letter,$x,$y,$colour) = @_; + + croak "undef colour" unless defined $colour; + croak "undef letter" unless defined $letter; + + $self->grid->[$y][$x]=[$colour,$letter]; + return; +} + +sub to_string { + my ($self) = @_; + + my $rows = scalar @{$self->grid}; + + my $str; + + for my $row (0..$rows-1) { + for my $cell (@{$self->grid->[$row]}) { + $str .= $cell->[1] eq ' ' ? '.' : $cell->[1]; + } + $str .= "\n"; + } + + return $str; +} + +1; |