Android Game Development (Programming/Algorithm) Question - java

I have a bunch of objects (balloons) that move upwards, hit the roof (i.e. object.yPos <= 0), and stop. Balloons that follow them hit the existing balloons and stop. Now, I shoot at balloons and remove those that are hit ... easy enough if they are already on the bottom.
However, I also have to remove those balloons that are left hanging after their supporting Anchor is hit and removed i.e. they are not attached to the roof OR any of the other balls anymore. Relevant to this, I have following supporting methods in my Balloon Object:
balloon.getAdjacentList() -> Returns ArrayList of all the Balloons that are attached to balloon
balloon.getX() -> Returns X Pos of balloon
balloon.getY() -> Returns Y Pos of balloon
One way of detecting "hanging in the air" balloon that I can think of is to use "Graph traversal" with DFS or BFS where origin would be all adjacent balls of the one that is hit (and removed) and destination would be ... if any of the adjacent ball (or "adjacent's adjacent" ball OR "adjacent's adjacent's adjacent" and so on) has getY() <= 0 i.e. find path to the roof.
This check seems very expensive to run especially when, to remove one or two hanging balls, I have to run dozens of searches. Also keep in mind that, in theory, a balloon might have many others attached to it and still have its Anchor (the one supporting them all to roof) hit and removed and therefore all of them have to go ... so ... if ( getAdjacent().size() == 0) would not work.
1- Any better idea of something that seems so easy to visualize and is implemented in so many games?
2- Any supporting methods that I can add to help me detect the balls?
Thanks in advance for any help

Here's a simple algorithm that probably performs decently for your purposes: just start at the anchor, and mark each node you get to from the anchor as reachable. When you're done, pop all the balloons that haven't been marked reachable. The cost of this will be linear in the number of balloons plus connections, which I think is close to optimal for this problem (since a shot could possibly pop every balloon in the graph, you at least need to do O(balloons) work).

Why didn't you just tell us you are making a Frozen Bubbles clone? Would have made the question way shorter :)
If you want to avoid a search, do some sort of reference counting scheme:
For each ballon, mantain the list of child (attached) ballons and an integer counting the number of parent (anchoring) baloons. When a ballon pops, go through all its children and decrement their anchor count. If the child ballon is left with no parents left after this then pop it as well (do it recursively or add it to some queue...)
This should work as long as no circular dependences are possible. (I think this is the case. However, if there are circular dependences the graph search is the only solution)
By the way - doing an exaustive search to find the connected ballons is only O(number of ballons). I seriously doubt your game has so many ballons that this will become a real problem. After all, rendering the ballons in the first place should have the same complexity...

When a balloon finds an anchor, have it tell its anchor(s) that it is anchoring.
Keep a list of anchored balloons on the anchor
Keep a list of anchors on the balloon that found an anchor(s)
when the anchor goes away tell the anchored balloons that its gone.
Then you can use the list of anchors to determine if you need to move up.
Assuming you can have more than two balloons stacked, you should also probably traverse down and just move the last one the right amount of spaces up instead of moving each one individually.

Related

Shortest path with blocking units and moving units on a grid

I'm trying to approach this problem of moving objects on a grid from start to finish. I'm well aware of A* Pathfinding algorithm, but I'm a bit clueless to how I can modify it so it will handle my problem:
I have a WxH grid. I need to move the star box to the empty box position (they are always in the same positions: 0,0 and W-1,H-1). My starting point is the empty (W-1,H-1) place, and each step I take is non-diagonal. If I move up, I need to move the box that blocks my way downwards to the empty space, and so forth until I reach the star (0,0) and then I need to start moving it the same way towards my starting point. To make things easier, the movement of the star is always to the direction of the starting point and never away from it. I need to find the shortest route to do so, aka the shortest number of steps required to move the star to the start position.
Here is a 2x2 grid to illustrate the problem:
This is obviously a shortest path problem (maybe A*), but I can't figure out the modifications needed here. I'm not looking for solutions or answers, just for a direction, because I'm a bit lost of where should I even start.
P.S. the grid might also have immovable boxes, but I can handle this once I understand the algorithm behind the problem itself
I'm not looking for solutions or answers, just for a direction, because I'm a bit lost of where should I even start.
Hint: instead of treating each block as a node in the graph, treat the entire state of all the blocks as a single node. Then the neighbors of each node are the states that can be reached in a single move.

