Most efficient method to randomly generate a location on some certain area? - java

I am working on a "greedy snake" game. I am using a 2d array to store the value of each location/grid of the map: either egg or snake body or empty. The egg needs to be generated on the empty spot. One solution could be:
while (new egg location overlaps snake body)
Within the range of 2d array randomly generate an egg location
However when the snake grows very big and fills up most area of the map, the generating new egg become very inefficient, since it has to check almost every element of the 2d array. How can this be optimized?

Maintain a list of all empty squares. Every time you need a new random empty square use:
Collections.shuffle(list).get(0);

First, I would like to say that there is nothing wrong with your solution. The only issue you get is that late game (when most of the squares are taken up by the snake) you may have to try a large number of times to find an empty space.
In this situation OldCurmudgeon's solution is a good fit. However, it suffers from a different issue. Maintaining a list of empty squares from a large empty grid is a waste of time.
So early in the game, your current solution is preferable. But late game their solution is better.
So I would suggest doing a check on the size of the snake. If the snake takes up less than half of the grid use your current solution. Only when the snake takes up more than half of the grid start maintaining a list of empty squares.

Give all the spaces the snake currently occupies as an input and then check from the remainder. Won't quite get to O(1) but will reduce how much of your array it needs to go through.

public Point generateRandomPoint(){
Random rand = new Random();
Point p;
boolean goodPoint = false;
//while the point selected is not empty
while (goodPoint!=true){
p= new Point(rand.nextInt(MAX_X),rand.nextInt(MAX_Y));
//is the point empty
goodPoint = array[p.x][p.y].equals("empty");
}
return p;
}
If you use this, then it only checks the space that the egg would be spawned on. Now, because it is random, it may have to check a lot of spaces, but unless your board is a couple thousand across, it should be almost instant (<<50 ms).

Related

2D Arrays Battleship place random ships

Hi, I just started to create a battleship game and I would like to know how to place random ships in my 2D Array. Here is the code for 2D Array.
public class javaapplication24 {
public static void main(String[] args) {
int[][] table = new int[10][10];
int i,j,k;
for(i=0;i<table.length;i++){
for(j=0;j<table.length;j++){
System.out.print(table[i][j]+" ");
}
System.out.println();
}
}
}
The problem that you have undoubtedly noticed is that as each ship is placed, it rules out possibilities of where subsequent ships can be placed. The easiest way around the difficulty is just trial and error. First write a function for randomly placing a ship of a given size somewhere on the board. Place the ships using a nested loop. The outer loop could be a for-loop which iterates through the ships to be placed. The inner loop can be a while loop (or maybe a do-loop) that repeatedly calls the ship-placing function to get a candidate placement, then checks if it clashes with previous choices, looping until a clash-free placement is found.
As far as placing a single ship goes:
1) First generate a random number which is either 0 or 1 to determine if the ship will be placed horizontally or vertically
2) Then pick a random number to determine what the row or column it will be in
3) Finally, pick a random number for the first square in the row or column that contains the ship. The size of the ship will enter in here. If it has length 3, for example, then there are only 10-3 = 7 possible choices for the first square (assuming a standard 10x10 board).
On Edit: #Manus raised a good point about difficulties that would be encountered if the number of ships are above a certain threshold. If you have a massive fleet of ships on a small board it is possible that certain partial placements (of some of the ships) would rule out any valid placement of the remaining ships. The only way I see around this difficulty is to use a back-tracking approach that checks if there is enough room for a ship before trying to place it and, if not, revisit the placement of previous ships until you get something that works. But -- the work involved in checking if there is any valid position can be done in such a way that you simultaneously determine the set of valid positions, in which case you might as well directly pick from that set rather than use trial and error. My approach is essentially a quick-and-dirty approach for simulating the child's game. You would need a more sophisticated approach if you want a more flexible game.

Check if the mouse is over a circle - Java

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.

Java more efficient array searching

