Iterative Depth First Search To Find A String (2D Array) - java

I'm trying to create an iterative approach to a boggle game. The class contains fields for a 2d Array of Strings called "board" and has a 2d array of booleans called "haveVisit". The method that calls test 2 loops through the whole board, finding positions of the first character of the target string, then passes the coordinates into the test2 method, returning a list holding coordinates.
The return1Index method takes a 2D array coordinate at creates a int representative of the coordinates from a corresponding 1d array from it. The return2DIndex does the opposite and returns an int array holding the two coordinates.
public List<Integer> test2(int row1, int row2, String findMe){
String temp = findMe;
List<Integer> output = new ArrayList<Integer>();
if (board[row1][row2].charAt(0) != findMe.charAt(0))
return output;
haveVisit = new boolean[size][size];
int row = row1;
int column = row2;
output.add(return1DIndex(row, column));
haveVisit[row][column] = true;
//for each letter in the string
for(int j = 0; j < temp.length(); j++)
//for every column and row combination
for (int x = row - 1; x < row + 2 ; x++)
for (int y = column - 1; y < column + 2 ; y++)
//if index is valid and not visited
if (x > -1 && y > -1 && y < size && x < size && !haveVisit[x][y])
//if the output is the same size as string, return
if(output.size() == findMe.length())
return output;
//if the character in the board matches the char we're looking for
if(board[x][y].charAt(0) == temp.charAt(j))
{
haveVisit[x][y] = true;
output.add(return1DIndex(x, y));
//update row and column indices
row = x;
column = y;
}
}
}
return output;
}
For some reason this method works only 50% of the time. The method works fine with finding the letters when they're arranged left to right or top to bottom, but finding words from right to left or bottom to top never works except for one case: when you're searching for a string of length 1 or 2, where this method always works.
I have a working recursive solution but I wanted to try this way. Any thoughts as to why this wouldn't work?
Edit: Code now works from right to left, but still does not work when attempting to search upwards.

I don't know exactly what the problem is, but there are a few suspects:
You are updating row and column indices while checking their neighbors. This is like removing an element from an array while iterating through it: it's well defined, but has tricky semantics. I suggest either bailing out (greedy algorithm) or keeping a stack of matches (deeper search, requires saving stack of visited cells too).
The fors are missing opening braces, but the closing braces are there, suggesting missing code.
I'm not familiar with boggle, but isn't it possible for a letter to have two similar neighbors, like AXA? By just doing output.add(return1DIndex(x, y)); you may be outputting two ways to get the same letter. You may end up with output longer than findMe.
My suggestion is to follow a more standard format of depth-first search while you iron out the bugs. Wikipedia has a non-recursive pseudocode implementation, for example: https://en.wikipedia.org/wiki/Depth-first_search#Pseudocode .

Related

I don't understand what the multiplication in q.offer(x*m + y) does and what the while loop is doing and everything in the code

