Trying to determine what each item of an array neighbors to

Godot Version

v4.3 beta3

Question

Not sure if I managed to do a good title. Did my best. I am new at Godot and programming in general, couldn’t get out of a problem I’ve encountered.

I have a function that creates random Vector2s and appends to an array. They represent location of sprites that I’ll draw later on. This will be a randomly generated road. I do want to ID each item based on their coordinates (their X and Y). So, I can determine if they go straight, bend up, bend down and such. For some reason I have not been able to go beyond determining if they are straight. I am probably missing something, but couldn’t find it.

I thought about checking this as I instantiate each sprite, but I also want to see if it could be done in the way I am trying to do.

Here is my script

Here is how I have been trying to determine what each Vector2 is neighbored to. By checking X and Y values of each item, comparing them to one before and one after.

You could stor some info for each sprite. You need 4 bits. (8 possibilities that represent paths from current position, none being an island, and only having one being a dead end)

enum paths {
  None = 0x0,
  Up = 0x1,
  Down = 0x2,
  Left = 0x4,
  Right = 0x8
}

You start with none then you logically add a direction.

If you have path == path.Left + paths.Right it’s horizontal straight.

If you have path == paths.Up+paths.Down vertical straight path

You could probably do some math with the coordinates to do the same thing.

Scenarios 2,3 and 4 are combinations of scenario 0 and 1.
For example 2 is x+1 followed by y-1.
So those scenarios can be thrown out provided you don’t need to enforce a gap.
Theoretically you can only traverse left to right.
You also have to prevent walking back over a previous step.

I did a mock up with a ColorRect node and no real bounds checking.

var block_count_y:int = 64
var block_pos:Vector2 = Vector2.ZERO
var prev_dir:Vector2 = Vector2.ZERO

func _ready() -> void:
	seed(1)
	print(get_viewport_rect())
	block_pos = get_rand_start_vector()
	get_new_block(block_pos)
	for n in 103:
		if n == 2: 
			pass
		block_pos = get_next_block_dir() + block_pos
		get_new_block(block_pos)
	
func get_next_block_dir()->Vector2: 
	# next block can only be up/down,right
	const MULTI:Array[Vector2] = [Vector2(0,-10), Vector2(10, 0), Vector2(0, 10)]
	var next_dir:Array[Vector2]
	for dir in MULTI: 
		if dir != -(prev_dir): 
			next_dir.append(dir)
	prev_dir = next_dir.pick_random()		
	return prev_dir

func get_rand_start_vector()->Vector2: 
	var n:int = randi() % (block_count_y - 1)
	return Vector2(0,n * 10)

func get_new_block(block_pos:Vector2)->ColorRect: 
	var block:ColorRect = ColorRect.new()  
	block.size = Vector2(10,10)
	add_child(block)
	block.position = block_pos
	return block

This is the road it creates:
patho

You can see what I mean by not enforcing a “gap” wherein many places will traverse for example down, right, and up creating a square.

You can store the type of block it is based on prev_direction and next_direction in a dictionary or an array.

prev_direction     next_direction          block_type for the block at prev_direction
Right                 Up                      scenario2
                      Down                    scenario3
                      Right                   scenario0
Up                    Up                      scenario1
                      Right                   scenario4
Down                  Right                   scenario5(not shown)
                      Down                    scenario1

Note that I use seed(1) for testing. It is a must to repeat values until you have the code nailed down.