I am coding a game using LibGdx and I have an array with all of my wall objects that the player can collide with. For those who don't use LibGdx, I am talking about LibGdx's Array class which provides the same functionality as an ArrayList but it's built with memory efficiency in mind. When I check for collision, I am having to go through every wall in the array and check for collision like this:
for(Wall w : walls) {
if(w.bounds().contains(player.bounds()) {
// handle collision
}
}
I realized this was inefficient because I am going through every wall even if that wall is off the current view of the map. Obviously, if I am checking for collision with walls currently in the camera's viewport (this means they are currently visible by the player) then there is no point in going through the whole array because the player can't collide with them until they come into view. I was thinking of making my game a bit more efficient by only checking for collision with walls close to the player. In my game, I have all of the walls snapped onto a grid with cells 32x32 px. I really don't know how I could create more efficient searching for collision. Could I use like a map of some sort which uses a vector2 position for its key and then look up the player's position and look through walls within a certain range from the player's position in the map? I am just really lost on how to have code that won't go through all 100+ walls in my game when there are only 10 current possible walls that the player could touch because of where it currently is. Does this make any sense? Could someone explain a good way to do something like this? Thanks so much.
There are lots of collision alghoritms out there, you will need to find one that suits your need.
One solution I can think of on the top of my head is:
Keep your wall list sorted on their coordinates. If you create a new wall, use insertion sort to resort your array. When you want to check for collisions, take the objects coordinates (in this case probably the player that is running) and do a binary search to find the closest wall to the player. Then calculate if the player and this wall collides. If the closest wall isn't causing a collision, you can be pretty confident that no other wall is as well.
Each wall is on one or more of these 32x32px grids. Let the coordinates of a grid be x and y. If a grid contains a wall, enter this into a
HashMap<CoordPair,Set<Wall>> xy2wall
To investigate where a location is in contact with a nearby wall, use the coordinates of the location to determine a small set of grid coordinates, fetch the set or sets of Walls mapped by these CoordPairs. I guess the Player.bounds() can provide a suitable set of coordinates.
If the 32x32 grid results in too many entries, you can always use a coarser grid.
I once came into the same realization that you have while developing a top down rpg.
There are more walls than you can imagine in a top down rpg.
Here is how I solved it:
First: Segment the map into zones ie.) draw your map on paper or something and cut it up into parts.
Second: Record the pixel boundaries for each segmented section of the map.
Third: Check where your players location is with respect to the boundaries.
Finally: Only check the walls within those boundaries.
In a realm of infinite walls this is not any more efficient (speaking about Big O) but for all practical purposes this is effective in cutting down on lookup times
if (boundary1.contains(player1)) {
for(Wall w : Boundary1Walls) {
if(w.bounds().contains(player.bounds()) {
// handle collision
}
}
}
else if (boundary2.contains(player1)) {
for (Wall w : Boundary2Walls) {
if(w.bounds().contains(player.bounds()) {
// handle collision
}
}
}
....
Continue in this fashion
Take note... I did it like this before going to college for software development, so I did not make use of data structures such as BST which could be used to store walls with respect to their coordinates. Making your lookup time extremely fast.

Tetris with Custom Images

I am working out a concept for a Tetris style game with a twist. I have worked through a few tutorials for the basic logic but with the way we are wanting to do this, I am not sure if the logic is even possible in our time frame.
Basically, we are using custom images for the Tetris pieces. We have three different colors for each and a different image for each possible rotation. On top of that, our game will be trying to pair letters together so we have images with each possible rotation with each possible letter placement. For example, for the "T" shape, we have right now 92 images of each possible rotation for just ONE of the three color's we want to use with the four letters we are using. After thinking about it for the past few days, there is going to be hundreds (maybe even over a thousand) images.
However, that's not the issue. The only way I can think of checking is using a TON (like well over a thousand) IF statements. For example, if piece 1 which is a "T" shape with an "A" on the right side, we need to check if "B" is next to any of the other possible positions the piece can ever be in. If a piece with an "A" on it is next to (either above, below, or on either side) a piece with a "B" on it, a good match with be registered. If at any point two letters that are the same land next to each other, the whole row of pieces that the are a bad match will disappear causing any pieces above it to fall down. Once these pieces land again, every single piece needs to be checked again to see if its new position is a part of any possible letter pair. The checking will always need to be happening for every single piece that is spawned onto the game board so the more pieces there are, the more checking that needs to always be happening.
So, is this something that will simply take way to long (we have just over a month) or is there something else that can be done besides a TON of IF statements? Is something like this even possible? After all we are talking most likely 1000 images and every single image needs to always be getting checked if it:
Has hit another image and needs to stop
Check if where the player placed it is next to another letter and if it is a good
letter match or not (this is the big issue)
Once a whole piece disappears, the pieces need to shift down again and get all the checking needs to happen once again.
The plan is to do this in java since its the only language I have a good understanding of but I am open to any and all suggestions. If its a lost cause, please let me know. Would like to come up with another concept before I invest a lot of time into this if it is a lost cause.
EDIT:
Here is a very quickly tossed together image that gives you an idea of what it looks like:
http://imageshack.us/a/img560/1814/dg80.png
Looking at this image, you see 4 pieces already in place at the bottom of the board and the player is guiding the straight piece down. The player wants to match the "A" at the bottom of the line with the "A" that is in the right "square" of the "T" shape. Once the piece has landed next to the "T", the code needs to say "Oh hey, another "A" just landed next to me so I am a good match and we both need to disappear". Once that has happened, the other pieces will shift down and the checking needs to happen again. Since there are SO many combinations of pieces and with players having free reign to put pieces in crazy spots, the checking needs to be insane. Every single piece needs to check with all the other pieces to ensure a valid combo is never missed.
Here is an example of what a piece looks like:
http://imageshack.us/a/img23/6632/1g3q.png
What you will probably want to do is think of your Gamefield as a 2 dimensional array with a set of cells. Each row is N cells wide and there are M rows. Now whenever a piece gets dropped anywhere you register the letters in the piece in the gamefield array.
Lets assume your pieces look like this:
public class GamePience {
public Character letter;
public Color color;
}
This gives you
GamePience[][] gamefield = new GamePience [M][N]; // null is empty, otherwise gilled
When a piece is dropped you copy it's letters to the array (for simplicity I'm assuming pieces are also 2 dimensional arrays because that works well)
gamefield[0][2] = piece[0][0];
Now after a letter is placed and copied to the field you can simply check the over the field
boolean destroyedLine = false;
do {
for (int x = 0; x < gamefield.length; x++) {
for (int y = 0; y < gamefield[x].length; y++) {
GamePiece cur = gamefield[x][y];
if (cur != null && x < MAX_FIELD_WIDTH && gamefield[x+1][y] != null) {
// there are gamepieces in both!
GamePiece neighbour = gamefield[x+1][y];
if (cur.letter == neighbour.letter) {
destroyLine(x); // this method should null out the line and shift everything down, you'll probably want to loop trough the whole line first and check if there are pieces in every cell
destroyedLine = true;
break;
}
}
}
}
} while(destroyedLine);
You can also easily check against the gamefield while dropping down pieces to check if the cells are already filled.
Now, all you need to do is fill out that logic and write some code to draw the gamefield and you are set ;) (you might want to think about using an LinkedList for the gamefield because that makes deleting rows trivial)

