Cohesion

Blitz3D Forums/Blitz3D Beginners Area/Cohesion

MAX711(Posted 2004) [#1]
Hi!

New to programming so if this is really obvious I appologise. Does anyone have a good routine for checking if characters on a board game are all within a certain distance of each other, say 40 pixels max? I might have upto 20 characters and they all need to be within 40 pixels of each other, but in any random location. Or maybe another way to think of it is a flock of pigeons on the ground, all randomly spaced but needing to be within 2 feet of each other, how would you go about checking if they are?

Thanks


RiverRatt(Posted 2004) [#2]
If your working in 3d you could use
EntityDistance# ( src_entity,dest_entity)

If your working in 2d you could use mathamatics
and if then statments to check number of pixels between
characters.

And check the code archives under algorithms, ther is one that checks the distance between 2 rectangles and another
one with homing missles that could just as well be little
sheep folowing a sheep herder.Have a looksee.


Todd(Posted 2004) [#3]
Maybe something like this?:

Const MaxDistance = 40

Type Character
	Field PosX, PosY
End Type

For Ch.Character = Each Character
	InRange = False
	For Ch2.Character = Each Character
		DistX# = Ch2\PosX - Ch\PosX
		DistY# = Ch2\PosY - Ch\PosY
		If Sqr((DistX#^2)+(DistY#^2)) <= MaxDistance
			InRange = True
		EndIf
	Next
	If Not InRange
		;Character Too Far Away
	Else
		;Character Within MaxDistance Range
	EndIf
Next



_PJ_(Posted 2004) [#4]
Yeah I would definitely suggest using 'Types' as Todd suggested because it is a quick way to check through each 'instance'.


MAX711(Posted 2004) [#5]
Thanks for the reply(s). I have been working with something very similar to Todd's suggestion but the problem that I'm having is that the algorithm would allow a situation where the flock of pigeons break into 2 seperate groups on other sides of the field. This is not allowed, but as long as the pigeons in each group are close enough to each other, the algoritm above wouldn't catch this situation. Somebody mentioned a "Binary Heap" might work, but I don't even know what a "Binary Heap" is, let alone whether it would work?


_PJ_(Posted 2004) [#6]
'Binary heap' means nothing to me either ;)

If you need the 'pigeons' to split up into separate groups, are these groups different for a reson? different 'teams'???

If so, then repeat the above, but have a different Type for each group maybe?


MAX711(Posted 2004) [#7]
No, the 'pigeons' are all part of the same team. It's the splitting up that I'm trying to stop them doing, but I have no way of detecting when it happens.


_PJ_(Posted 2004) [#8]
Could you post some of your existing code?


WolRon(Posted 2004) [#9]
Perhaps simply looking for two or more 'pigeons' in close proximity is what you are after...


Todd(Posted 2004) [#10]
The method I wrote just checks if each "pigeon" is within 40 pixels of at least one other pigeon. If you wanted to check that each pigeon should be within 40 pixels of each other pigeon, than just change the "<=" to ">", and change "If Not InRange" to "If InRange". That way, the code after "If InRange" would only be run if a pigeon was more than 40 pixels away from any other pigeon.

For example, using the code I wrote in my first post, both A and B would work. If you made those two changes I described though, only B would work, because in A it's possible for pigeons to be more than 40 pixels away:




MAX711(Posted 2004) [#11]
Wow! great graphics Todd, I think I might use them in my game ;). I've attached a screenshot from the game that might help.

In this shot, all the units (members of 'red' team) are within 2 cells of each other and there are no gaps of more than 2 cells between 'clusters', i.e. 14,1,7,4 are not more than two cells away from 10,12,8. So this is perfectly OK, but.....



In the shot below, 14,2,4 meet the criteria, but they are more than two cells away from the rest, which is not allowed, but the algorithm can't catch this because when 14 is tested, it finds that it's next to 2, so it thinks it's OK.




Curtastic(Posted 2004) [#12]
if the pieces start out next to eachother, you could check for adjaceceny when one is moved, if it is no longer adjacent, then move back to original position.

but if the pieces become scattered or dont start next to eachother, you would have to do a union tree or a flood fill, to check them all.

make a fill Type, each only has a position on the grid
start on any piece, by placeing a fill spot there
check all tiles within adjacency radius of the fill spot, if there is a piece on any of those tiles, with a piece \checked=false then set that piece's\checked=true and place a fill spot on that piece.
delete the origional fill spot when you check all its adjacent tiles
for each fill spot do that same thing until theres no more fill spots

youre done. you can go through each piece and if it's \checked is false then it is unconnected


MAX711(Posted 2004) [#13]
Thanks Coorrae, it worked like a charm!