Simple java game: Filling up figures drawn by a moving cursor

So I'm doing the project of an introduction to Java course and it seems that I chose something that goes way beyond what I'm able to do. :P
Any help would be greatly appreciated. This is what I'm having problems with:
You have a cursor that is controlled by a player (goes forward or
turns 90°) which leaves a colored line as it goes. If you manage to go
over your own line and close a polygon of any shape (only right angles
though), its surface changes color into the color of your line.
I can detect when this situation arises but I am kind of lost as how to actually fill the correct polygon just closed. I can't seem to imagine an algorithm that would cover any case possible.
I looked at the Scanline fill algorithm but I think it would start having problems by the time there are already some polygons already filled in the map.
The Floodfill algorithm would be perfect if I had a way of finding a point inside the polygon, but, as there are many different possibilities, I can't think of a general rule for this.
I'm using an array 2x2 of integers where each color is represented by a number.
Does anyone have an idea on how to approach this problem?
If you can detect the situation then this can be solved in very simple manner. The question is which point to choose as start point for floodfill. The simple answer is: try all of them. Of course it makes a sense to start only with points adjacent to the one where your cursor is located. In this case you will have at most 8 points to check. Even better - at least 2 of them are definitely painted already if current point forms a polygon.
So you have 8 points to check. Launch floodfill 8 times starting from each of those points.
Two things which you probably should keep in mind:
You should try filling the area in cloned version of your field in order to be able to get back if floodfill will not find a polygon.
Launching floodfill second time and later you should reuse this cloned version of your field to see whether it was filled there. This will allow you to check every point at most once and this will make your 8 floodfills almost as fast as 1 floodfill.
Check this question, using Graphics2 and Polygon to fill an arbitrary polygon: java swing : Polygon fill color problem
Finding out whether a point is inside or outside a polygon: http://en.wikipedia.org/wiki/Point_in_polygon
Make sure you use double buffering. If you set individual pixels and don't use double buffering the component may redraw after every pixel was set.

Writing a demo for snake game

I've written a snake game in Java. What I also want to do is to create a demo for that (so snake would play by itself). I've written a simple demo, but snake dies pretty fast. So, is there any algorithms or something for that kind of problem? I believe it is a little bit similar to chess game problem? I want that snake would be alive as long as possible. Thank you.
The Google-sponsored AI Challenge ran a "Tron" game in 2010. You might get some good ideas from searching for solutions to that challenge.
If you just want a very simple strategy that makes a reasonable demo then you might try something like the following:
Never make a move that causes you to crash unless you have no other option
If your next move forces you to choose between two or more distinct (unconnected) spaces, always move into the larger of the two spaces. This will stop your snake from getting trapped too easily.
If you are moving along a wall, keep moving along the wall 98% of the time, following it around to the left or right as needed. This will help your snake look reasonably intelligent, and also conserve space in the playfield.
Otherwise move ahead 90% of the time, turn left and right randomly 5% of the time each (this will make your demo less boring).
Apart from that, I don't think a Chess-style AI approach (with a move search tree) would work very well. You wouldn't be able to easily search enough moves in advance.
This is not the answer you are looking for, but I post it because I would genuinely like to see you explore this algorithm further, modifying it until you find yourself with a pretty reasonable AI:
The simplest algorithm to solve this problem is the "go around the edge, and then squiggle downward" approach. Basically, you start out with a snake, get it so it is moving west, then hug the west wall, then the ceiling. Then you traverse over every possible square like a slinky until you get to the bottom, go west, and start all over again.
If you try, you can turn this into a really excellent AI :D
Without doing the work for you, I can tell you that the best way to start approaching a problem like this is to think about what the snake should do to survive as long as possible. What 'rules of thumb' should the snake follow in order to stay alive. For starters the snake should probably turn before it hits an obstruction, and towards a direction where it won't be boxed in. So, you can program the snake to turn when it is within one space of it's tail (or wall) and towards a direction with the greatest distance between it and other obstructions. Also, snake I believe is a game in which the computer can play perfectly and in your demo you may not want that so you can always throw in some randomness just to spice things up if things get too same-y.

