So my problem is the following: I want, given some point with X,Y-coordinates in a grid, to return all of its adjacent cells.
( Note: in the following examples, I'm using the notation UL = upper-left, UM = upper-middle, UR = upper-right, L = left, R = right, BL = bottom-left, BM = bottom-middle and BR = bottom-right. )
E.g.:
For element x at (3,3) on a 5x5 grid
_ _ _ _ _
_ UL UM UR _
_ L x R _
_ BL BM BR _
_ _ _ _ _
For element x at (1,1) on a 5x5 grid
x R _ _ _
BM BR _ _ _
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _
Now, as can be seen in the examples above, the amount of cells adjacent to our current element x may vary depending on the X,Y-coordinates of element x itself.
I wanted to solve this by saying that every X to the left and right of the specified coordinate's X, as well as every Y above and below the specified coordinate's Y should be in the domain of 1..N and afterwards define their actual values:
% Adj_cells/2 : (X,Y) coordinate, board width/height N
adjacent_cells((X,Y),N) :-
[Xleft,Xright,Yup,Ydown] #:: 1..N,
Xleft #= X-1, Xright #= X+1,
Yup #= Y-1, Ydown #= Y+1,
...
However, of course, this evaluates to false whenever a border of the board gets crossed.
I was hoping I wouldn't explicitly need to differentiate between the situations concerning the board's borders; instead I'm trying to find something that, rather than evaluating to false whenever an out-of-bound coordinate is reached, just 'discards' that result and tries to calculate the other adjacent cells.
I'm sure there'll be a nice little solution for this in ECLiPSe, but I've searched the docs and -so far- can't seem to find something that fits my needs.
Any help is greatly appreciated!
You didn't say in what form you want to "return" the adjacent cells, but if you just want to "do" something for every neighbour, you could use this pattern:
adjacent_cells([X,Y], N) :-
( multifor([I,J], [max(1,X-1),max(1,Y-1)], [min(N,X+1),min(N,Y+1)]), param(X,Y) do
( [I,J]==[X,Y] -> true ;
writeln([I,J])
)
).
which gives for example
?- adjacent_cells([1, 3], 6).
[1, 2]
[1, 4]
[2, 2]
[2, 3]
[2, 4]
Yes (0.00s cpu)