I've been trying to get over a problem :
Let's say, you have an 3*4 (3 row 4 col) :
Let's take A[1][3] for example :
He's adjacent to the A[2][3], who is adjacent to A[2][2]
My goal, like the "SameGame" Game, is to find a way in order to have every adjacent similar characters' positions in an array in order to highlight them.
At first, I was thinking about doing a loop to check neighbors everytime I found some adjacent similar character, but it seems like a lot of pain for something like this.
if((this.tabi[x][y] == this.tabi[x+1][y])) {
this.group[x+1][y] = this.tabi[x+1][y];
this.group_size++;
// call it again for this.tabi[x+1][y]
}
}
Is there a more "performant-wise" solution ?
The board is generated randomly :
for (i=0; i<row; i++) {
for (j=0; j<col; j++) {
tab[i][j] = A OR B OR C
}
}
Thanks !
You could use a pathfinding algorithm like Dijkstra or Fjord-Warshall between two Group-Elements and treat every other group as an obstacle.
It's hard to tell, if you don't post a bit more about how you manage your playing field, elements and groups.
Related
I'm making a snake game and the apples shouldn't spawn inside the snake when randomly spawned on the screen. I have tried looking for a new place for the apples, when they get placed inside the snake with:
for (int i = 0; i < snake.size() - 1; i++) {
if (snake.get(i).xPos == plum.get(0).xPos && snake.get(i).yPos == plum.get(0).yPos) {
plum.remove(0);
plum.add(new Coordinate(rollDice(squaresX - 1) * (squareSize + sizeOfSpace) + sizeOfSpace, rollDice(squaresY - 1) * (squareSize + sizeOfSpace) + sizeOfSpace, new Color(199, 7, 255)));
}
}
This is not a good solution so I'm looking for a new one where I can create invalid coordiantes which are the snakes coordinates and valid coordinates that is the rest. So I can randomize the apples new position from just valid coordinates. But I'm not sure how I'm supposed to code this
This is just a general suggestion, but I think it might work for you.
Keep the length of the snake updated all of the time
Now when creating a new apple, create an array of Coordinations of size of the grid size minus snake length. For example: if your grid size is 9x9 and your snake length is 6, create an array of length 75.
Run over the grid and array and add to the array just Coordinations that do not have the snake in them. It should look something like this:
int arrayLocation=0;
for(int i=0; i< grid.length();i++)
{
for(int j=0; j<grid[i].length(); j++)
{
if (!snakeAtLocation(i,j))
{
arr[arrayLocation++] = new Coordinate(i, j);
}
}
}
Then you can randomly pick a number n between 0 to arr.length(), then retrieve the coordination from arr[n] and you should have a coordination without a snake in it. Hope it helps and if you need more detailed example I will provide tommorow as I'm writing this from my phone and I don't have pc right now:)
By the way, this answer if for a simple use case, as it isn't optimized and running with o(n)^2 each time you eat an apple. If you want more optimized solutions, you would have to track the snake location with each move he make. I'll be able to post both answers tommorow if needed:)
I have a typed array with 4 elements and I'm trying to shuffle them. How would I go about it? I'm really close but I think the only problem is I don't know the syntax with dealing with Typed Array.
Here is the code so far:
int correctIndex=0;
for(int i=0; i<4; i++){
int randomShuffle = random.nextInt(4);
if(i==correctIndex){//keep track of the correct answer (which always starts at 0)
correctIndex=randomShuffle;
}
else if(randomShuffle==correctIndex){
correctIndex=i;
}
Drawable hold= questionAnswers.getDrawable(i);
questionAnswers.getDrawable(i)=questionAnswers.getDrawable(randomShuffle);
questionAnswers.getDrawable(randomShuffle)=hold;
}
The problem is only with the last two lines. That obviously doesn't work. Is there a
typedArray.setIndex(index,value)
kind of call?
I have an array with 5 size , and I want to assign value from random function if any index doesn't have it.
while(positionXtoStart==array1[0] || positionXtoStart==array1[1] ||
positionXtoStart==array1[2] || positionXtoStart==array1[3] ||
positionXtoStart==array1[4])
{
positionXtoStart = (rand1.nextInt(400) + 1)+30;
}
this solution is ok for small size of array but if i have array with size of 1000, I cant enter 1000 conditions in the while loop.
I tried For-loop with if-else condition in it but the
problem is, I want to check all array indexes at the same time.
Please try to understand what i am asking. I want to check all array index values at the same time (in one shot).
in For-loop, we can check only one value at a time.
If I understand correctly, you just need to loop through the array, checking each value.
for (int i = 0; i < array1.length; i++)
{
if (array1[i] == positionXtoStart)
{
positionXtoStart = (rand1.nextInt(400) + 1)+30;
break; // exit the loop
}
}
are you looking for something like this?
for(int i=0; i<array1.length; i++)
if(array[i] == whatever)
{
// do stuff
}
unfortunately, what you're asking is not possible. Even in your code:
while(positionXtoStart==array1[0] || positionXtoStart==array1[1] ||
positionXtoStart==array1[2] || positionXtoStart==array1[3] ||
positionXtoStart==array1[4])
the computer is checking one condition at a time. It's not doing all the conditions at once, like you may think it is. The code you posted is equivalent to the code #Supericy and #Samiam posted.
Unless there's a reason the forloops doesn't work for your case, I would say go with the answers that are posted here.
If you have to check each entry you have to go trough the whole array. An unordered array in not really suitable for searching trough it. Maybe you should think of changing your data structure into something like a BST so you have a guarantied O(logn) search.
To compare all elements in an unordered array you need linear time.
I have an ArrayList which holds Planes (enemies) on my android game. These planes move from one side of the screen to the other and the user has to dodge them. When a plane's x value becomes less than -50 it is removed from the ArrayList. When this happens, it causes all the planes on the screen currently to 'jump' slightly. They disappear for a few milliseconds and then are re-drawn but 2px behind where they are supposed to be.
Here is the paint method, where planes is the ArrayList
public void onDraw(){
bg1.onDraw(c);
bg2.onDraw(c);
chopper.onDraw(c);
score.onDraw(c);
// PAINTS THE PLANE OR DELETES IF OFF SCREEN
for (int i = 0; i < planes.size(); i++) {
Plane p = planes.get(i);
if(p.getX()<-50){
planes.remove(p);
}else{
p.onDraw(c);
if (p.getX() < 170) {
detectPlaneCollision(p, c);
}
}
}
}
Is there a way of fixing this? Should I use a different data structure?
Thanks
Tom
I think your problem is nothing to do with your choice of data structure, but instead because you are modifying your List while you're looping over it.
Imagine you have three planes in your list - [P1,P2,P3].
On the first iteration of your loop i is 0, you process P1
P1 has getX() < -50 so you remove it, making the list now [P2,P3]
On the next iteration of the loop i is now 1 so you process P3.
This means P2 never gets processed and so will never be drawn, making it disappear briefly.
Try using an Iterator which will allow you to safely remove items while looping over the List.
Iterator<Plane> i = planes.iterator();
while (i.hasNext()) {
Plane p = i.next();
if (p.getX() < -50) {
i.remove();
} else {
p.onDraw(c);
if (p.getX() < 170) {
detectPlaneCollision(p, c);
}
}
}
Although, since you don't care about the order in which you process your Plane obejcts you could consider storing them in a Set rather than a List. A Set doesn't have to worry about maintaining an order of items as you add and remove them.
If you do a lot of removing and adding from a list, consider using a LinkedList. An ArrayList is more suitable, if there's very little change in the dataset.
Although you must also consider the fact that getting elements from a LinkedList is somewhat slower than from an ArrayList, so keep that in mind when using a LinkedList.
I think there is a bug in that code.
What if i==0 and planes[0] gets removed?
planes[n] will move into position planes[n-1]. E.g. planes[1] will move into position planes[0].
Then i gets incremented, so i==1.
Therefore the original planes[1] (which is now planes[0]) will be skipped.
Disclaimer: This is for a homework assignment.
I am currently working on an assignment where I need to implement an iterable interface in order to pass each array from a square two-dimensional array. This array is supposed to represent a grid of numbers (so I will be referring to them as such [row][col]). My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible? Second, any suggestions/hints?
My next method currently looks like this:
public Data[] next(){
Data [] holder = new Data[ray.length];
for (int i = 0; i <ray.length; i++)
holder[i]=ray[counter][i];
counter++;
return holder;}
EDIT: I am aware of being able to switch counter and i in ray[counter][i], but I'm not sure how to have it do both if that's possible.
ray is the multidimensional array and count is an attribute of the Iterator method I've created (It's initialized to 0 and this is the only method that changes it). I know I cannot return the "column" of ray this way, so how would I go about having next call columns and rows?? Thanks for any of the help. I'll be standing by if you have further questions.
My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible?
Yes it is possible, assuming you mean what I think you mean. (The phrase "iterate through the rows and the columns" is horribly ambiguous.)
Since this is a homework exercise here are a couple of hints:
You need two counters not one.
When you get to the end of one row you need to go to the start of the next row. (Obviously!) Think about what that means if you've got two counters.
This should be enough to get you on the right track.
I want a row by row iteration and a column by column iteration.
This is also a horribly ambiguous description, but I'm going to interpret it as meaning that sometimes you want to iterate left to right and top to bottom, and other times you want to iterate top to bottom and left to right.
That is also possible:
One possibility is to use an extra state variable to tell the iterator which direction you are iterating; i.e. row within column, or column within row.
Another possibility is to implement two distinct Iterator classes for the two directions.
The problem is that the iterator class is only supposed to have one counter and returns an single-dimension array.
You've (finally) told us unambiguously that the iterator is supposed to return an array. (A good dentist could pull out a tooth quicker than that!)
So here's a hint:
Returning the ith row is easy, but returning the jth column requires you to create a new array to hold the values in that column.
My advice is: transform the 2d array to a list and iterate.
When initialize the Iterator, transform the list. Then you could iterate the list easily.
Following is p-code, you could enrich the implementation in your homework. Hope it helps you!
class TwoDimeIterator implements Iterator<Date> {
List transformedList = new ArrayList();
int cursor = 0;
/** transform to a list row by row.
So you could define your Iterator order.**/
TwoDimeIterator(){
for(int i=0; i < ray.length; i++)
for(int j=0; j < ray[0].length; j++)
transformedList.add(ray[i][j]);
}
public Date next() {
return transformedList.get(cursor++);
}
public boolean hasNext() {
return cursor != transformedList.size();
}
//...
}