I've developed an android Travelling Salesman Problem (TSP) game application in which the user makes a path and plays against the computer, which uses the TSP algorithm to make a full path every time the user clicks to join two points with a line. Currently my method for the computer's path being draw is called whenever the user makes their move. However, my code is only allowing the first two points in the computer's path (stored in the arraylist called 'test') to be joined up.
public void CompDrawLine(List<Point> test) {
int d = 0;
int i;
test.add(test.get(0));
Point c = test.get(d);
for (i=0;i<test.size();i++)
{
cPath.moveTo(c.x,c.y);
c = test.get(d+1);
cPath.lineTo(c.x,c.y);
mCanvas.drawPath(cPath,cPaint);
// String testIndex = "this is iteration" + i;
// Toast.makeText(mContext, testIndex, LENGTH_SHORT).show();
}
cPath.reset();
}
How do I get the complete path drawn whenever the method is called??
I think your error is in the second line of your for loop. The variable d is never being incremented, so you are always using points 0 and 1. Personally, I would get rid of the d variable and just use i like this:
c = test.get(i+1);
However, another option would be to use d and increment it each time:
c = test.get(++d);
It must be a pre-increment though, or else you will be going from point 0 to point 0, and then point 1 to point 1, etc. instead of point 0 to 1, since d is initialized to 0.
Related
I am trying to find a way to get a bunch of points to connect via the ShapeRenderer`s method of line(Vector2 first, Vector2 second). So I will explain then show image and code to help.
There is a List of type Vector2 and I need to find the next closest vertice and then exclude the first point. Here is an image of what I mean. I labeled the iterations of the loop in the image.
1st iteration.) it finds the closest point.
2nd iteration.) it sees that the first point is closer but still chooses the third point. This is the core problem, I need to make sure the second point finds the third point even though the first point is the closer one.
Here is the code I have tried to do this.
private void cleanVertices(Array<Vector2> verts){
newVerts = new Array<Vector2>();
Vector2 tmpKey, tmpClose = null;
tmpKey = verts.get(0);
for(int i = 0; i < verts.size; i++){
for(int k = 0; k < (verts.size - 1); k++){
if(k == i)
continue;
//Distance formula
double dist = MathFactory.distance(verts.get(i), verts.get(k));
if(MathFactory.distance(verts.get(i), verts.get(k + 1)) < dist){
tmpClose = verts.get(k + 1);
}else
tmpClose = verts.get(i);
}
tmpKey = tmpClose;
newVerts.add(tmpClose);
}
}'
This does not accomplish what I need, instead, it seems to connect points closest on x-axis. I desperately need help with this. Thanks!
Make a deep copy of the input parameter verts (i.e. a new Array containing the same list of references in verts). Then iterate over that, but remove each point after you choose it as the next "nearest" neighbor.
I'm not familiar with the Array class, but an ArrayList would have the correct behavior when you remove an element. At each point only unvisited points would remain in the list.
since your problem is to find the closest vertex to the second vertex,which is the third in your case, without considering the first one. Make the second for loop starts from the position of the first for loop in every iteration ( k = i). Meaning that the second for loop will not consider the first vertex as point to calculate the distance from.
I'm really struggling to do this! z is an array of gravitational fields. To find the total gravitational field acting on a planet, say earth, I want to add all the entries together, while excluding the entry for earth's gravitational field, because earth's gravity doesn't act on earth itself.
For example, say z = [earthGrav, sunGrav, marsGrav, moonGrav]. Then the total field on earth is sunGrav+ marsGrav + moonGrav. I could maybe deal with this by using s=i+1. But that doesn't work subsequently, for the sun, when sunGrav = earthGrav+marsGrav+moonGrav, because the first entry would be left out!
for(int i=0; i<planets.length;i++){
for(int s=0;s<z.length;s++){
if(i!=s){
sum1.increaseBy(z[s]);
newP[i] = planets[i].updatePosition(position[i], velocity[i], timeStep, sum1);
}
else{
sum1.scale(1);
}
}
}
Problem is, the way I've done it above means whenever I add 1 to i, 1 also gets added to s, so s and i are always the same and the if statement never gets executed! Can anyone think of a way to do this?
I have to write a program for a Boggle-like game, and I currently have it check each letter below the current one to see if they make a word. So for a board like so:
W O Y R
F U M F
H T R V
I G S W
The only word it would find is "OUT" going from top to bottom. When it finds part of a word it puts that letter into a string and sets it to null so it won't use a letter twice in the same word (the full algorithm has to be able to search in multiple directions). I use a stack to keep track of the coordinates of the letters I've used so I can backtrack, and every time I pop the stack I take the last letter of the string and put it back into the board in its original position. But the issue is that if multiple letters are removed, it places them all in the same index, overwriting the previous one. So in the case of "OUT" the board ends up looking like this after replacing the three letters:
W null Y R
F null M F
H O R V
I G S W
I've gone through my code and tried rewriting it twice but it always does this. Do you have any insight as to why this is happening?
private void checkNeighbors(LetterCoor center){
String check = out;
while (!path.empty()){
if(center.getDirec()==0){//If the direction to check is down
System.out.println("Bottom");
if((center.getRow())+1<sideLength && board[(center.getRow())+1][center.getCol()]!=null){//makes sure the space below is !null and !out of bounds
check+=board[center.getRow()+1][center.getCol()];
System.out.println("Checking " + check);
if(isValidWord(check)){//checks if string is part of the lexicon
center.nextNeighbor();
board[center.getRow()+1][center.getCol()]=null;
center = new LetterCoor(center.getRow()+1, center.getCol(), 0);
System.out.println("push " + check.substring(check.length()-1));
path.push(center);
out=check;
}
else{
center=(LetterCoor) path.pop();
center.nextNeighbor();
path.push(center);
}
}//end of null if
else{
System.out.println("Null or end of board");
center=(LetterCoor) path.pop();
center.nextNeighbor();
path.push(center);
}
}//end of direc 0 if
else{
System.out.println("pop " + out.substring(out.length()-1,out.length()));
center=(LetterCoor) path.pop();
center.nextNeighbor();
board[center.getRow()][center.getCol()]=out.substring(out.length()-1,out.length());
out=out.substring(0,out.length()-1);
if (center.getDirec()<1){
path.push(center);
}
}
System.out.println("Current string is " + out);
}//end of while loop
}
If you need any clarification of my code please let me know.
Also, as clarification the LeterCoor object stores three ints. The first is the row index of the letter, the second is the column index and the third indicates which direction it is searching in (0=down, 1=down right, 2=right, etc)
I ended up coming across the solution on my own. The issue was with my LetterCoor object. Eclipse required the variables be set as static since I had the object class in a separate file, so when I updated the coordinate data in one LetterCoor object, it set the data for every LetterCoor object to that coordinate. I resolved this by moving the object class into the same file as this class and removing the static declaration from the variables.
i am using the import becker.robots file for this assignment!
I must create a class DistributeBot (extended RobotSE) which will put down a number of 'things' in the shape of 2 squares.
When the main method is then created, a single call to a method (which i must create myself using stepwise refinement and also contains a parameter) called this.putThings();
The method i am to create should have a single variable parameter to define the size of the squares! ie a parameter of (4) will make a 4x4 square of 'Things'.
The robot should set out the Things one line at a time from left to right! (once one line is displayed, it should move back to the LHS before displaying the next line)
I think i will be able to complete the scenario without problem whenever i am certain on how to create the method with the parameter i have specified.
Assumptions.
1. Starting position of the robot will always be the same. ie starting at 1, 1.
2. There will always be enough 'things' in the robots backpack to display the two squares.
Anyone have an idea how I would go about setting up this method initially with the variable parameter?
If you have your method starting
Public void MakeSquare(int size)
{
for(int i = 0; i < size; i++)
{
for(int x = 0; x < size; x++)
{
//drop thing
//move right
}
for(int y = 0; y < size; y++)
{
//move left
}
//move up
}
}
Whilst reading the question you should try and break it down into its simplest parts.
start with Build a square that is the most abstract form of the scenario and so makes your method, then break it down
//I want to move up until I hit size limit
for each number in "the size you want"
//I want to move right and drop a thing, until I hit size limit
for each number in "the size you want"
drop a thing
move one right
endloop
//I want to move back to the LHS until I hit size limit
for each number in "the size you want"
move one left
endloop
//then make the move up
move up
endlood
If you make this method and call it twice you will make the 2 squares as required)
I have a problem on a program I'm making that I honestly can't find a solution for. It seems the objects contained on a Java ArrayList collection are being modified without me programming such modifications.
The program as a whole is meant to basically create a random connection between two nodes on a 10x10 grid by moving through a path. This path is represented as an ArrayList collection of points in the grid, with the first index containing the first node's location (node A) and the last index containing the second node's location (node B). How I do this is by locating myself on A's location, and then moving randomly to contiguous points in the grid, repeating this in a while loop until B's location is reached.
Everything seems to work except that the "path" collection is altered somehow, such that every point in it ends up being the same as the last point to which I move, which is also B's location.
The method is as follows:
public void generateRandomPath()
{
path = new ArrayList<Point>();
path.add(pInitial);
complete = false;
while(!complete)
{
k = path.get(path.size()-1);
d = selectDirection(k);
GUI.log.append("==== Before the method. ==== \n");
GUI.log.append(Integer.toString(path.get(path.size()-1).getX())+" - "+Integer.toString(path.get(path.size()-1).getY())+"\n");
x = move(k, d);
path.add(x);
if(k.getX() == pEnd.getX() && k.getY() == pEnd.getY())
complete = true;
}
GUI.log.append("Finished. \n");
}
"Point" are simply points, with an X
and Y coordinate represented by
integers.
"pInitial" is the point representing the location of node A.
"pEnd" is the point representing the location of node B.
"d" is the direction on which I'm going to move on this repetition. This can be either up, right, down, or left represented by an integer 1, 2, 3, and 4 respectively.
"k" is the last point in the path, which is the point to which it moved on the previous repetition.
"x" is the new point to which it moved on the current repetition.
So what it basically does is it grabs the last point in the path as reference, chooses a direction, and then moves to the point contiguous on that direction. Each repetition of the while loop should add a new point to path. However what ends up happening is that not only is this new point added, but every other point already in path takes the value of this last point added. By utilizing the log entries show above (GUI.log.append) I managed to see that path is being mysteriously altered inside the step:
x = move(k, d);
Which is the following method:
private Point move(Point n, int y)
{
GUI.log.append("==== Inside the method. ==== \n");
GUI.log.append(Integer.toString(path.get(path.size()-1).getX())+" - "+Integer.toString(path.get(path.size()-1).getY())+"\n");
Point newP = n;
if(y == 1)
newP.setY(n.getY()-1);
if(y == 2)
newP.setX(n.getX()+1);
if(y == 3)
newP.setY(n.getY()+1);
if(y == 4)
newP.setX(n.getX()-1);
GUI.log.append("==== After method. ==== \n");
GUI.log.append(Integer.toString(path.get(path.size()-1).getX())+" - "+Integer.toString(path.get(path.size()-1).getY())+"\n");
return newP;
}
Integer y is the direction as mentioned before. As you can see this method does not alter path in any way, yet the logs show it does. In this example node A was on the point X = 2, Y = 3. The log shows what the coordinates of the last point in path are. As you can see, the coordinates of the last point in path take on the value of the coordinates of the new point, but this new point was not yet added to path.
I honestly don't know how this is happening. If anyone could think of a reason I would appreciate it very much if you could tell me.
Try
Point newP = new Point(n.getX(), n.getY());
instead of
Point newP = n;