0

I am working on a game where I use different sized objects - such as houses, trees etc. My question is, which way should I determine is the place I am going to place my object free or not? World is generated randomly every time the game is launched.

(I'm only using x and z coordinates) For example, I have tree in a item pool with a size of 10x10, in the location 10, 0, 10 and I am going to add a stone which is size 5x5 for example. So how do I tell the stone "hey you can't place yourself to coordinates from 5 to 15 on x axis and 5 to 15 on z axis, place somewhere else".

Yes a simple way would be to just write down all the coordinates which are taken (5,6,7 ... 14,15), but what if I have 1000 trees? Is there any better and faster way to locate free spot for the item other than looping through a list of coordinates which have also looped to be written in taking a slot?

Anas
  • 971
  • 13
  • 28

2 Answers2

0

The logic behind hash-tables search can be inspiring.

To remind us of hash-table:

When searching for n in a hash-table

  • we first look at h(n) where h is the hash function.
  • Report the record if it hits, move to h(n)+1 if it misses.
  • Report the record if it hits, move to h(n)-1 if it misses.
  • Report the record if it hits, move to h(n)+2 if it misses.
  • Report the record if it hits, move to h(n)-2 if it misses.
  • Report the record if it hits, move to h(n)+4 if it misses.
  • Report the record if it hits, move to h(n)-4 if it misses.
  • ...

We set the step size to the numbers in 2^i sequence and their negatives (0,1,-1,2,-2,4,-4,8,-8,16,...)


Now in your scenario:

  • we first look at t where t is the target location.
  • Report the location if it's free, move to [t.x,t.y+1] if it's not.
  • Report the location if it's free, move to [t.x,t.y-1] if it's not.
  • ...
  • Report the location if it's free, move to [t.x-1,t.y-1] if it's not.
  • Report the location if it's free, move to [t.x,t.y+2] if it's not.
  • ...
  • Report the location if it's free, move to [t.x,t.y+4] if it's not.
  • ...

Now how we tell if a location is free or not? You can create an actual hash-table to store all the objects positions in it. Now when you need to check for a free location around [x,y] to put a stone, you will have to search the hash-table for h(x,y).

If you need to place a bigger object like a 3x3 round-shaped fountain at location [x,y] you will need to check these records too: h(x+1,y), h(x-1,y), h(x,y+1), h(x,y-1). Since it's a round object you can approximate the area to simplify and thus remove four relative locations like h(x+1,y+1), h(x+1,y-1), h(x-1,y+1), h(x-1,y-1) from your search.

Afterwards you should add all these positions to the hash-table to make it easier to find occupied positions later on. e.g. adding a 3x3 object requires adding of 9 records to the hash-table.

Note that the hash function should reflect the two-(or three)dimensional world. e.g. h(x,y) = x*N + y where N is the max size of the world in y axis.

Bizhan
  • 16,157
  • 9
  • 63
  • 101
  • Using hashtables is what I had in mind, and also tried to simplify my location, but simplifing takes me to a bug - for example if object has size of 3x3 on position (x,y), and my system places a 3x3 item to position x+3 y-3 then there will be overlapping on positions (x+1,y-1), (x+1, y-2), (x+2,y-1),(x+2,y-2) or am I thinking wrong? – user9534568 Mar 23 '18 at 20:25
  • the real size on that example would be 6x6 tho :) – user9534568 Mar 23 '18 at 20:31
  • @user9534568 You are right I edited the answer. however my assumptions of your question goes like this https://pasteboard.co/HdzkHPm.png where two rectangles collide at (+1.5,-1.5). So if this position is already occupied, then you need an entry in your hashtable telling this position is occupied, i.e. having a 3x3 rectangle is equal to having 9 entries in hashtable. It can still be much more memory-efficient than having a sparse bool[,] lookup (like a bitmap). – Bizhan Mar 25 '18 at 18:27
  • By a sparse bool[,] lookup I mean converting the map into an MxN 1bit bitmap where its elements are booleans saying whether this pixel is occupied or not. Using a hashtable provides more flexibility than that and consumes less memory for larger sparse maps. – Bizhan Mar 25 '18 at 18:36
0

You could work with a grid system. Or to prevent objects from overlapping when placing them you could just add a collider to the object, set it as trigger and check if it collides with another object before placing it. If you want to keep some distance between objects you can make the colliders bigger.