0

I have a struct called Grid that is 10 cells x 10 cells, and I need to determine the position of a given cell's neighboring cells.

Every cell has a position ranging from (0,0) to (9,9). Position is typealias Position = (row: Int, col: Int). norm normalizes positions like makes sure that something like (12,0) gets mapped back to the 10x10 grid as (2,0).

func norm(_ val: Int, to size: Int) -> Int {
    return ((val % size) + size) % size
}

This extension to Grid is supposed to determine the position of all neighboring cells given a cell like (6,3). I've commented out the part that I'm trying to figure out. I'm trying to run norm on the x and y coordinates of the neighbors to determine their actual position.

extension Grid {
    func neighbors(of cell: Cell) -> [Position] {
        // return Grid.offsets.map{(norm($0, to: rows)), (norm($1, to: cols))}
    }
}

Within the Grid struct all 8 possible neighboring positions are contained within offsets.

struct Grid {
    static let offsets: [Position] = [
        (row: -1, col:  1), (row: 0, col:  1), (row: 1, col:  1),
        (row: -1, col:  0),                    (row: 1, col:  0),
        (row: -1, col: -1), (row: 0, col: -1), (row: 1, col: -1)
    ]
    ...
    }
}
Kermit
  • 4,922
  • 4
  • 42
  • 74
  • I think your `norm` function could be written as: `return val % size`. Given your example, currently it would be `((12 % 10) + 10) % 10` which simplifies down to `(2 + 10) % 10` -> `12 % 10` -> `2`. What I mean is that the `(+ 10) % 10` doesn't do anything – nanothread Jun 30 '17 at 13:08
  • Somewhat related: https://stackoverflow.com/questions/44180840/what-is-the-shortest-code-to-get-surrounding-coordinates/44181515#44181515 – dfrib Jun 30 '17 at 14:18

1 Answers1

1

Because you're mapping the offsets, you need to add them to the cell's current position to get the absolute positions of its neighbouring cells. You're also mapping an array of Position tuples, so there will only be one argument in the map closure which will be a Position - so instead of $0 and $1, you need $0.row and $0.col.

return Grid.offsets.map { (norm($0.row + cell.position.row, to: rows), norm($0.col + cell.position.col, to: cols)) }

Note that because of your norm function, this will wrap. For example, this function will say that the cell at (row: 3, col: 0) is next to the cell at (row: 3, col: 9)

nanothread
  • 908
  • 3
  • 10
  • 25
  • thank you! i got it to work by accessing row as cell.position.0 and col as cell.position.1 per https://www.weheartswift.com/tuples-enums/ – Kermit Jun 30 '17 at 13:58
  • 1
    In my code, I assumed you defined `cell.position`as `struct Cell { var position: Position }`, but if you defined it as `(Int, Int)`, then it wouldn't know what row is. You'd either have to change `cell.position.row` to `cell.position.0` and `cell.position.col` to `cell.position.1` (bad in terms of readability) or change the definition of a cell's position to be a `Position` (good in terms of readability) because then you can use `cell.position.row` and `cell.position.col` – nanothread Jun 30 '17 at 13:58