1. Shlomi Fish
  2. nurikabe

Commits

shl...@b384bcd7-cfd4-0310-aca0-d78b80f7b91b  committed 5025859

Started added the solve_using_adjacent_whites method.

The solve using adjacent whites tries to see if there are different
islands with white cells which are close enough to mark the cells between
them as black.

  • Participants
  • Parent commits 99a3a98
  • Branches default

Comments (0)

Files changed (2)

File nurikabe-solver/Games-Nurikabe-Solver/lib/Games/Nurikabe/Solver/Board.pm

View file
  • Ignore whitespace
     return \@ret;
 }
 
+sub _is_in_bounds
+{
+    my ($self, $y, $x) = @_;
+
+    return
+        (
+            ($y >= 0) && ($y < $self->_height())
+         && ($x >= 0) && ($x < $self->_width())
+        );
+}
+
 sub _solve_using_surrounded_by_blacks
 {
     my $self = shift;
     return \@moves;
 }
 
+sub _solve_using_adjacent_whites
+{
+    my $self = shift;
+
+    my @moves;
+
+    foreach my $y (0 .. ($self->_height()-1))
+    {
+        X_LOOP:
+        foreach my $x (0 .. ($self->_width()-1))
+        {
+            my $cell = $self->get_cell($y,$x);
+
+            if (! (($cell->status() eq $NK_WHITE) && defined($cell->island())))
+            {
+                next X_LOOP;
+            }
+
+            my $offset = [1,1];
+            my $blacks_offsets = [[0,1],[1,0]];
+
+            # Other X and Other Y
+            my $other_coords = [$y + $offset->[0], $x + $offset->[1]];
+            
+            if ($self->_is_in_bounds(@$other_coords))
+            {
+                my $other_cell = $self->get_cell(@$other_coords);
+                
+                if (   ($other_cell->status() eq $NK_WHITE)
+                    && defined($other_cell->island())
+                    && ($other_cell->island() != $cell->island()))
+                {
+                    # Bingo.
+                    foreach my $b_off (@$blacks_offsets)
+                    {
+                        my $b_coords = [$y + $b_off->[0], $x + $b_off->[1]];
+                        $self->_mark_as_black(@$b_coords);
+                    }
+                    if (@{$self->_verdict_marked_cells()->{$NK_BLACK}})
+                    {
+                        push @moves,
+                            Games::Nurikabe::Solver::Move->new(
+                                {
+                                    reason => "adjacent_whites",
+                                    verdict_cells => $self->_flush_verdict_marked_cells(),
+                                    reason_params =>
+                                    {
+                                        base_coords => [$y,$x],
+                                        offset => [@$offset],
+                                        islands =>
+                                        [
+                                            $cell->island(),
+                                            $other_cell->island(),
+                                        ],
+                                    },
+                                }
+                            );
+                    }
+                }
+            }
+        }
+    }
+
+    return \@moves;
+}
+
 =head1 AUTHOR
 
 Shlomi Fish, C<< <shlomif at cpan.org> >>
 
 =cut
 
-1; # End of Games::Nurikabe::Solver
+1; # End of Games::Nurikabe::Solver::Board

File nurikabe-solver/Games-Nurikabe-Solver/t/solve1.t

View file
  • Ignore whitespace
 use strict;
 use warnings;
 
-use Test::More tests => 20;
+use Test::More tests => 25;
 
 use Test::Differences;
 
         );
     }
 }
+
+{
+    # http://www.logicgamesonline.com/nurikabe/archive.php?pid=983
+    # Daily 9*9 Nurikabe for 2008-10-03
+    my $string_representation = <<"EOF";
+Width=9 Height=9
+[1] [] [] [] [] [] [] [5] []
+[] [6] [] [] [6] [] [] [] []
+[] []  [] [3] [] [] [] [] []
+[] [] [] [] [] [] [] [] []
+[] [] [] [] [] [] [] [] []
+[] [] [] [] [] [] [] [] []
+[] [] [] [] []  [2] [] [] []
+[] [] [] [] [3] [] [] [3] []
+[] [2] [] [] [] [] [] [] [1]
+EOF
+
+    my $board =
+        Games::Nurikabe::Solver::Board->load_from_string(
+            $string_representation
+        );
+
+    {
+        my $moves = $board->_solve_using_adjacent_whites({});
+
+        my $m = shift(@$moves);
+
+        # TEST
+        is ($m->reason(), "adjacent_whites", "reason[0] is OK.");
+
+        # TEST
+        eq_or_diff(
+            $m->get_verdict_cells($NK_BLACK),
+            [[0,1],[1,0]],
+            "Verdicted cells[0] are OK.",
+        );
+
+        # TEST
+        eq_or_diff ($m->reason_param("offset"), [1,1], "Offset[0] is (1,1).");
+
+        # TEST
+        eq_or_diff ($m->reason_param("islands"), [0,2],
+            "Islands of [0] are [0,2]",
+        );
+
+        # TEST
+        eq_or_diff (
+            $m->reason_param("base_coords"),
+            [0,0],
+            "Base coords[0] is (0,0)."
+        );
+    }
+}