Determining Neighbours of Cell Two Dimensional List

Determining neighbours of cell two dimensional list

# Size of "board"
X = 10
Y = 10

neighbors = lambda x, y : [(x2, y2) for x2 in range(x-1, x+2)
for y2 in range(y-1, y+2)
if (-1 < x <= X and
-1 < y <= Y and
(x != x2 or y != y2) and
(0 <= x2 <= X) and
(0 <= y2 <= Y))]

>>> print(neighbors(5, 5))
[(4, 4), (4, 5), (4, 6), (5, 4), (5, 6), (6, 4), (6, 5), (6, 6)]

I don't know if this is considered clean, but this one-liner gives you all neighbors by iterating over them and discarding any edge cases.

Finding neighbours in a two-dimensional array

(pseudo-code)

row_limit = count(array);
if(row_limit > 0){
column_limit = count(array[0]);
for(x = max(0, i-1); x <= min(i+1, row_limit); x++){
for(y = max(0, j-1); y <= min(j+1, column_limit); y++){
if(x != i || y != j){
print array[x][y];
}
}
}
}

Of course, that takes almost as many lines as the original hard-coded solution, but with this one you can extend the "neighborhood" as much as you can (2-3 or more cells away)

Looking for a readable, elegant way to select direct neighbors in 2D list in Python

If you want to use numpy, you can use an indexing array, which contains the indices of the neighbors relative to the index you want, and then add this to your desired index.
I personally think this is elegant, but YMMV

Here's an example:

import numpy as np

# A 5 * 5 grid
grid = np.arange(25).reshape(5, 5)

# A schematic representation of the grid
# 0, 1, 2, 3, 4
# 5, 6, 7, 8, 9
# 10, 11, 12, 13, 14
# 15, 16, 17, 18, 19
# 20, 21, 22, 23, 24

# We define how our neighbors relate to our index.
mask = np.array([[0, 1], [1, 0], [0, -1], [-1, 0]])

# Let's say we want the neighbors of [2, 2], which are 17, 11, 7, and 13
# Index marked with X, neighbors marked with O
# 0, 1, 2, 3, 4
# 5, 6, O 8, 9
# 10, O X O 14
# 15, 16, O 18, 19
# 20, 21, 22, 23, 24

desired_index = np.array([2, 2])

# We add the neighbor indices to the mask
neighbor_indices = desired_index + mask
# [[2, 3], [3, 2], [2, 1], [1, 2]]
# Index the array using the indices.
neighbors = grid[neighbor_indices[:, 0], neighbor_indices[:, 1]]

Note that this example does not take care of out of bounds issues. Specifically, it will error when given indices higher than the number of columns or rows, and will wrap around for indices < 0.

desired_index = np.array([0, 0])
neighbor_indices = desired_index + mask
neighbors = grid[neighbor_indices[:, 0], neighbor_indices[:, 1]]
# Wrong

desired_index = np.array([4, 4])
neighbor_indices = desired_index + mask
neighbors = grid[neighbor_indices[:, 0], neighbor_indices[:, 1]]
# Error

Efficient way to find neighboring cells in a 2d array

When it just works then it's fine !

Here's a little optimization that makes it easier to debug:

var playfieldHeight = 5;
var playfieldWidth = 5;
var playfieldTiles = new byte[playfieldWidth + dnDistance * 2, playfieldHeight + dnDistance * 2];
var len1 = playfieldWidth * playfieldHeight;
var len2 = dnDistance * 2 + 1;

for (var i = 0; i < len1; i++)
{
var ix = i % playfieldWidth;
var iy = i / playfieldWidth;
for (var j = 0; j < len2 * len2; j++)
{
var jx = j % len2 - dnDistance;
var jy = j / len2 - dnDistance;
Console.WriteLine($"x1: {ix}, y1: {iy}, x2: {jx}, y2: {jy}");
}
}

You now have only 2 loops, the field and the neighbors.

You could further optimize it with a single for but I believe readability will decrease (inside the loop).

How do I check the neighbors of the cells around me in a 2D array (C++)?

You can use nested loops

int sum{0};
for (int x{std::max(xPosition, 1) - 1}; x < std::min(xPosition + 2, columns); ++x) {
for (int y{std::max(yPosition, 1) - 1}; y < std::min(xPosition + 2, rows); ++y) {
if (x == xPosition && y == yPosition) continue;
sum += array[x][y];
}
}

Determining neighbours of cell as diamond shape in python

For an iterative approach where you just construct the diamond:

def get_neighbors(center, n=1):
ret = []
for dx in range(-n, n + 1):
ydiff = n - abs(dx)
for dy in range(-ydiff, ydiff + 1):
ret.append((center[0] + dx, center[1] + dy))
return ret

Result of get_neighbors((2, 2), 2):

[(0, 2), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (4, 2)]

Or, for a recursive approach:

dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]

def add_tuples(a, b):
return tuple([x + y for (x, y) in zip(a, b)])

def get_neighbors(center, n=1, seen=set()):
seen.add(center)
if n <= 0:
return seen
for dir in dirs:
newpos = add_tuples(center, dir)
if newpos in seen:
continue
get_neighbors(newpos, n - 1, seen)
return seen

Finding the neighbors of 2D array

Try this

//col , row : representing the cell you want to find neighbors to 
private void neighbours(int col, int row) {

//find all serouding cell by adding +/- 1 to col and row
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {

for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {

//if not the center cell
if(! ((colNum == col) && (rowNum == row))) {

//make sure it is within grid
if(withinGrid (colNum, rowNum)) {
System.out.println("Neighbor of "+ col+ " "+ row + " - " + colNum +" " + rowNum );
}
}
}
}
}

//define if cell represented by colNum, rowNum is inside grid
//function used by neighbours()
private boolean withinGrid(int colNum, int rowNum) {

if((colNum < 0) || (rowNum <0) ) {
return false; //false if row or col are negative
}
if((colNum >= COLS) || (rowNum >= ROWS)) {
return false; //false if row or col are > 75
}
return true;
}

Don't hesitate to ask if the code isn't clear.

To test it with you code modify this block:

    if(actualState == GameState.JOUE){
if((selectedRow >= 0) && (selectedRow < ROWS) && (selectedCol >= 0)
&& (selectedCol < COLS) &&
(board[selectedRow][selectedCol] == Token.VIDE)){
board[selectedRow][selectedCol] = actualPlayer;
//actualiseJeu(actualPlayer, selectedRow, selectedCol);
actualPlayer = (actualPlayer == Token.CERCLE_BLEU)? Token.CERCLE_ROUGE : Token.CERCLE_BLEU;

//add this to call function :
neighbours(selectedCol, selectedRow);
}
}


Related Topics



Leave a reply



Submit