[Programming help] Getting tiles in a ring, efficiently

Padmewan

King
Joined
Nov 26, 2003
Messages
748
Location
Planet
Let's say I want to iterate through all tiles in a radius around a tile, but only at a specified distance. For example, let's say I wanted all tiles 3 tiles distant:
Code:
XXXXXXX
XOOOOOX
XOOOOOX
XOO*OOX
XOOOOOX
XOOOOOX
XXXXXXX
What's the fastest way to assemble an array of the tiles marked with "X" when given an arbitrary integer radius?

(Once I have this code, presumably it'd be pretty easy to "search" outwards or inwards from the tile marked *, by passing an incrementing or decrementing radius to the formula.)

Thanks to anyone who can help!
 
Untested, but I'm fairly confident since I've written similar routines:

PHP:
def getAllTileCoordsAtDistance(startx, starty, distance):
  tileCoordinateSet = []
  #starting with the left and right vertical stripes
  for x in [-distance, distance]:
    #the vertical range is from -distance to distance inclusive
    for y in range(-distance,distance+1):
      tileCoordinateSet.append((startx+x, starty+y))
  #adding the horizontal stripes
  for y in [-distance, distance]:
    #we note that we don't need to pick up the corners again
    # (because that would be a duplicate from the x case)
    # so the range is -distance+1 to distance-1 inclusive
    for x in range(-distance+1,distance):
      tileCoordinateSet.append((startx+x, starty+y))

  return tileCoordinateSet

edit: correct the variable name 'dist' to 'distance'
edit: Just noting the performance of this is pretty much as good as is possible. There is exactly one append per tile that you want, and no unnecessary tiles are evaluated.
 
Thanks. I think you're right that this is the fastest way to do it.

I forgot that in Civ, a diagonal move "costs" the same as a vertical or horizontal one. Once I started drawing out the circles I realized they were squares!
 
Back
Top Bottom