I'm currently dabbling in Java AI programming, and trying an AI challenge. In the challenge, my AI is given 2 seconds to respond to the new game state. If these two seconds are exceeded without producing a response, my AI forfeits. The game consists of a grid with goals and enemies, each enemy being an independent AI generated by the game. I have implemented a standard A* to find the nearest available goal.
I would like my A* algorithm to increase the cost of squares near an enemy that could potentially prove dangerous, thus avoiding dangerous paths. I am considering a two-dimensional array containing the estimated loss of health for each square, limited to calculating within ~2 squares of each enemy (~5x5). Each turn, for each enemy this array would have a 5x5 square set to 0 and recalculated.
Assuming I write code that only does what it must and moves on... Will a two dimensional array of between 20x20 and 100x100 elements significantly effect execution time? Is a two dimensional array of estimated threat per square a good method of calculating cost in an A* algorithm so as to avoid enemies?
UPDATE:
I got it working absolutely perfectly. The cost function I used:
For each enemy
Calculate manhattan distance
If 0 or 1, cost += absolute(enemy health - health) / 5
Else if 2, cost += absolute(enemy heath - health) / 10
Else cost += 0
Using it, I saw some really impressive pathfinding and moves; the bot would often take calculated risks where there were no other moves to get to a goal, but basically avoided enemies otherwise. I was thoroughly impressed with how insignificant the performance cost was of adding the heuristic. It's not a perfect solution for the game, but it showed me how robust A* can be.
A* is generally used for pathfinding, but I'm going to modify it for the purpose of a game state lookahead. I'm pretty sure that turns it into a minimax algorithm.
If you are only calculating the content of your array once and the calculation
for each cell is something simple like checking a few adjacent cells for enemies then
a 100x100 array is no work at all relative to your time constraints.
Given the information in your post it sounds like a good idea to me.
Related
I am making a 2D car game like earn to die 2. I ve almost completed it. Only problem is the physics engine performance. I am using box2d and there are 10 meters length edge shapes totally building a 100 km terrain. 1 car and usually 30-40 boxes. Number of active dynamic bodies is around 60-100, max 120. Game fluently working in desktop but in android fps drops below 30 when actives bodies are more than 60. There are collisions between car and boxes and boxes each other and both box and car to ground.
I am using libgdx framework 1.9.4 as version, java is 1.7, coding with eclipse neon, windows 7.
this is how I am counting active bodies in world
int num=0;
Array<Body> bodies=new Array<>();
world.getBodies(bodies);
for(Body b:bodies){
if(b.isActive())num++;
}
active dynamic bodies are usually around 100
it is not a drawing issue with all terrain and underground meshes and car and boxes cost 6-7 mili seconds I measured them when box2d debug rendered is off and world step method call costs about 30 mili seconds when there are about 30 boxes while the car is crushing into them
I don't load all game objects (boxes for now) I splitted entire map into chunks map size is 100 km and chunk size is 50 meters when the car is in the next 50 meters ( in the chunk range) I load the boxes from a ready pool ( box2d world representations of the those objects are also pooled and when the boxes are in pool I deactivate their box2d body with setActive(false) and back to true while the chunk is loading)
I applied this chunk system for terrain too. I load all the terrain when the game is loading then deactivate them by setting with this method setActive(false) and when the car goes on trough the map if the chunk range includes car's x axis coordinate I activate the next chunk which contains the terrain static bodies having around 20 fixtures with size of 10 meters, makes the chunk size 200 meters at total.
the green lines are active terrain shapes as you see left and right after a distance are deactivated till the end of the map this part is from around 60 km of the map in middle of 100 km terrain map.
when vehicle moved little more new boxes will load there ahead and old ones will be pooled if they are 20 meters back from the car.
My questions are
1) is this fps (20 fps) normal and expected?(android 7 this is phone specifications http://www.androidpolice.com/2016/02/23/the-general-mobile-gm-5-plus-is-the-most-powerful-android-one-device-yet/)
2) can the 100 km terrain be problem if so how should I manage it?
->I tried activating/deactivating terrain bodies when they out of the screen rectangle.
->I tried hundreds of fixtures on a single body or every terrain piece is as separated body but best performance with I splited 100 km terrain into 200 meters chunks and each chunk is a body and consist of about 20 fixtures.
3) simulating 100 dynamic bodies with huge edge shape terrain is tottaly impossible ? ( but in the earn to die they did it)
4) should I write my own simple physics for only this kind of game (a simple specific one) ?
5) should I use bullet physics instead of box2d for 2D purposes ? is it possible? and will I face with performance problems ?
if you need any code pls comment, I will add.
are there any really fast physics engines I couldn't find on the net if there are do you suggest to change box2D ?
good to note:
I am simulating box2d with constant time step I tried 1/60 1/45 1/30 and 8-3 , 6-
2 as iteration steps.
I use high damping values like .9 for both linear and angular for all bodies.
I also would like to split those boxes into pieces actually I am doing it but without splitting hem when car crushed I am experiencing this fps drop so I disabled it for now.
Only joints are wheel joints and used for wheel of car no more joints in anywhere in map.
Sizes are realistic those boxes are 1.2 meters high.
for boxes and cars polygon shapes used for terrain edge shapes used (chain shape)
velocity threshold is 1 as default in world settings.
if there are any notes I forgot pls comment and I will share.
thank you.
Disclaimer: I can't answer all of your question, and below are just a guess from me.
A few years ago, I developed a game prototype and game library with Java + box2d + plain Opengl (LWJGL).
I think you are facing some issues that occurred to me.
However, with my low experience, I could be wrong.
If experts (readers) think that there are any mistake in my post, please comment below, I will fix it.
My guess
Java is slow / not quite suitable for game.
Disclaimer: There is a lot of argument about this.
I am not an expert enough to put a solid statement here, but I see a lot of my game-prototype run 3x-10x faster in C++ than Java. (with not-so-different algorithm)
Memory fragmentation
As you may already know, even you use pool, it is still very poor compared to C++.
You pool the boxes, but you can't pool everything, e.g. game logic data-structure, vector2D, plain array (new[] often), some horror algorithm in some libraries that you use.
Deactivated bodies still cost memory (intensify memory fragmentation indirectly).
You have a lot of static bodies / high complexity of static body.
You didn't mention how many static body you have, and what are them.
Are you using a high-amount-of-vertices shape for the terrain?
Popular physic engines like Box2D and Bullet are cool at convex shape, and expert at primitive shape, but tend to work poorly with concave shape (e.g. your terrian)
Your shapes are continuously colliding each other.
For example, a stack of 100 boxes cost a lot more computation than 100 boxes scattering around the scene.
Too large world
As far as I know, box2d divide a scene (world) into a grid. If your world is very large, but a lot of body cluster into the same cell of the grid, Box2D will work relatively worse.
It is not limited to Box2D.
Bullet and Ogre3D - in certain configuration - also suffer from this issue.
Answer (guess again)
1) is this fps (20 fps) normal and expected?
I don't know about moblie, but your code can still be optimized in some ways. (see below)
2) can the 100 km terrain be problem if so how should I manage it?
Unfocused chunk -> remove the body (not just deactivated it).
Yes, it is easier said than done, you may just deactivate near chunk, but remove (delete) all bodies in chunk that is far away (> 3 chunk-distance, may be).
If the deleted chunk can come back to the scene, you may have to find a way to save it somewhere. (e.g. save only position of body, size, weight)
3) simulating 100 dynamic bodies with huge edge shape terrain is tottaly impossible ? ( but in the earn to die they did it)
They did, or you just think they did?
In some aspect, programming is an art.
Thing you see can be very different from how they are actually implemented.
You bottleneck may be only the terrain - reduce its level-of-detail may also help.
4) should I write my own simple physics for only this kind of game (a simple specific one) ?
No, except you want to learn && have a lot of time && really love Math.
5) should I use bullet physics instead of box2d for 2D purposes ? is it possible? and will I face with performance problems ?
I think you will still face in some degree.
Constraint is expensive for both Box2D and Bullet.
Are you sure you really need constraint?
In some cases, it can be avoided with compound shape / modify design of the game a bit.
I think if you change to C++ and Bullet, you will gain about at least 3x performance, but I am not sure about it at all.
I have to implement a Reversi game for Android. I have managed to implement all the game, is functional, but the problem is that I don't have an AI. In fact, at every move the computer moves in the position that achieves him the highest number of pieces.
I decided to implement and alpha-beta pruning algorithm. I did a lot of research on the internet about it, but I couldn't come to a final conclusion how to do it. I tried to implement a few functions, but I couldn't achieve the desired behaviour.
My board is stored in class Board (inside this class, the pieces occupied by each player are stored in a bi-dimensional int array). I have attached an small diagram (sorry about the way it looks).
DIAGRAM: https://docs.google.com/file/d/0Bzv8B0L32Z8lSUhKNjdXaWsza0E/edit
I need help to figure out how to use the minimax algorithm with my implementation.
What I understood so far, is that I have to make an evaluation function regarding the value of the board.
To calculate the value of the board I have to account the following elements:
-free corners (my question is that I have to take care only about the free corners, or the one that I can take at the current move?! dilemma here).
-mobility of the board: to check the number of pieces that will be available to move, after the current move.
-stability of the board… I know it means the number of pieces that can't be flipped on the board.
-the number of pieces the move will offer me
I have in plan to implement a new Class BoardAI that will take as an argument my Board object and the dept.
Can you please tell me a logical flow of ideas how I should implement this AI?
I need some help about the recursion while calculating in dept and I don't understand how it calculates the best choice.
Thank you!
First you can check this piece of code for a checkers AI that I wrote years ago. The interesting part is the last function (alphabeta). (It's in python but I think you can look at that like pseudocode).
Obviously I cannot teach you all the alpha/beta theory cause it can be a little tricky, but maybe I can give you some practical tips.
Evaluation Function
This is one of the key points for a good min/max alpha/beta algorithm (and for any other informed search algorithm). Write a good heuristic function is the artistic part in AI development. You have to know well the game, talk with expert game player to understand which board features are important to answer the question: How good is this position for player X?
You have already indicated some good features like mobility, stability and free corners. However note that the evaluation function has to be fast cause it will be called a lot of times.
A basic evaluation function is
H = f1 * w1 + f2 * w2 + ... + fn * wn
where f is a feature score (for example the number of free corners) and w is a corresponding weight that say how much the feature f is important in the total score.
There is only one way to find weights value: experience and experiments. ;)
The Basic Algorithm
Now you can start with the algorithm. The first step is understand game tree navigation. In my AI I've just used the principal board like a blackboard where the AI can try the moves.
For example we start with board in a certain configuration B1.
Step 1: get all the available moves. You have to find all the applicable moves to B1 for a given player. In my code this is done by self.board.all_move(player). It returns a list of moves.
Step 2: apply the move and start recursion. Assume that the function has returned three moves (M1, M2, M3).
Take the first moves M1 and apply it to obtain a new board configuration B11.
Apply recursively the algorithm on the new configuration (find all the moves applicable in B11, apply them, recursion on the result, ...)
Undo the move to restore the B1 configuration.
Take the next moves M2 and apply it to obtain a new board configuration B12.
And so on.
NOTE: The step 3 can be done only if all the moves are reversible. Otherwise you have to find another solution like allocate a new board for each moves.
In code:
for mov in moves :
self.board.apply_action(mov)
v = max(v, self.alphabeta(alpha, beta, level - 1, self._switch_player(player), weights))
self.board.undo_last()
Step 3: stop the recursion. This three is very deep so you have to put a search limit to the algorithm. A simple way is to stop the iteration after n levels. For example I start with B1, max_level=2 and current_level=max_level.
From B1 (current_level 2) I apply, for example, the M1 move to obtain B11.
From B11 (current_level 1) I apple, for example, the M2 move to obtain B112.
B122 is a "current_level 0" board configuration so I stop recursion. I return the evaluation function value applied to B122 and I come back to level 1.
In code:
if level == 0 :
value = self.board.board_score(weights)
return value
Now... standard algorithm pseudocode returns the value of the best leaf value. Bu I want to know which move bring me to the best leaf! To do this you have to find a way to map leaf value to moves. For example you can save moves sequences: starting from B1, the sequence (M1 M2 M3) bring the player in the board B123 with value -1; the sequence (M1 M2 M2) bring the player in the board B122 with value 2; and so on... Then you can simply select the move that brings the AI to the best position.
I hope this can be helpful.
EDIT: Some notes on alpha-beta. Alpha-Beta algorithm is hard to explain without graphical examples. For this reason I want to link one of the most detailed alpha-beta pruning explanation I've ever found: this one. I think I cannot really do better than that. :)
The key point is: Alpha-beta pruning adds to MIN-MAX two bounds to the nodes. This bounds can be used to decide if a sub-tree should be expanded or not.
This bounds are:
Alpha: the maximum lower bound of possible solutions.
Beta: the minimum upper bound of possible solutions.
If, during the computation, we find a situation in which Beta < Alpha we can stop computation for that sub-tree.
Obviously check the previous link to understand how it works. ;)
I'm creating a game which has around 3000 particles that fall into a pile. The particles are each a pixel and i just use a boolean[][] to set and check which pixel is clear. Right now i am using this code
if (!isFalling(m)) {
if (isClear(getX() + 1, getY()) && isClear(getX() + 1, getY() - 1))
setX(getX() + 1);
else if (isClear(getX() - 1, getY()) && isClear(getX() - 1, getY() - 1)
setX(getX() - 1);
}
the problem is that this code gives me a very strict pyramid shape which doesnt look very natural. I want it to look something like salt would if you poured it into a pile. My question is, does anyone know of an algorithm or a better way to simulate particle piles?
Any help would be greatly appreciated.
Solution:
I have found a nice article here
You've taken on a big task :) It's not just how to calculate and draw the particles, it's the physics which describe how they should move.
Take a look at this for a starter:
http://www.daniweb.com/software-development/java/threads/426676/sand-game-problem-with-graphics
When Googling, try "particle generator" or "particle emitter".
Also see this question:
How do those java sand games keep track of so many particles?
The main thing you might be missing is to add randomness, some entropy, into your system.
So your function looks at particles which have settled to the bottom and asks if they can slide down the side, and then effects that motion if they can.
Do you have this in a loop? If so, you may be considering particles from the "bottom up" whereas the sliding motion may take place at any point on the pile. You could try shuffling the particle list prior to performing the loop, or repeatedly choosing random elements from the list until you get a low rate of settling.
In the case of a 2D array, you could try looping from different directions or finding other ways of mixing it up - again choosing pixels at random may not be a bad choice. Simulated annealing comes to mind.
Or, you could add a random check to your sliding condition. The particles should be semi-stable in their initial positions, so maybe there's only a 50% chance of them sliding down the side.
Hope this helps!
I made a program in Java where circles can bounce into each other and gravitate towards each other.
For the most part (few circles on the screen), there are no noticeable bugs. The problem starts to happen when there is a large amount of circles on screen. Sometimes, the circles will overlap if it gets too crowded. It's as if the weight of all the other circles are crushing the circles together, causing them to overlap. Of course, there program doesn't know anything about how much a circle weighs, so it's not really crushing. Most likely, the piece of logic that handles resolving collisions is not able to handle crowded situations.
Circles are stored in an array, and each circle goes through the array using a for loop, comparing itself to the other circles. If the distance between the center of this circle and the center of the other circle is less than the sum of their radii, then the circles are colliding. The velocities of both circles are updated using an equation for collisions.
I think the problem occurs because if a circle is surrounded, it might receive an updated velocity into the circle behind it, while the circle behind it also receives an updated velocity into the former circle. In other words, the two circles get told to move toward each other, even though they are already touching. Once they overlap this way, I don't know why they don't undo their overlap.
I've tried restoring touching scenario if they are overlapping by finding the distance they are overlapped, then moving them apart from each other; each moves half the overlap distance apart. This doesn't change the circle's velocity, only their position.
This still doesn't solve the problem. If the circle is surrounded, and it overlaps with one of it's neighboring circles, its position is changed so they aren't overlapping, but this new position may cause it to overlap with another circle. Same problem.
If there was no gravity pushing the circles together, they would eventually spread out and resolve their overlapping issues, but the gravity prevents this from happening.
Further information:
Gravity is not taken into account when calculating new velocities after a collision.
Sounds like your hunches about what is causing the problem are correct in both cases.
Unfortunately, there's no easy way to fix this issue - it pretty much means rewriting your whole collision detection & resolution code from scratch. You have to work out the exact timing of the first collision, update everything only that far, resolve the collision (do your velocity update) then work out the exact timing of the next collision, then repeat...
Writing a good physics engine is hard, there's a good reason that there are many textbooks on the market about this subject!
The cheap 'fix' for your problem is to reduce the time interval for updates - e.g. instead of updating the physics in 33ms steps (~30fps), try updating in 16ms steps (~60fps). This won't prevent the problem, but it will make it much less likely to occur. Halving the time step will also double the time the processor has to spend doing physics updates!
If you use the cheap fix, the time step which will work best for you will be determined by how frequently collisions occur - more collisions means smaller time steps. How frequently collisions occur basically depends on how fast the circles tend to move and their population density (how much of a given area is filled by circles).
UPDATE: A little more info on the 'proper' approach.
The update would go something like this:
Start updating a frame. Let's say we want to update as far as time tF.
For every pair of circles, work out when you would expect a collision to occur (ignoring all the other circles). Let's call this time tC.
Find the smallest value of tC. Let's say this is for the collision between circles A and B, and let's call that collision cAB.
If tC <= tF, update all of the circles up to time tC. Otherwise, go to step 6.
Resolve collision cAB. Go back to step 2!
Update all the circles to time tF.
As you might imagine, this can get quite complicated. Step 2 can be quite tricky (and coputationally expensive) for non-circular objects (especially once you include things like angular momentum, etc.) although there are a lot of tricks you can do here to speed it up. It's also basically impossible to know how many times you'll be looping between steps 2 and 5.
Like I said, doing good physics simulation is hard. Doing it in real-time is even harder!
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.