Flocking boids behaviour problem

Yesterday I came across Craig Reynolds' Boids, and subsequently figured that I'd give implementing a simple 2D version in Java a go.
I've put together a fairly basic setup based closely on Conrad Parker's notes.
However, I'm getting some rather bizarre (in my opinion) behaviour. Currently, my boids move reasonably quickly into a rough grid or lattice, and proceed to twitch on the spot. By that I mean they move around a little and rotate very frequently.
Currently, I have implemented:
Alignment
Cohesion
Separation
Velocity limiting
Initially, my boids are randomly distributed across the screen area (slightly different to Parker's method), and their velocities are all directed towards the centre of the screen area (note that randomly initialised velocities give the same result). Changing the velocity limit value only changes how quickly the boids move into this pattern, not formation of the pattern.
As I see it, this could be:
A consequence of the parameters I'm using (right now my code is as described in Parker's pseudocode; I have not yet tried areas of influence defined by an angle and a radius as described by Reynolds.)
Something I need to implement but am not aware of.
Something I am doing wrong.
The expected behaviour would be something more along the lines of a two dimensional version of what happens in the applet on Reynolds' boids page, although right now I haven't implemented any way to keep the boids on screen.
Has anyone encountered this before? Any ideas about the cause and/or how to fix it? I can post a .gif of the behaviour in question if it helps.
Perhaps your weighting for the separation rule is too strong, causing all the boids to move as far away from all neighboring boids as they can. There are various constants in my pseudocode which act as weights: /100 in rule 1 and /8 in rule 3 (and an implicit *1 in rule 2); these can be tweaked, which is often useful for modelling different behaviors such as closely-swarming insects or gliding birds.
Also the arbitrary |distance| < 100 in the separation rule should be modified to match the units of your simulation; this rule should only apply to boids within close proximity, basically to avoid collisions.
Have fun!
If they see everyone, they will all try to move with average velocity. If they see only some there can be some separated groups.
And if they are randomly distributed, it will be close to zero.
If you limit them by rectangle and either repulse them from walls or teleport them to other side when they got close) and have too high separation, they will be pushed from walls (from walls itself or from other who just were teleported, who will then be pushed to other side (and push and be pushed again)).
So try tighter cohesion, limited sight, more space and distribute them clustered (pick random point and place multiple of them small random distance from there), not uniformly or normaly.
I encountered this problem as well. I solved it by making sure that the method for updating each boid's velocity added the new velocity onto the old, instead of resetting it. Essentially, what's happening is this: The boids are trying to move away from each other but can't accelerate (because their velocities are being reset instead of increasing, as they should), thus the "twitching". Your method for updating velocities should look like
def set_velocity(self, dxdy):
self.velocity = (self.velocity[0] + dxdy[0], self.velocity[1] + dxdy[1])
where velocity and dxdy are 2-tuples.
I wonder if you have a problem with collision rectangles. If you implemented something based on overlapping rectangles (like, say, this), you can end up with the behaviour you describe when two rectangles are close enough that any movement causes them to intersect. (Or even worse if one rectangle can end up totally inside another.)
One solution to this problem is to make sure each boid only looks in a forwards direction. Then you avoid the situation where A cannot move because B is too close in front, but B cannot move because A is too close behind.
A quick check is to actually paint all of your collision rectangles and colour any intersecting ones a different colour. It often gives a clue as to the cause of the stopping and twitching.

PacMan character AI suggestions for optimal next direction

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.

Categories

Resources