Can someone explain this code in detail, I don't understand what the multiplication in q.offer(x*m + y) does and what the while loop is doing. This is the requirements for the program:
Starting from a given location on the grid, experiment explores the grid, expanding and labeling all of the cells in a single colony originating from the starting location. Taking as input a grid, the coordinates of a starting location, and a label, experiment will either label that location and all its neighbors or do nothing, depending on the presence or absence of a cell at the given location, respectively; either way, experiment is required to return the size of the labeled colony.
(c) The program is responsible for ensuring that experiment is called start- ing at every location on the grid storing a 1. The reason is that experiment locates only a single colony.
For example, using the first grid above and calling experiment for the first time on the location at the top row and forth column will modify the grid only at the locations labeled A, leaving all the other locations intact.
Once every grid location storing a 1 has been colonized, the program freezes the grid by replacing the 0s on the grid with s (dashes) .
(d) The program is responsible for creating an initial grid of random number of rows and columns in the range [5-20], and for filling the grid randomly with 0s and 1s.
(e) The program is responsible for generating the labels for experiment to use during exploration. Use the alphabet letters A · · · Z and a · · · z as labels (in that order).
public static Map<Character, Integer> experiment(int n, int m, int x, int y, char[][] matrix, int[][] mark, char colony) {
Queue<Integer> q = new LinkedList<Integer>();
q.offer(x*m + y);
mark[x][y] = 1;
matrix[x][y] = colony;
while(!q.isEmpty()) {
int front = q.peek(); q.remove();
int x1 = front / m, y1 = front % m;
if(x1 != 0)
if(mark[x1-1][y1] == 0 && matrix[x1-1][y1] == '1') {
matrix[x1-1][y1] = colony;
mark[x1-1][y1] = 1;
q.offer((x1-1) * m + y1);
}
I just don't understand this part of code. Can someone please explain it.
one possible explanation could be that
x and y are coordinates of grid,
if you loop over x and y as below
for( int x = 0 ; x < width; x++ ){
for( int y = 0 ; y < height; y++ ){
index_of_one_dimensional_array = x*m+y;//where m = width(i.e number if columns in each row)
}
}
seems like the q.offer() functions somehow uses this concept to set a value depending on value of index_of_one_dimensional_array given by x*m+y;
and loop is used to make sure every cell in the grid is processed which happens when the queue is empty

Finding adjacent elements in a 2d array and counting them.

Im stumped on what to do for this part of my homework and could really use some help. I need to cycle through a given 2d array and find all similar elements that are adjacent to another and count that so for example
AA--B
AA--B
-AA--
----C
So the count would be 3 one for the As one for the Bs and one for the C, I just kinda need an idea where to start So far i have
public static int howManyOrganisms(char[][] image){
int count = 0;
for (int i = 0; i < image.length; i++) {
for (int j = 0; j < image[i].length; j++) {
if(image[i][j] != '-') {
count++;
}
System.out.println();
}
return howManyOrganisms(image, count);
}
}
I need help figuring out how to track the total number of elements that are within contact of one another (so left, right, down, up) being another similar element.
In each iteration, you can use your i,j variables to "navigate" the 2d plane and see if any interacting items are the same. In each iteration you would check the following indexes to see if they are the same:
image[i-1][j] (one row up)
image[i+1][j] (one row down)
image[i][j-1] (one left)
image[i][j+1] (one right)
Of course for all of these statements first you should check if +1/-1 is still within the size of your matrix, otherwise you will end up with out of bounds exception.

Ordering ArrayList of points to follow closest point LibGDX Java

I have an ArrayList of Vector2 (Vector2 is an object that contains an x and y coordinate) that contains a bunch of vertices that make a shape when drawn. However, the way they were put into the ArrayList are out of order. For example, the starting Vector2 point is index 0 but the closest next point is of index 4. My goal is to have another ArrayList of Vector2 that orders the Vector2's in a way so that the starting point is index 0, the next closest point is index 1, next is index 2, etc. Here is an image of what is happening.
The image shows what is happening but the green arrows show what I want to happen. The green point is the starting point.
So what I need is once the new ArrayList is created and ordered, it should look like this:
So here is the code in which I thought would do it:
public Array<Vector2> orderedVertices;
private void cleanVertices(Array<Vector2> originalVertices){
//This will be the Array containing ordered vertices
orderedVertices = new Array<Vector2>();
//Copy vertices of unsorted Array in a new Array
Array<Vector2> verticesOfImage = originalVertices;
//Add a random vertice to begin with (starting point)
orderedVertices.add(verticesOfImage.get(1));
//For breaking loop
int originalArraySize = originalVertices.size;
for(int i = 0; i < orderedVertices.size; i++){
//Index to be compared, meaning to find closest vertice around this vertice
int indexOfCompare = i;
//Get a distance for reference //Random point to check
double currentDistance = MathFactory.distance(orderedVertices.get(indexOfCompare), verticesOfImage.get(0));
//If we found a closest vertice, add to ordered pair and remove from original
// So we don't go backwards
if(getClosest(verticesOfImage, indexOfCompare, currentDistance) != -1){
orderedVertices.add(verticesOfImage.removeIndex(getClosest(verticesOfImage, indexOfCompare, currentDistance)));
}
//If not, then the original 'currentDistance' check was the closest vertice
else
orderedVertices.add(verticesOfImage.removeIndex(0));
//Stop checks, ordered pair fully populated
if(orderedVertices.size == originalArraySize)
break;
}
}
public int getClosest(Array<Vector2> vertices, int checkedIndex, double currentDistance){
//This is used to find the closest vertice, defaulted to -1 for condition statements
int correctIndex = -1;
for(int k = 0; k < vertices.size; k++){
//Make sure to not check same Vector2
if(vertices.get(k).x == orderedVertices.get(checkedIndex).x && vertices.get(k).y == orderedVertices.get(checkedIndex).y){
continue;
}
if(MathFactory.distance(orderedVertices.get(checkedIndex), vertices.get(k)) < currentDistance){
correctIndex = k;
currentDistance = MathFactory.distance(orderedVertices.get(checkedIndex), vertices.get(k));
}
}
return correctIndex;
}
This code comes very close to working, here is an image explaining what is going wrong.
I understand the one that isn't working doesn't look as smooth, but the only real problem is the fact that the lines freak out at the end and go through the body. I can't seem to figure out why this is happening or how to fix it. Any help at all with this is hugely appreciated! Thank you!

Checking symmetry in a grid with java

I need help with a game I'm doing:
The game is the following,
There are two players, 'B' and 'N'.
There is a grid of characters.
Both players take turn to place a char (B or N depending on who they are) on the grid.
Every time they place a char, I have to check whether there a symmetry is occuring. For example. There are differents types of symmetries. Horizontal and Vertical in every 2*2, 3*3 and 4*4 squares that contains the char that was just placed here. In the case of the 3*3 symmetry, the middle row or column does not take place in the symmetry.
I have done everything until now except the symmetries. I'm having some difficutly at doing them. I have an idea on how to do them but individually. Does any of you know how I could do the symmetries in one method only?
The java code for something similar to what you described for an n by n sized grid would go something like:
boolean isHorizontallySymmetrical(char[][] grid, int n){
int across = n / 2;
for(int i = 0; i < n; i++){
int right = 0
for(int left = 0; left < across; left++){
right = n - left - 1;
if(grid[i][left] != grid[i][right]){
return false;
}
}
}
return true;
}
A similar sort of thing would be needed for a vertical symmetry function.

Formula to draw pyramid of circles

I'm trying to create a pyramid of circles to my game, looking similar to this :
alt text http://img266.imageshack.us/img266/3094/lab1213c.jpg
But I can't make it print properly. Constantly I'm getting really strange spirals but nothing close to this. Can anyone give me some tip on proper formula ? My window is 600x600, base of pyramid is 8 .
fields = new Field[BASE*(BASE/2)+4];
int line_count = BASE;
int line_tmp = line_count;
for(int i=0; i< fields.length; i++){
for( int j=line_tmp; j <= line_count; j++){
fields[i] = new Field(0, (150+(line_tmp*5)),(600+line_tmp*5));
}
line_count--;
line_tmp = line_count;
}
The mistakes I see are:
Incorrect array size formula.
Including line_tmp (which seems to be your column counter) in your y expression.
Having two variables, line_count and line_temp that are always equal.
Having your outer loop count by node rather than counting by row.
Having generally meaningless variable names and magic numbers strewn about.
// I use java.util.ArrayList because using its add(..) method is convenient here.
// The proper forumula for anticipated number of nodes is: base×(base+1)÷2
final List<Field> fields = new ArrayList<Field>(BASE*(BASE+1)/2);
// I use a java.awt.Point to store the (x,y) value of the first node of the row.
// This clarifies the meaning, rather than using ints or long inline expressions.
final Point rowStart = new Point(PANEL_WIDTH/2, DIAMETER);
// The number of rows equals the number of nodes on the final row.
for (int row = 1; row <= BASE; row++) {
// The nth row has n nodes.
for (int circle = 0; circle < row; circle++) {
// Each row starts at rowStart and each subsequent circle is offset to
// the right by two times the circle diameter.
fields.add(new Field(0, rowStart.x + circle*DIAMETER*2, rowStart.y));
}
// Each subsequent row starts a little down and to the left of the previous.
rowStart.x -= DIAMETER;
rowStart.y += DIAMETER;
}
Remember to only use this as reference for fixing your own code if this is homework.

Categories

Resources