package GridFiller::Chooser::Random; use Moose; use namespace::autoclean; use GridFiller::Constants ':all'; use Carp; extends 'GridFiller::Chooser'; sub find_place_for { my ($self,$word) = @_; my $dir = int(rand(2)) ? $HORIZONTAL : $VERTICAL; my $length = $self->length->($word); my @ret; if ($dir == $HORIZONTAL) { @ret = $self->_find_place_horiz($length); @ret = $self->_find_place_vert($length) unless @ret; } else { @ret = $self->_find_place_vert($length); @ret = $self->_find_place_horiz($length) unless @ret; } return @ret; } sub _find_place_horiz { my ($self,$length) = @_; my $rows = scalar @{$self->grid}; my $col; for my $row (0..$rows-1) { $col = $self->_find_in_row($row,$length); return (0,$col,$row,$HORIZONTAL) if defined $col; } return; } sub _find_place_vert { my ($self,$length) = @_; my $cols = scalar @{$self->grid->[0]}; my $row; for my $col (0..$cols-1) { $row = $self->_find_in_col($col,$length); return (0,$col,$row,$VERTICAL) if defined $row; } return; } { my %symbols=( $NOTHING => ' ', $BLACK => 'X', $WHITE => 'O', ); sub _do_find { my ($self,$str,$length) = @_; my ($skip) = ($str =~ m{^ (.*?) (?: X{$length} | O{$length} ) }x); $self->log->debug(defined $skip ? " skip <$skip>" : " nope"); return length($skip) if defined $skip; return; } sub _find_in_row { my ($self,$row,$length) = @_; my $str = join '',map { $symbols{$_} } @{$self->grid->[$row]}; $self->log->debug("row $row = $str"); return $self->_do_find($str,$length); } sub _find_in_col { my ($self,$col,$length) = @_; my $str = join '',map { $symbols{$_->[$col]} } @{$self->grid}; $self->log->debug("col $col = $str"); return $self->_do_find($str,$length); } } 1;