Games-Nonogram

 view release on metacpan or  search on metacpan

lib/Games/Nonogram/Grid.pm  view on Meta::CPAN


  my $self = $class->new( height => $height, width => $width );

  $self->load( @lines );

  $self;
}

sub load {
  my ($self, @lines) = @_;

  my @clues = $self->clues;

  foreach my $line ( @lines ) {
    chomp $line;
    next unless $line =~ /^[\d,]+$/;

    my $clue = shift @clues;

    die "clues mismatch" unless ref $clue;

    $clue->set( split ',', $line );
  }

  die "clues mismatch" if @clues;

  $self->clear_stash;
  $self->is_dirty( 1 );
  $self->{has_answers} = 0;
}

sub rows  { @{ shift->{rows} } }
sub cols  { @{ shift->{cols} } }
sub clues { my $self = shift; return ( $self->rows, $self->cols ) }
sub row   { my ($self, $id) = @_; $self->{rows}->[$id - 1]; }
sub col   { my ($self, $id) = @_; $self->{cols}->[$id - 1]; }

sub is_dirty {
  my $self = shift;
  @_ ? $self->{is_dirty} = shift : $self->{is_dirty};
}

sub as_string {
  my $self = shift;

  my $str = '';
  foreach my $row ( $self->rows ) {
    $str .= sprintf "%s\n", $row->as_string;
  }
  if ( $self->debug ) {
    $str .= "\n";

    foreach my $col ( $self->cols ) {
      $str .= sprintf "%s\n", $col->as_string;
    }
  }

  defined wantarray ? return $str : print $str;
}

sub update {
  my ($self, $mode) = @_;

  $self->log( 'updating' );

  $self->is_dirty( 0 );
  foreach my $row ( 1 .. $self->{height} ) {
    my $clue = $self->row( $row );

    next if $clue->is_done && !$clue->line->is_dirty;

    $self->_update( $clue, $mode );

    foreach my $col ( $clue->line->dirty_items ) {
      $self->is_dirty( 1 );
      $self->_update_dirty_item(
        $self->col( $col ),
        $row,
        $clue->line->value( $col )
      );
    }
  }

  foreach my $col ( 1 .. $self->{width} ) {
    my $clue = $self->col( $col );

    next if $clue->is_done && !$clue->line->is_dirty;

    $self->_update( $clue, $mode );

    foreach my $row ( $clue->line->dirty_items ) {
      $self->is_dirty( 1 );
      $self->_update_dirty_item(
        $self->row( $row ),
        $col,
        $clue->line->value( $row )
      );
    }
  }
  return if $self->is_dirty;
  return if $self->is_done;

  unless ( $mode ) {
    $self->update( 'more' );
  }
  elsif ( $mode eq 'more' ) {
    require Games::Nonogram::BruteForce;
    Games::Nonogram::BruteForce->run( $self );

    if ( $self->answers ) {
      $self->{has_answers} = 1;
    }
  }
}

sub has_answers { shift->{has_answers} }

sub answers {
  my $self = shift;

  my %seen;



( run in 1.770 second using v1.01-cache-2.11-cpan-39bf76dae61 )