I put together an example script with a tilemap, showing how to obtain grid positions within a radius, and also a few different methods to pick a random position within a circle. (note that if you have an array of positions you can also pick a random item from it directlty).

```
extends Node
onready var _tilemap = $TileMap
var _radius_in_tiles = 4.0 # Note: decimal values work too, you may try
var _center_in_tiles = Vector2(5, 5) # Hardcoded, you may choose
func _ready():
var positions = get_tile_positions_in_circle()
for pos in positions:
_tilemap.set_cellv(pos, 0)
# Get random position around point. There are several ways to do it.
var tile_position = pick_random_position_v1()
# Remove a tile for testing
_tilemap.set_cellv(tile_position, -1)
# Or simply use the array computed earlier.
tile_position = positions[randi() % len(positions)]
_tilemap.set_cellv(tile_position, -1)
func get_tile_positions_in_circle():
# Get the rectangle bounding the circle
var radius_vec = Vector2(_radius_in_tiles, _radius_in_tiles)
var min_pos = (_center_in_tiles - radius_vec).floor()
var max_pos = (_center_in_tiles + radius_vec).ceil()
# Convert to integer so we can use range for loop
var min_x = int(min_pos.x)
var max_x = int(max_pos.x)
var min_y = int(min_pos.y)
var max_y = int(max_pos.y)
var positions = []
# Gather all points that are within the radius
for y in range(min_y, max_y):
for x in range(min_x, max_x):
var tile_pos = Vector2(x, y)
if tile_pos.distance_to(_center_in_tiles) < _radius_in_tiles:
positions.append(tile_pos)
return positions
func pick_random_position_v1():
# Trigonometry solution.
# It's fast and simple, but points have a higher chance to be near the center.
# In some cases this is acceptable.
var angle = rand_range(-PI, PI)
var direction = Vector2(cos(angle), sin(angle))
return _center_in_tiles + direction * _radius_in_tiles
func pick_random_position_v2():
# Improved trigonometric solution.
# Density of results will be the same at any distance from center.
# https://programming.guide/random-point-within-circle.html
var angle = rand_range(-PI, PI)
var direction = Vector2(cos(angle), sin(angle))
var distance = _radius_in_tiles * sqrt(rand_range(0.0, 1.0))
return (_center_in_tiles + direction * distance).floor()
func pick_random_position_v3():
# So-called "Monte-carlo" solution.
# Generate random points until it is inside the radius.
# Can be used in more complex shape scenarios as simple prototyping solution.
for attempt in 100:
var pos = _center_in_tiles + Vector2(
rand_range(-_radius_in_tiles, _radius_in_tiles),
rand_range(-_radius_in_tiles, _radius_in_tiles))
if pos.distance_to(_center_in_tiles) > _radius_in_tiles:
return pos.floor()
return _center_in_tiles.floor()
```