It is all about 3 robots, named A, B, and C, that can move around their environment using informed search. The environment contains obstacles. The 3 robots need to meet at some point such that the total distance they walk is minimum.
To make the problem a little computationally simpler, we will limit the obstacles to be rectangles. The 3 robots are always circles with radius 1. The goal state is to have the 3 robots (circles) to touch each other; the distance between the centers of every two robots is 1 unit. While moving, robots must not cut across any of the obstacles. In every step, one of the 3 robots moves one unit from the current location in each of the four directions: left, right, up and down. A move from one point to another must not go through any obstacle.
I just need a good heuristic function that can approximate the distance between the 3 robots can you help me guys?
I solved this issue here is the code Github code
I assume here that you want to minimize the number of total steps (only one robot moves at a time). If the robots all move at the same time and you want to minimize the time needed the solution would be different. Also, some fine tuning is necessary becuase the robots should just touch, not come to the same point.
You actually need a lower bound, not an approximation. A good lower bound can be calculated by disregarding any obstacles and check how many moves are necessary on an empty field. Since the robots can only move horizontally or vertically we consider these directions separately.
Take the horizontal direction first. The leftmost and the rightmost robot need to meet somewhere between them so independent where they meet, in total they have to move the horizontal distance between them. If they meet at the horizontal position of the middle robot, the middle does not have to move. So the horizontal steps necessary in any case is the horizontal distance between the leftmost and rightmost robot. Call this the horizontal span.
A similar argument holds for the vertical direction.
In total a lower bound is therefore the vertical span plus the horizontal span.
If each robot moves at the same time and it is known where the obstacles are at the beginning(so a known map), and obstacles are none moving this would work. Uou would need to generate a grid of sorts using a wavefront algorithm. This would be done for each robot in the beginning. Then going through each grid add the steps from each robot. Then find the grid with the lowest amount.
Related
I have an array with the coordinates of the center of small circles which have the same radius. I know how to find when the mouse is over a circle, but my array is big and I want the fastest way to calculate this operation.
Is there a way of finding if the mouse is over a circle without looping all the array for each movement of the mouse?
Initially, set up some 'zones' for quicker reference:
Separate the whole surface into a small number of rectangles that don't intersect.
For each of these rectangles, list all circles that are at least partially contained in it. (A circle may end up listed in multiple rectangles, but that's okay.)
Every time you want to check whether the mouse is over a circle, you won't have to go through the whole array of circles. Instead:
Figure out which rectangle you're in.
Check only the circles that are listed under that rectangle.
This looks like a problem of optimizing the boundary check for a large number of items. The approach of going linearly does not scale well for thousands of circles.
This is a good topic to read on the net. But first, without going there, I'll try to explain (as an exercise) what I would explore. I would create a binary tree and partition the space, then instead of using an array I would put the circle points in such a tree. Looking the tree elements that are closer to the actual X,Y location becomes a matter of doing a binary search on the tree. The you have the closest point as a result of that search and can check for collision on it. There is still more to be done to the algorithm, and further optimizations are needed. For example, how to check for more points and not only the final one? Potentially I need a tree for the X coordinate, and another for the Y coordinate, etc... But I would explore these ideas. I will come back to this post and expand my reply with an actual example and a more concrete solution.
What if you check the coordinates that are r(radius) distance from the mouse? Then you could narrow your search down in the array if it is ordered.
I am programming a 2D, grid-based Pacman game. All the tiles are 8x8 in size. In-game, the map tiles are treated as 16x16, and the characters (Pacman and the ghosts) are treated as 32x32. In actuality, they are all pulled from a spritesheet of 8x8 tiles. I store positions as the center point of each character. Since the character tiles are bigger than the map tiles, the map is built in a way that requires the characters being able to "overlap" onto blocked tiles.
To deal with this set of problems, I created an invisible Rectangle and attached it to the character's position. Where the position is an (x,y) point, the Rectangle is a box surrounding that point. This rectangle is essentially 16x16 in-game, and is in the center of the character, which allows for the overlap necessary.
This works fine if you're working with 8px as the global movement speed, but I'd like to treat 8px as "100% speed" and have complete control over character speed with a double that is in the range [0,1). The positions are stored as double points, so on that level, this is fine. I read the positions back as integers, though, since I'm working with pixels.
So the question I ask is essentially "if this moves X amount of pixels to direction Y now, will my collision box be touching a blocked tile? But if you're moving 5px at a time, this eventually causes a very obvious issue. Say you're at x = 0, moving right. The tiles are 16x16 in-game, as stated before, and you have two of these open before the third, which is blocked. So you move, x = 5, x = 10, x = 15, x = 20, we just got to the 2nd tile, x = 25, x = 30, x = 35 now we're in the 3rd tile... but wait. We can't go there, because X = 35 collides. And unfortunately, we needed to turn and start moving down, but we can't, because now our Y-axis isn't aligned properly with the grid. Our X position needs to be 32, but can't.
My question for everyone here is, what are my options? What are some ideas or insights you have? I have a feeling I'm making it more difficult than I need to.
sounds like you have...
Why not give your "pac-man" sprite a velocity vector? The vector will describe not only the speed at which "pac-man" is traveling but in what direction, meaning you can see ahead.
"pac-man" should be calculating and ultimately making a decision based upon the following conversation..."hey, moving at this speed and in this direction..in so many seconds I'm going to hit a wall, when does that happen?". The seconds don't even have to be seconds...they could be "squares".
You would need a function which takes in the initial movement vector (direction and speed) which returns a coordinate of an X,Y point where "pac-man" must stop, where he cannot go further and must change direction (the center of a tile adjacent to a wall). Each time "pac-man" changes direction, run this calculation again...you do not need to keep checking if the next square is passable. If his direction hasn't changed and his speed is constant..you only need calculate once and let the coordinate system do the rest.
With this approach, square size and velocity is irrelevant...until "pac-man" hits or within his next movement exceeds the stopping point, continue to move along the vector.
I have an image such as this:
and I need to calculate the orientation of it. In this case the shape is pointing towards the top left of the screen. Accuracy isn't hugely important as long as 3 or 4 calculations average out to within 5 degrees or so of the actual orientation (it will be moving slightly).
Can anyone point me towards an algorithm to do this? I don't mind if the orientation is returned as a double or as a vector.
If the image is always T-shaped, you can simply get the furthest pair of pixels, then find the furthest pair from either both of those (the edges of the T), find which is further from the other two, draw a line from that one to the middle point of those two.
You can further refine it by then finding the base of the T by comparing the middle line with the edges of the base, and adjusting the angle and offset until it is actually in the middle.
The definitive solution is impossible I guess, since requires image recognition. I would project the 2D image onto axis, i.e. obtain the width and height of the image and get direction vector from these values taking them as components.
First, a couple of assumptions:
The center and centroid are "close"
The descending bar of the T is longer than the cross-bar
First, determine the bounding rectangle of the image and find the points of the image that lie along this rectangle. For points that lie along the line and are a certain distance from one another (say 5 pixels to pick a value) you'll need to only take 1 point from that cluster. At the end of this you should have 3 points, i.e. a triangle. The shortest side of the triangle should be the cross-bar (from assumption 2), i.e. find the two points closest to each other. The line that is perpendicular to the line crossing those two points is then your orientation line, i.e. find the angle between it and the horizontal axis.
I would try morphological skeletonization to simplify the image, followed by some straightforward algorithm to determine the orientation of the longer leg of the skeleton.
The solution in the end was to use a Convex Hull Algorithm, which finds the minimum number of points needed to enclose a shape with a bound.
Firstly, this is AI for PacMan and not the ghosts.
I am writing an Android live wallpaper which plays PacMan around your icons. While it supports user suggestions via screen touches, the majority of the game will be played by an AI. I am 99% done with all of the programming for the game but the AI for PacMan himself is still extremely weak. I'm looking for help in developing a good AI for determining PacMan's next direction of travel.
My initial plan was this:
Initialize a score counter for each direction with a value of zero.
Start at the current position and use a BFS to traverse outward in the four possible initial directions by adding them to the queue.
Pop an element off of the queue, ensure it hasn't been already "seen", ensure it is a valid board position, and add to the corresponding initial directions score a value for the current cell based on:
Has a dot: plus 10
Has a power up: plus 50
Has a fruit: plus fruit value (varies by level)
Has a ghost travelling toward PacMan: subtract 200
Has a ghost travelling away from PacMan: do nothing
Has a ghost travelling perpendicular: subtract 50
Multiply the cell's value times a pecentage based on the number of steps to the cell, the more steps from the initial direction, the closer the value of the cell gets to zero.
and enqueue the three possible directions from the current cell.
Once the queue is empty, find the highest score for each of the four possible initial directions and choose that.
It sounded good to me on paper but the ghosts surround PacMan extremely rapidly and he twitches back and forth in the same two or three cells until one reaches him. Adjusting the values for the ghost presence doesn't help either. My nearest dot BFS can at least get to level 2 or 3 before the game ends.
I'm looking for code, thoughts, and/or links to resources for developing a proper AI--preferably the former two. I'd like to release this on the Market sometime this weekend so I'm in a bit of a hurry. Any help is greatly appreciated.
FYI, this was manually cross-posted on GameDev.StackExchange
If PacMan gets stuck in a position and starts to twitch back and forth then it suggests that the different moves open to him have very similar scores after you run your metric. Then small changes in position by the ghosts will cause the best move to flip back and forth. You might want to consider adding some hysteresis to stop this happening.
Setup: Choose a random move and record it with score 0.
For each step:
Run the scoring function over the available moves.
If the highest score is x% greater than the record score then overwrite the record score and move with this one.
Apply the move.
This has the effect that PacMan will no longer pick the "best" move on each step, but it doesn't seem like a greedy local search would be optimal anyway. It will make PacMan more consistent and stop the twitches.
Have a way to change PacMan into a "path following" mode. The plan is that you detect certain circumstances, calculate a pre-drawn path for PacMan to follow, and then work out early exit conditions for that path. You can use this for several circumstances.
When PacMan is surrounded by ghosts in three of the four directions within a certain distance, then create an exit path that either leads PacMan away from the ghosts or towards a power up. The exit situation would be when he eats the power up or ceases to be surrounded.
When PacMan eats a power up, create a path to eat some nearby ghosts. The exit situation would be when there are no ghosts on the path, recalculate the path. Or if there are no ghosts nearby, exit the mode entirely.
When there are less than half the dots left, or no dots nearby, enter a path to go eat some dots, steering clear of the ghosts. Recalculate the path when a ghost comes nearby, or exit it entirely if several ghosts are nearby.
When there are no situations which warrant a path, then you can revert back to the default AI you programmed before.
You can use Ant Colony Optimisation techniques to find shortest visible path that leads to many icons to eat or can get many score.
I don't know a lot about AI or specific algorithms, but here are some things you could try that might just get you close enough for government work :)
For the problem with ghosts surrounding him quickly, maybe the ghost AI is too powerful? I know that there's supposedly specific behaviors for each ghost in classical Pacman, so if you haven't incorporated that, you may want to.
To eliminate backtracking, you could create an weight penalty for recently traversed nodes, so he's less inclined to go back to previous paths. If that's not enough to kick him in one direction or another, then you can logarithmically increase the attraction penalty, so one path will become significantly more attractive than the other at a very quick rate.
For the problem of him getting caught by ghosts, you might be able to change from a general goal-based algorithm to an evasive algorithm once the ghosts have reached a dangerous node proximity.
You might benefit of knowing how the bots "reason" (as explained in this excellent dossier). For example, knowing the chase/scatter pattern of the ghosts will allow you to get the dots in "dangerous" locations, and so on.
I am adding this answer knowing that it's not the best solution you were looking for (since you wanted to deliver next week..) but maybe will be of use to somebody reading this in the future. Sortof a time capsule :)
You should check out this description of Antiobjects, which is the technique used by the Pacman ghosts to traverse the maze. In particular, note:
Each of these antiobjects or agents
has an identical and simple algorithm
which it runs at every turn of the
game. Instead of making Ghosts smart
enough to solve "shortest path"
problems around the maze, a notion of
"Pac-Man scent" is created instead and
each tile is responsible for saying
how much Pac-Man scent is on its tile.
So you consider a similar scent-based technique to control Pacman, perhaps where Pacman preferred traversing a path with a smaller amount of scent; this would reduce the chance of him going over old ground.
I'm building a pacman game. Basically, I want to have a map representation of this window consisting of blocks/tiles. Then as the pacman character/ghost moves i would change their position on the map to represent what's on the screen, and use that for collision detection etc.
How can I build this map, especially since the screen is made of x,y coordinates, so how can I correctly represent them in tiles/on this map?
I know it's tempting to start thinking of objects and interfaces but have you thought about a 2-dimensional array with each element representing 40 pixels or something? I don't remember pacman being pixel accurate when it came to collision, more a question of the direction each piece was moving in.
Generally you have an abstract representation that doesn't reference pixels as such (for example, maybe the Pac-Man maze is simply w units wide), and then you have a linear transformation (you know, y = mx + b) to carry the abstract representation to actual pixels.
To make it concrete, let's say that you want your abstract representation to be 100 units wide, and you want to render it as 400 pixels. Then the transformation is just scrn_x = 4 * x.
Kind of difficult to come up with this without writing it myself but.
First you'll need to create entity definitions that implement ICollidable. Entities would include ghosts, pacman, dots and powerups.
Each element in the map would contain, along with other information, a list of all present entities with a sort of "position" value for added precision. The ICollidable interface would include not only logic for determining which entities collide with one another (ghosts don't collide with dots for example.) but determining if they're in position to collide with one another. IE if pacman is entering a space from the right and a ghost is leaving that space from the left there's no collision. It will also help determine when exactly pacman has eaten a dot so that graphically it looks correct. IE if you destroy a dot right as pacman enters a space it's going to disappear before he even touches it graphically.
Your sprites such as pacman and the ghost are represented by positions (x,y). To determine if they collide with each other, use this psuedocode:
sprites = [ ... list of sprites ... ]
for i1=0 to len(sprites):
sprite1 = sprites[i1]
for i2 = i1+1 to len(sprites):
sprite2 = sprites[i2]
if (sprite1.x-sprite2.x)^2+(sprite1.y-sprite2.y)^2 < radius_of_sprites^2:
collide(sprite1, sprite2)
Note that this doesn't involve the map at all. We can check for collisions between pacman and the map separately. The key trick here is you divide the pixel coordinate of each of pacman's sides (top, bottom, left, right) and check for collisions. For example, if pacman is going to the right, we need to check the right edge for a collision:
pacman_tile_x = (pacman.x+tilesize/2)/tilesize # added tilesize/2 to check the middle of pacman
pacman_tile_y = pacman.y/tilesize + 1 # +1 because right edge is 1 tile to the right of the sprite's coordinate
if tile[pacman_tile_x][pacman_tile_y].is_a_wall:
... wall collide code ...
Now, if you have a huge number of sprites on the screen, you can optimize the sprite-to-sprite collision detection by storing which sprites exist on any particular tile in the map, and so you only have to check against sprites in adjacent tiles. But for a first pass and for this pacman game, it's probably not a necessary optimization.