package DragonNet::Games::Sudoku::Board; BEGIN { $diagnostics::DEBUG = 1, $diagnostics::PRETTY = 1 } use strict; use warnings; use criticism 'harsh'; use diagnostics -verbose; use Data::Dumper; use Perl::Tidy; Perl::Tidy::perltidy(); use DragonNet::Games::Sudoku::Board::Cell; # Initialise new Sudoku Board # Params: # size => Size of the new Sudoku Board (optional) # Returns: # Object of the class DragonNet::Games::Sudoku::Board sub new { my ($class, %options) = @_; my $self = bless({}, ref ($class) || $class); # Array with cells my @cells = (); # Get the size from the options # If size is not specified set it to 9 # If size is smaller than 9 set it to 9 (smallest Sudoku Board) # If the squareroot of size is not a natural number set it to the next smaller size my $size = $options{'size'} || 9; $size = 9 if $size < 9; $size = int(sqrt($size)) ** 2 if $size != int(sqrt($size)) ** 2; $self->{'size'} = $size; # Initialise cells for (my $row = 1; $row <= $size; $row++) { $cells[$row] = (); for (my $col = 1; $col <= $size; $col++) { $cells[$row][$col] = DragonNet::Games::Sudoku::Board::Cell->new(size => $size); } } $self->{'cells'} = \@cells; return $self; } # Initialise new Sudoku Board and set the values of the cells to the value at # the according string position # Params: # string => String with the values (if not specified creates an empty board) # Returns: # Object of the class DragonNet::Games::Sudoku::Board sub new_from_string { my ($class, %options) = @_; my $self = bless({}, ref ($class) || $class); # Array with cells my @cells = (); # If the parameter string is not specified create an empty board my $string = $options{'string'} || return $class->new(size => 9); # Get the size from the squareroot of the length of the string # If size is smaller than 9 set it to 9 (smallest Sudoku Board) # If the squareroot of size is not a natural number set it to the next smaller size my $size = int(sqrt(length($string))); $size = 9 if $size < 9; $size = int(sqrt($size)) ** 2 if $size != int(sqrt($size)) ** 2; $self->{'size'} = $size; # Split the string into chars my @string_parts = split(//, $string); for (my $row = 1; $row <= $size; $row++) { $cells[$row] = (); for (my $col = 1; $col <= $size; $col++) { my $value = $string_parts[($row - 1) * $size + ($col - 1)]; $value = -1 if ($value == 0); $cells[$row][$col] = DragonNet::Games::Sudoku::Board::Cell->new(size => $size, value => $value); } } $self->{'cells'} = \@cells; return $self; } # Prints the Board in a pretty way sub print_pretty { my ($self) = @_; for (my $row = 1; $row <= $self->{'size'}; $row++) { for (my $col = 1; $col <= $self->{'size'}; $col++) { my $value = $self->get_cell_value(row => $row, column => $col); if ($value == -1 || !$value) { print ' '; } else { print "$value "; } } print "\n"; } print "\n"; } # Gets a specific cell # Params: # row => Row of the cell # column => Column of the cell # Returns: # Returns an object of the class DragonNet::Games::Sudoku::Board::Cell (the specified cell) # or false if this cell does not exists sub get_cell { my ($self, %options) = @_; my $row = $options{'row'} or die "Parameter row not specified!"; my $col = $options{'column'} or die "Parameter column not specified!"; return if ($row < 1 || $row > $self->{'size'}); return if ($col < 1 || $col > $self->{'size'}); return $self->{'cells'}->[$row][$col]; } # Gets the value of a specific cell # Params: # row => Row of the cell # column => Column of the cell # Returns: # Returns the value of the specific cell # or false if this cell does not exists sub get_cell_value { my ($self, %options) = @_; my $cell = $self->get_cell(%options); return if (!ref $cell); return $cell->get_value(); } # Sets a specific cell value # Params: # row => Row of the cell # column => Column of the cell # value => new value of cell # Returns: # Returns true on success else false sub set_cell_value { my ($self, %options) = @_; my $row = $options{'row'} or die "Parameter row not specified!"; my $col = $options{'column'} or die "Parameter column not specified!"; my $value = $options{'value'} or die "Parameter value not specified!"; return if ($row < 1 || $row > $self->{'size'}); return if ($col < 1 || $col > $self->{'size'}); return $self->get_cell(row => $row, column => $col)->set_value(value => $value); } 1;