Efficient algorithm for collisions in 2D game?

I'm programming a Bomberman in Java following a tutorial (this is my first game).
The tutorial suggests the following code for detecting collisions.
for (int p=0; p<entities.size(); p++) {
for (int s=p+1; s<entities.size(); s++) {
Entity me = (Entity) entities.get(p);
Entity him = (Entity) entities.get(s);
if (me.collidesWith(him)) {
me.collidedWith(him);
him.collidedWith(me);
}
}
By now, entities is an array list containing the enemies and the player.
As I want to also detect the player collides with walls, should I put every single wall or bricks tile in the level into the entities arraylist? If so, isn't this algorithm very inefficient? These tiles aren't going to collide with other tiles, so I was thinking to manage game entities in different lists. What do you suggest? Is there a more efficient algorithm to do it?
Note: I already read other questions related to collisions in 2D games.
Thanks a lot.
I suggest reading this excellent article about how ghost movement and collision detection works in PacMan.
Then I would suggest logically modeling your Bomberman levels as a collection of tiles. Each tile represents a discrete position in your level, and it is not logically possible to ever be "between" tiles or occupying two tiles at the same time. Each tile can track what sort of terrain feature is currently on it, and whether or not it is a valid destination tile for the player (and the enemies, potentially with different rules for each if the enemies are allowed to traverse terrain that is normally impassable for the player).
Then you don't need a collision detection algorithm for every object in the world. When it comes time for an enemy to move, or when the user tries to move their character, all you have to do is check all the tiles that are adjacent to their current tile (4, or 8 max if you allow diagonal movement), see if each tile represents a valid movement direction, and block the movement if it is not in a valid direction.
And to answer your question, yes, iterating every object in the world on every position update will be very inefficient.
There is another way to use grids for collision system. I'm using more complex version of the Aroth's suggestion and using this to fix collision bugs.
Theoretically this system is the fastest(assuming you are doing this check if(Grid[x][y] ==true)) because it only uses a single Boolean check for each entity(the things that can move).
Note: In the above grid check example, I've used a 2 dimensional array of booleans that sets the coordinates of impassable grids to false.`
If you are not worried about physics like bouncing from a wall you can use this:
1- Divide the map into grids.
2- Making every entity only fill a tile would be better but not necessary.
3- Store the previous position or the grid of the entities.
4- Whenever an entity moves, before visually updating their location (also before
doing other calculations) check the grids they are in. If they are in grid
that is not empty or simply in a grid that they are not supposed to
be, return their position back to the previous position (which you have stored).
If you want to allow entities to move freely inside the grids(the grids are bigger than the minimum distance they can move) then you need to put them adjacent to the grids they've entered and they weren't supposed to. Otherwise just return them back to the previous grid.
If you want them to bounce from the wall you can still use this but I'm not sure how many features can be added to a collision system like this.
May I recommend my own project. But it's still wip.
https://github.com/YagaoDirac/Dirac-2d-collision-detection-for-games
It's based on quad-tree which handles sparse pretty well.
It supplies collision group. This conception is also used in both UE and Unity.
It support only circle vs circle and overlapping only for now(2022 feb 22).
I plan to make at least AABB, and collision which at least stop your pawn from leaving the map.
I may also provide another system based on fixed grid.

Categories

Resources