# neighbors returns the neighbors of given index. Neighbors are cached # in @neighbors array. This way we don't have to compute them # everytime neighbors subroutine is called for the same position. sub neighbors( @puzzle, Int $y, Int $x --> List ) is export { # @directions is holding a list of directions we can move in. It's # used later for neighbors subroutine. state List @directions = ( # $y, $x ( +1, +0 ), # bottom ( -1, +0 ), # top ( +0, +1 ), # left ( +0, -1 ), # right ); # @neighbors holds the neighbors of given position. state Array @neighbors; if @puzzle[$y][$x] { # Don't re-compute neighbors. unless @neighbors[$y][$x] { # Set it to an empty array because otherwise if it has no # neighbors then it would've be recomputed everytime # neighbors() was called. @neighbors[$y][$x] = []; my Int $pos-x; my Int $pos-y; # Starting from the intital position of $y, $x we move to # each direction according to the values specified in # @directions array. In this case we're just trying to # move in 4 directions (top, bottom, left & right). direction: for @directions -> $direction { $pos-y = $y + $direction[0]; $pos-x = $x + $direction[1]; # If movement in this direction is out of puzzle grid # boundary then move on to next direction. next direction unless @puzzle[$pos-y][$pos-x]; # If neighbors exist in this direction then add them # to @neighbors[$y][$x] array. push @neighbors[$y][$x], [$pos-y, $pos-x]; } } } else { # If it's out of boundary then return no neighbor. @neighbors[$y][$x] = []; } return @neighbors[$y][$x]; }