So I have been searching these two algorithms on the Internet and was able to, after days of working on it, get Dijkstra's Algorithm working. From what I have read the two Algorithms are not that different. So I am going to post what I did for Dijkstra's and I was hoping that you can show me or point me into the direction on how to modify it to the A* algorithm.
public Integer processGraph(int graph[][], int algorithm, int s, int d) {
if(algorithm == 1) {
// shortestDist[index] will hold the distance from s to the index
int shortestDist[] = new int[graph.length];
// added[i] is true if vertex index is included / the shortest distance from the source to the index is finalized
boolean added[] = new boolean[graph.length];
// establish all distances as Integer.Max_Value and added[] as false
for (int vertexIndex = 0; vertexIndex < graph.length; vertexIndex++) {
shortestDist[vertexIndex] = Integer.MAX_VALUE;
added[vertexIndex] = false;
}
// Distance of the source from itself is always 0
shortestDist[s] = 0;
// Parent array to store shortest the shortest path -- example: [num, num, num]
int[] parents = new int[graph.length];
// Find shortest path for all vertices
for (int i = 1; i < graph.length; i++) {
// Pick the minimum distance vertex
// from the set of vertices not yet
// processed. nearestVertex is
// always equal to the source in
// first iteration.
int u = minDistance(shortestDist, added);
added[u] = true;
for (int vertexIndex = 0; vertexIndex < graph.length; vertexIndex++) {
if (!added[vertexIndex] && graph[u][vertexIndex] != 0 && shortestDist[u] != Integer.MAX_VALUE && shortestDist[u] + graph[u][vertexIndex] < shortestDist[vertexIndex]) {
shortestDist[vertexIndex] = shortestDist[u] + graph[u][vertexIndex];
parents[vertexIndex] = u;
}
}
}
if(shortestDist[d] == Integer.MAX_VALUE) {
System.out.println(" ");
System.out.println("ERROR MESSAGE -- No path present from " + s + " to " + d);
System.out.println("ERROR MESSAGE --no path present from " + s + " to " + d);
System.out.println(" ");
return null;
}
//pathPrint(s, shortestDist, d); this only works for the first test
return shortestDist[d];
} // end algorithm 1
TO add more context to this, I have a driver class in which with several graphs upon which this finds the shortest path.
Example of graph[][]:
int regValid[][] = {{0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0}};
Again, how can I modify what I have to work with the A* algorithm instead of Dijkstras. Thank you and hopefully this makes sense.
You have full information about all nodes, edges and destination node, so Dijkstra is the best solution for your problem. A* would be useful if you hadn't known complete graph (most often for huge node space) and were forced to prioritize decisions according to some heuristics.
If you really want to simulate A* on your graph, you have to think out some artificial criterion (heuristics) which describes the estimated distance between given node and target node (in other words, pretend you don't know the path). Since your data set doesn't contain such additional information (and thinking out any satisfying admissibility condition is not trivial), your question doesn't make much sense to me.
Related
I'm new to Android and still following some tutorials. One tut is about TypedArray for storing the image information.
MainActivity.java
package com.example.materialme;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TypedArray sportsImageResources = getResources().obtainTypedArray(R.array.sports_images);
Log.d(TAG, "sportImageResources: " + sportsImageResources);
sportsImageResources.recycle();
}
}
strings.xml
<resources>
<array name="sports_images">
<item>#drawable/img_baseball</item>
<item>#drawable/img_badminton</item>
<item>#drawable/img_basketball</item>
<item>#drawable/img_bowling</item>
<item>#drawable/img_cycling</item>
<item>#drawable/img_golf</item>
<item>#drawable/img_running</item>
<item>#drawable/img_soccer</item>
<item>#drawable/img_swimming</item>
<item>#drawable/img_tabletennis</item>
<item>#drawable/img_tennis</item>
</array>
</resources>
When I see in logcat, the values of TypedArray sportsImageResources are
[3, 179, 6, 2131165272, 0, 0, 3, 178, 6, 2131165271, 0, 0, 3, 180, 6, 2131165273, 0, 0, 3, 181, 6, 2131165274, 0, 0, 3, 182, 6, 2131165275, 0, 0, 3, 183, 6, 2131165276, 0, 0, 3, 184, 6, 2131165277, 0, 0, 3, 185, 6, 2131165278, 0, 0, 3, 186, 6, 2131165279, 0, 0, 3, 187, 6, 2131165280, 0, 0, 3, 188, 6, 2131165281, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 17, 512, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 16, 250, 1, 0, 1073742848, 0, 16, 400, 1, 0, 1073742848, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 2131558747, 6, 2131558747, 1073742848, 0, 1, 2131558746, 6, 2131558746, 1073742848, 0, 28, -1, 1, 17170443, 1073742848, 0, 3, 193, 6, 2131165294, 1073742848, 0, 3, 27, 6, 0, 1073742848, 0, 18, -1, 6, 0, 1073742848, 0, 18, 0, 6, 0, 1073742848, 0, 18, 0, 6, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 1073742848, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 18, 0, 6, 0, 1073742848, 0]
How to read this data?
May be this example will help you.
TypedArray sportsimgs = getResources().obtainTypedArray(R.array.random_imgs);
// get resource ID by index
sportsimgs .getResourceId(i, -1)
// or set you ImageView's resource to the id
mImgView1.setImageResource(sportsimgs .getResourceId(i, -1));
// recycle the array
sportsimgs .recycle();
Essentially I am making a board game using sockets. Each client connected is stored in a map .
When the user makes a move to a coordinate in the 2D Array i.e. "move 2,3", it should put the connectionID in that position.
Currently my issue is, because I have a for loop; when i use the move command, the connection ID is replaced with the last value in the loop.
public void move(int x, int y) {
for (int value : gs.returnClients().values()) {
storeArray[x][y] = value;
}
}
i.e. If i have 2 clients connected: {62029=1, 62032=2} and my board
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Let's say I want to have client 1 move to 0, 3 it should be:
[[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
But instead I get:
[[0, 0, 0, 2, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
Since it's overwriting the last value of the map in the for loop.
How would I make it move dependent on its client "id" from the map?
Edit
In my server i have clients.put(socket.getPort(), connectionID); and methods to return the map and id. I have a class GameService that executes command which is
switch (request.type) {
case MOVE:
int clientID = Integer.parseInt(request.params[0]);
int getX = Integer.parseInt(request.params[1]);
int getY = Integer.parseInt(request.params[2]);
game.move(clientID,getX, getY);
return game.returnBoard();
In a file Request
String[] items = line.trim().split("\\s+");
switch (items[0].toUpperCase()) {
case "MOVE":
return new Request(RequestType.MOVE, items[1], items[2], items[3]);
As far as I understand your code, you need to do your move the following way:
public void move(int client, int x, int y) {
storeArray[x][y] = client;
}
where client is one (!) of the numbers within the gs.returnClients().values()-list. If you need to take it out of that map, you need to deliver the appropriate key for that, e.g.:
public void move(int clientId, int x, int y) {
storeArray[x][y] = gs.returnClients().get(clientId);
}
I am creating a map system for my game which requires me at a few stages to replace the old 2D array map with another. What I wanted to do is add all the 2D arraylist maps into a List of these 2D arraylists. However, what I found difficult was that when I wanted to retrieve said map, the .get method would not give me the correct data, as it you would try to pull the first item of that arraylist which in this case would be null. Thus the program threw me nullpointerexceptions.
private int[][] mapArray;
private List<int[][]> maps = new ArrayList<>();
mapArray = new int[][]{
{0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 9, 1, 1, 7, 7, 7, 7, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{7, 7, 7, 7, 5, 8, 8, 8, 4, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{4, 4, 4, 4, 4, 8, 8, 8, 4, 4, 6, 7, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{4, 4, 4, 4, 4, 8, 8, 8, 4, 4, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
maps.add(mapArray);
When I sout maps.get(0) I get the following:
[[I#58838f3f
If I have two items, it will show up like this:
[[[I#58838f3f, [[I#59a60155]
Ideally I want it to be added like this:
[I#58838f3f, I#58838f3f]
I am just unsure how to do this. Any help would be appreciated!
I might have overlooked something obvious, probably is the case!
Much obliged
You seem to be confusing the output of converting your map (or the list of maps) to string (which is what happens when you try to print them) - with what actual value there are there.
Because ArrayList like most Java container formats have nice toString() implementations that get automatically called when trying to print them, you'd get something that "looks like an array" in the output. So for example when printing an array list containing two strings, it might look like this: [a, b].
Arrays don't have such nice formatters, because they aren't really objects (they are "primitive types") and so print them gets you their address and some Java byte code that describes their type (if you can understand Java byte code), so an array of integers will look like this: [I#<address> while an two dimensional array of bytes will look like this: [[B#<address>, and so on.
In regards to your original question, the code seems to work well for me. Here is an example program:
import java.util.ArrayList;
public class Test2D {
public static void main(String... args) {
ArrayList<int[][]> maps = new ArrayList<>();
maps.add(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9},
});
maps.add(new int[][] {
{10,20,30},
{40,50,60},
});
int[][] map = maps.get(0);
System.out.println(map[0][0]);
}
}
The output will print correctly 1 , showing that there is no null pointer exception.
I have a string in the below format.
[[115, 1, 0123490, 63824005632, 0036760004, , 01, N, 78, , 7481067028,
122016, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, RXRELIEF CARD,
MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG], [115, 1, 0123490,
63824005632, 0038380001, ,
01, N, 78, , 7481067028, 122016, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA,
OH, 45805, EM, APEX AFFINITY DISCOUNT CARD, MUCINEX DM 20 0056-32 TAB SA
12HR 600-30MG]]
I want to store in collection with each
[115, 1, 0123490, 63824005632, 0038380001, , 01, N, 78, , 7481067028,
122016, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, APEX AFFINITY
DISCOUNT CARD, MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG]
[115, 1, 0123490, 63824005632, 0036760004, , 01, N, 78, , 7481067028,
122016, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, RXRELIEF CARD,
MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG]
How can I split or store in collection?
This should work as long the character ] does not appear as part of a value inside an entry:
public static void main(String[] args) {
String clob = "[[115, 1, 0123490, 63824005632, 0036760004, , 01, N, 78, , 7481067028, 122016, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, RXRELIEF CARD, MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG], [115, 1, 0123490, 63824005632, 0038380001, , 01, N, 78, , 7481067028, 122016, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, APEX AFFINITY DISCOUNT CARD, MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG]]";
List<String> entries = new ArrayList<>();
int start = 1;
while (true) {
start = clob.indexOf("[", start);
int end = clob.indexOf("]", start);
if (start != -1 && end != -1) {
entries.add(clob.substring(start, end + 1));
start = end + 1;
} else {
break;
}
}
}
If you know the escape sequence for characters inside your entries (e.g. \]) you have to check if the found end index represents that escape sequence and if, read again, starting from the end index.
There are many ways to do it. Here’s my suggestion:
public static List<List<String>> stringTo2DList(String input) {
if (input.equals("[]")) {
return Collections.emptyList();
}
if (! input.startsWith("[[")) {
throw new IllegalArgumentException("Not a list of lists");
}
if (! input.endsWith("]]")) {
throw new IllegalArgumentException("Not a list of lists");
}
List<List<String>> result = new ArrayList<>();
String[] innerLists = input.substring(2, input.length() - 2).split("\\], \\[");
for (String innerList : innerLists) {
// check for empty inner list
if (innerList.isEmpty()) {
result.add(Collections.emptyList());
} else {
result.add(Arrays.asList(innerList.split(", ")));
}
}
return result;
}
Should your string contain [], I am interpreting it as an empty list even though it might be a list of one element, the empty string. If you prefer the latter, just skip the check for the empty list in for loop.
I've been following a tutorial about creating a basic tile-based tower defense game in Java and have encountered a piece of code I cannot wrap my brain around and would like some help. (My main question is at the bottom after the code)
At this point we are iterating through a multidimensional array of 0's and 1's that we pass to a constructor which has a method that assigns a grass tile for 0's and stone tile for 1's and then another method to draw them to the screen creating our game screen. Simple enough, right?
Here is the class:
package data;
import static helpers.Artist.*;
public class TileGrid {
public Tile[][] map;
public TileGrid(int[][] newMap){
map = new Tile[20][15];
for(int i = 0; i < map.length; i++){
for(int j = 0; j <map[i].length; j++){
switch(newMap[j][i]){
case 0:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.GRASS);
break;
case 1:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.STONE);
break;
case 2:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.WATER);
break;
}
}
}
}
public void Draw(){
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[i].length; j++){
Tile t = map[i][j];
DrawQuadTex(t.getTexture(), t.getX(), t.getY(), t.getWidth(), t.getHeight());
}
}
}
}
And here is the array we are passing in:
int[][] map = { //20 tiles wide, 15 tiles high
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
};
So my main question has to do with the switch statement in the constructor for the TileGrid.
Why do the i and the j get switched newMap[j][i] when checking what it equals? I get that this code works, well, because it does and I understand nested for loops to iterate through a multidimensional array.
But why wouldn't newMap[i][j] work?
As well at the very beginning of that same constructor why do we create an array (of type Tile) with the dimension of map = new Tile[20][15] when we are passing in an array with the dimensions of map[15][20]?
I have tried to figure this out and study this on my own and will continue to do so until I understand it but any help would be soooo appreciated!
You are passing to the TileGrid constructor a 2D array of 15 rows and 20 columns, but inside the constructor you create a 2D array of 20 rows and 15 columns. That's why map[i][j] corresponds with newMap[j][i].
If the input int[][] map was also of 20 rows and 15 columns, you wouldn't have to switch the order of the indices inside the constructor.
This would give an index out of bounds error if it was really switched. However, there is a col variable in the second for loop that is not defined anywhere so it's hard to tell what's going on. This code will not compile.
If it is some code pulled off a a tutorial on some web page, I would just assume that it was a typo and continue on with that in mind. OR better yet, contact the author.