Maze genorator skips spots? - java

My code(Shown Below) is doing what it's supposed to do (generate a passageway from point a to b with random stops in between) and It works. Well, not all of the time. I have tried to research for syntax problems, and spent hours on end looking for some simple math problem, but I can't find it.
The Probolem is that it generates a valid path most of the time, but ocationaly, it is 3 spots off from the first point to the second. Does anyone see what the issue is?
public static int[][] genLayer(int enterX, int enterY) {
// Initiate Variables and arrays
ArrayList<Integer> xPos = new ArrayList<Integer>(); // Array of x
// positions
ArrayList<Integer> yPos = new ArrayList<Integer>(); // Array of y
// positions
int[][] layer = new int[20][20]; // The 2D array of the layer to be
// returned to the caller
// Generates the points for the passageway to go thru.
int point1X = rand.nextInt(20); // The first point's x
int point1Y = rand.nextInt(20); // The first point's y
int point2X = rand.nextInt(20); // The second point's x
int point2Y = rand.nextInt(20); // The second point's y
int point3X = rand.nextInt(20); // The third point's x
int point3Y = rand.nextInt(20); // The third point's y
layer[enterX][enterY] = 4; // Set the cords of enter X and Y to 4, the
// number representing the up stairs
// Enter To Point 1:
// Generate the first set of x points for the layer's passages
if (enterX > point1X) {
for (int x = enterX - 1; x > point1X; x--) {
xPos.add(x);
}
} else if (enterX < point1X) {
for (int x = enterX + 1; x < point1X; x++) {
xPos.add(x);
}
}
// Generate the first set of y points for the layer's passages
if (enterY > point1Y) {
for (int y = enterY - 1; y > point1Y; y--) {
yPos.add(y);
}
} else if (enterY < point1Y) {
for (int y = enterY + 1; y < point1Y; y++) {
yPos.add(y);
}
}
// Make Passages
if (yPos.size() > 0) {
if (rand.nextBoolean() & xPos.size() > 0) { // Chose randomly
// whether to
// make the passage up
// then
// sideways or sideways
// then
// up.
//
// Then, decide if there
// is
// any horizontal or
// vertical passages to
// generate
// x then y
for (int i = 0; i < xPos.size(); i++) {
layer[xPos.get(i)][enterY] = 1; // make the horizontal
// passage
}
for (int i = 0; i < yPos.size(); i++) {
layer[xPos.get(xPos.size() - 1)][yPos.get(i)] = 1; // make
// the
// vertical
// passage
}
} else {
// y then x
for (int i = 0; i < yPos.size(); i++) {
layer[enterX][yPos.get(i)] = 1; // make the vertical passage
}
for (int i = 0; i < xPos.size(); i++) {
layer[xPos.get(i)][yPos.get(yPos.size() - 1)] = 1; // make
// the
// horizontal
// passage
}
}
}
// Set point 1 to the last xPos and yPos to make up for unknown
// calculation errors
if (xPos.size() > 0)
point1X = xPos.get(xPos.size() - 1);
if (yPos.size() > 0)
point1Y = yPos.get(yPos.size() - 1);
// Flush the values of xPos and yPos
xPos.clear();
yPos.clear();
// Point 1 To Point 2:
// Generate the second set of x points for the layer's passages
if (point1X > point2X) {
for (int x = point1X - 1; x > point2X; x--) {
xPos.add(x);
}
} else if (point1X < point2X) {
for (int x = point1X + 1; x < point2X; x++) {
xPos.add(x);
}
}
// Generate the second set of y points for the layer's passages
if (point1Y > point2Y) {
for (int y = point1Y - 1; y > point2Y; y--) {
yPos.add(y);
}
} else if (point1Y < point2Y) {
for (int y = point1Y + 1; y < point2Y; y++) {
yPos.add(y);
}
}
// Make Passages
if (yPos.size() > 0) {
if (rand.nextBoolean() & xPos.size() > 0) { // Chose randomly
// whether to
// make the passage up
// then
// sideways or sideways
// then
// up.
//
// Then, decide if there
// is
// any horizontal or
// vertical passages to
// generate
// x then y
for (int i = 0; i < xPos.size(); i++) {
layer[xPos.get(i)][point1Y] = 1; // make the horizontal
// passage
}
for (int i = 0; i < yPos.size(); i++) {
layer[xPos.get(xPos.size() - 1)][yPos.get(i)] = 1; // make
// the
// vertical
// passage
}
} else {
// y then x
for (int i = 0; i < yPos.size(); i++) {
layer[point1X][yPos.get(i)] = 1; // make the vertical
// passage
}
for (int i = 0; i < xPos.size(); i++) {
layer[xPos.get(i)][yPos.get(yPos.size() - 1)] = 1; // make
// the
// horizontal
// passage
}
}
}
// Set point 2 to the last xPos and yPos to make up for unknown
// calculation errors
if (xPos.size() > 0)
point2X = xPos.get(xPos.size() - 1);
if (yPos.size() > 0)
point2Y = yPos.get(yPos.size() - 1);
// Flush the values of xPos and yPos
xPos.clear();
yPos.clear();
// Point 2 To Point 3:
// Generate the third set of x points for the layer's passages
if (point2X > point3X) {
for (int x = point2X - 1; x > point3X; x--) {
xPos.add(x);
}
} else if (point2X < point3X) {
for (int x = point2X + 1; x < point3X; x++) {
xPos.add(x);
}
}
// Generate the third set of y points for the layer's passages
if (point2Y > point3Y) {
for (int y = point2Y - 1; y > point3Y; y--) {
yPos.add(y);
}
} else if (point2Y < point3Y) {
for (int y = point2Y + 1; y < point3Y; y++) {
yPos.add(y);
}
}
// Make Passages
if (yPos.size() > 0) {
if (rand.nextBoolean() & xPos.size() > 0) { // Chose randomly
// whether to
// make the passage up
// then
// sideways or sideways
// then
// up.
//
// Then, decide if there
// is
// any horizontal or
// vertical passages to
// generate
// x then y
for (int i = 0; i < xPos.size(); i++) {
layer[xPos.get(i)][point2Y] = 1; // make the horizontal
// passage
}
for (int i = 0; i < yPos.size(); i++) {
layer[xPos.get(xPos.size() - 1)][yPos.get(i)] = 1; // make
// the
// vertical
// passage
}
} else {
// y then x
for (int i = 0; i < yPos.size(); i++) {
layer[point2X][yPos.get(i)] = 1; // make the vertical
// passage
}
for (int i = 0; i < xPos.size(); i++) {
layer[xPos.get(i)][yPos.get(yPos.size() - 1)] = 1; // make
// the
// horizontal
// passage
}
}
}
// Set point 3 to the last xPos and yPos to make up for unknown
// calculation errors
if (xPos.size() > 0)
point3X = xPos.get(xPos.size() - 1);
if (yPos.size() > 0)
point3Y = yPos.get(yPos.size() - 1);
// Flush the values of xPos and yPos
xPos.clear();
yPos.clear();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
System.out.print(" " + layer[i][j]);
}
System.out.println();
}
return layer;
}
Note: I know this code can be much, much smaller with methods, but this is just a rough test of it's capabilities. I will be working on that later.
Thanks in advance!

One mistake I notice is in the "Make Passages" sections. Each one is wrapped in an
if(yPos.size() > 0)
conditional, but doesn't consider the case of when xPos.size() is greater than zero. Basically, if there's no change in Y, but there is a change in X, then it will just skip creating that section of passage.
Example:
p2 p3
p1
results in
1 1 1 1
0 0 0 0
4 0 0 0
Next bug:
If one of the variables is only off by one, then the size of the list of points it generates will be 0, so it will not connect the two. For example enterX equals to 10 and point1X equal to 9 will not connect them.
p3
p2
p1
results in
1 0
1 0
0 0
0 4
To fix this, I'd suggest changing all of the loops of the form
for (int x = enterX - 1; x > point1X; x--)
to
for (int x = enterX - 1; x >= point1X; x--)
In other words, including the final point in the list.

The paths you generate aren't going the entire distance between your sets of two points. Since you stop generating your path at pX - 1 and pY - 1 (in the case of positive direction traversal, and pX + 1 and pY + 1 during negative direction traversal), you get this sort of design:
0 0 0 P2
1 1 1 0
1 0 0 0
P1 0 0 0
Notice that the path doesn't actually reach P2. Try changing these sections and those like it to
// Generate the first set of x points for the layer's passages
if (enterX > point1X) {
for (int x = enterX - 1; x >= point1X; x--) { // > becomes >=
xPos.add(x);
}
} else if (enterX < point1X) {
for (int x = enterX + 1; x <= point1X; x++) { // < becomes <=
xPos.add(x);
}
}
so that the entire distance between the points is always traversed.

Related

How Do I Identify The Edge Case That Is Failing My Code?

I'm working on a coding question and I'm given an array for example something like this: [1, 7, 3, 21, 13, 19]
I'm suppose to pair up items in the array. Then after that I'm suppose to apply this simple rule.
Say I choose a pair x and y:
Rule:
if x > y : y = 2*y and x = x - y
if y > x : x = 2*x and y = y - x
if x == y : break # x and y is a pair that does not cause an infinite loop
Example:
Say x = 7 and y = 3
1st round : x = 7 and y = 3
2nd round : x = 4 and y = 6
3rd round : x = 8 and y = 2
4th round : x = 6 and y = 4
at this point you know that this pair will loop forever
If for example x = 1 and y = 3
1st round : x = 1 and y = 3
2nd round : x = 2 and y = 2
At this point you know that this pair doesn't loop
So in order to solve this problem. I saw it as some kind of TSP but instead of minimizing path, I'm maximizing path.
So first step I did is create a graph of nodes and label whether a pair is a loop or not
In this array the graph generated (adjacency matrix) is this:
0 0 0 1 1 1
0 0 1 0 1 1
0 1 0 0 0 1
1 0 0 0 1 1
1 1 0 1 0 0
1 1 1 1 0 0
the index in the graph represent index in the array. For example let's say that i is row and j is column. If you look at i=0, j=2 that represents array[i] = x, array[j] = y which is array[0] = x = 1, array[2] = y = 3. From the above example we know that that is not a loop. Therefore there is a 0 weight on that index.
Then I do a nearest neighbor TSP algorithm (modified to be max route) in order to get the max pair that maximized the amount of loop pairs. This method passes the coding test cases except for one. I can't identify an array of integers that would fail my code. And the test cases on the coding challenge does not give me any info on what test it is failing on.
Here is my code:
import java.util.HashMap;
public class DistractTheGuards {
private static boolean IsPairLoop(int first, int second)
{
long result = first + second;
boolean success = true;
while ((result & 1) == 0)
{
if (first == second)
{
success = false;
break;
}
else if (first > second)
{
first = (first - second) / 2;
}
else
{
second = (second - first) / 2;
}
result = first + second;
}
return success;
}
public static void GenWeights(int[][] graph, int[] banana_list)
{
for (int i = 0; i < graph.length; ++i)
{
for (int j = 0; j < graph.length; ++j)
{
if (IsPairLoop(banana_list[i], banana_list[j]))
{
graph[i][j] = 1;
}
else
{
graph[i][j] = 0;
}
}
}
}
private static boolean AreAllNodesVisited(boolean[] visited)
{
boolean all_visited = true;
for (int i = 0; i < visited.length; ++i)
{
all_visited &= visited[i];
if (!all_visited)
break;
}
return all_visited;
}
private static int FindMaxTourKey(HashMap<Integer, int[]> tours)
{
int cur_max_r = -1;
for (Integer rank : tours.keySet())
{
if (cur_max_r < rank)
cur_max_r = rank;
}
return cur_max_r;
}
private static int GetN(int[][] graph, int[] max_tour, int n)
{
for (int i = 0; i < max_tour.length; i += 2)
{
if (i + 1 >= max_tour.length)
break;
if (graph[max_tour[i]][max_tour[i+1]] == 0)
{
n -= 2;
}
}
return n;
}
public static int answer(int[] banana_list)
{
int n = banana_list.length;
if (n < 1)
return 0;
if (n == 1)
return 1;
int[][] graph = new int[n][n];
GenWeights(graph, banana_list);
HashMap<Integer, int[]> tours = new HashMap<>();
for (int i = 0; i < n; ++i)
{
int[] cur_tour = new int[n];
boolean[] visited = new boolean[n];
int start_node = i;
int cur_tour_i = 0;
while (!AreAllNodesVisited(visited))
{
int s_n = start_node;
visited[start_node] = true;
cur_tour[cur_tour_i++] = start_node;
int cur_max = 0;
for (int j = 0; j < n; ++j)
{
if (!visited[j])
{
if (cur_max < graph[start_node][j])
{
cur_max = graph[start_node][j];
start_node = j;
break;
}
}
}
if (s_n == start_node)
{
for (int x = n - 1; x >= 0; --x)
{
if (!visited[x])
{
start_node = x;
break;
}
}
}
}
int cur_tour_r = 0;
for (int x = 0; x < n; x += 2)
{
if (x + 1 >= n)
break;
cur_tour_r += graph[cur_tour[x]][cur_tour[x+1]];
}
tours.put(cur_tour_r, cur_tour.clone());
if (cur_tour_r == n - 1)
break;
}
int cur_max_r = FindMaxTourKey(tours);
if (tours.size() == 0)
return 0;
int[] max_tour = tours.get(cur_max_r);
return GetN(graph, max_tour, n);
}
}
I just need help identifying an edge case that would fail my method. Can anyone help me or give me an array that would certainly fail my method? I can take it from there. Thanks
Update
Constraints
1 <= integers <= 2^30
1 <= len(array) <= 100

Growing Tree Algorithm in java not working seamless

I'm trying to create a dungeon generator. First, I place the rooms randomly, then I grow a maze in the empty space between them. But I got a problem, everytime I run my maze algorithm, it creates sometimes strange unreachable corridors:
Take a look at the red squares there. These corridors are unreachable for the player. How to avoid them? Here's some code:
public void createMaze(byte[][] dungeon) {
for (int y = 1; y < dungeon.length; y += 2) {
for (int x = 1; x < dungeon[0].length; x += 2) {
Vector2 pos = new Vector2(x, y);
if (dungeon[y][x] != 2 && dungeon[y][x] != 1){
growMaze(pos, dungeon);
}
}
}
}
public void growMaze(Vector2 pos, byte[][] dungeon) {
// Initialize some Lists and Vars
int lastDir = 0;
ArrayList<Vector2> cells = new ArrayList<Vector2>();
// Adding the startPosition to the cell list.
cells.add(pos);
// When the position is in the Grid
if(pos.y < dungeon.length - 2 && pos.y > 0 + 2 && pos.x < dungeon[0].length - 2 && pos.x > 0 + 2){
// And no walls or floors are around it
if(isPlaceAble(dungeon , pos)){
// Then place a corridor tile
dungeon[(int) pos.y][(int) pos.x] = 4;
}
}
// Here comes the algorithm.
while(!cells.isEmpty()){
// choose the latest cell
Vector2 choosedCell = cells.get(cells.size() - 1);
// Check again if the cell is in the grid.
if(choosedCell.y < dungeon.length - 2 && choosedCell.y > 0 + 2 && choosedCell.x < dungeon[0].length - 2 && choosedCell.x > 0 + 2){
// When that's true, then check in which directions the cell is able to move
boolean canGoNorth = dungeon[(int) (choosedCell.y + 1)][(int) choosedCell.x] == 0 && dungeon[(int) (choosedCell.y + 2)][(int) choosedCell.x] == 0;
boolean canGoSouth = dungeon[(int) (choosedCell.y - 1)][(int) choosedCell.x] == 0 && dungeon[(int) (choosedCell.y - 2)][(int) choosedCell.x] == 0;
boolean canGoEast = dungeon[(int) (choosedCell.y)][(int) choosedCell.x + 1] == 0 && dungeon[(int) (choosedCell.y)][(int) choosedCell.x + 2] == 0;
boolean canGoWest = dungeon[(int) (choosedCell.y)][(int) choosedCell.x - 1] == 0 && dungeon[(int) (choosedCell.y)][(int) choosedCell.x - 2] == 0;
// When there's no available direction, then remove the cell and break the loop...
if(!canGoNorth && !canGoSouth && !canGoEast && !canGoWest ){
cells.remove(cells.size() - 1);
break;
}
else{
// But if there's a available direction, then remove the cell from the list.
Vector2 savedCell = cells.get(cells.size() - 1);
cells.remove(cells.get(cells.size() - 1));
boolean placed = false;
// And place a new one into a new direction. This will happen as long as one is placed.
while(!placed){
// pick a random direction
int randomDirection = MathUtils.random(0,3);
int rdm = randomDirection;
// Init the length of the cells.
int length = 2;
// And now begin, if the direction and the random number fits, then dig the corridor. If no direction/number fits, then redo this until it works.
if(canGoNorth && rdm == 0 ){
int ycoord = 0;
for(int y = (int) choosedCell.y; y < choosedCell.y + length; y++){
dungeon[(int) y][(int) choosedCell.x] = 4;
}
Vector2 newCell = new Vector2(choosedCell.x, choosedCell.y + length);
cells.add(newCell);
lastDir = 0;
placed = true;
}
if(canGoSouth && rdm == 1 ){
int ycoord = 0;
for(int y = (int) choosedCell.y; y > choosedCell.y - length; y--){
dungeon[(int) y][(int) choosedCell.x] = 4;
}
Vector2 newCell = new Vector2(choosedCell.x, choosedCell.y - length);
cells.add(newCell);
lastDir = 1;
placed = true;
}
if(canGoEast && rdm == 2 ){
int xcoord = 0;
for(int x = (int) choosedCell.x; x < choosedCell.x + length; x++){
dungeon[(int) choosedCell.y][x] = 4;
}
Vector2 newCell = new Vector2(choosedCell.x + length, choosedCell.y );
cells.add(newCell);
lastDir = 2;
placed = true;
}
if(canGoWest && rdm == 3 ){
int xcoord = 0;
for(int x = (int) choosedCell.x; x > choosedCell.x - length; x--){
dungeon[(int) choosedCell.y][x] = 4;
}
Vector2 newCell = new Vector2(choosedCell.x - length, choosedCell.y );
cells.add(newCell);
lastDir = 3;
placed = true;
}
}
}
}
else{
cells.remove(cells.size() - 1);
}
}
// And finally delete dead end cells :) (Those who only got 3 Wall/Floor neighbours or 4)
killDeadEnds(dungeon);
}
So how to avoid these unreachable mazes?
You can use a union-find structure to quickly find and remove all the cells that aren't connected to rooms. See: https://en.wikipedia.org/wiki/Disjoint-set_data_structure
You initially create a disjoint set for each corridor or room cell, and then union every pair of sets for adjacent rooms or cells. Finally, delete all the corridor cells that aren't in the same set as a room.
Union-find is also the basis for a nice maze generation algorithm, which is just Kruskal's algorithm for finding spanning trees in a graph ( https://en.wikipedia.org/wiki/Kruskal%27s_algorithm ) applied to a grid. See: http://weblog.jamisbuck.org/2011/1/3/maze-generation-kruskal-s-algorithm
You could use this algorithm to generate your maze in the first place, before applying your dead end removal. It would change the character of your maze, though, so maybe you don't want to.

My recursive function for finding the number of paths in a grid runs infinitely

I'm working on a couple of Project Euler problems and want to test my solution. My recursive function never ends even with reachable base cases.
in a 20x20 grid I am using x and y coordinates to navigate up and left to find the number of paths from (19,19) to (0,0). My base case is to return 1 when we reach (0,0). Otherwise I add the current count to the recursive call.
Function:
private static int numPaths(int x, int y, int pathsFound)
{
if(x == 0 && y == 0)
return 1;
else
{
if(x > 0)
{
pathsFound += numPaths(x - 1, y, pathsFound);
}
if(y > 0)
{
pathsFound += numPaths(x, y - 1, pathsFound);
}
}
return pathsFound;
}
Main:
int x = 19;
int y = 19;
System.out.println("Answer: " + numPaths(x, y, 0));
Is there a flaw in my recursive logic, or is just taking a very long time to compute? If you know the solution to this Euler problem, please do not post it.
https://projecteuler.net/problem=15
So if anyone is interested, I looked into memoization and came up with an elegant solution without recursion.
Function:
private static BigInteger numberPaths(ArrayList<ArrayList<BigInteger>> grid)
{
for(int i = 0; i <= 20; ++i)
{
for(int j = 0; j <= 20; ++j)
{
int x = j;
int y = i;
if(x - 1 < 0 || y - 1 < 0)
{
grid.get(x).set(y, BigInteger.ONE);
}
else
{
BigInteger topVal = grid.get(x - 1).get(y);
BigInteger leftVal = grid.get(x).get(y - 1);
grid.get(x).set(y, topVal.add(leftVal));
}
}
}
return grid.get(20).get(20); //the solution
}
Main:
ArrayList<ArrayList<BigInteger>> grid = new ArrayList<>();
for(int i = 0; i <= 20; ++i)
{
ArrayList<BigInteger> column = new ArrayList<>();
for(int j = 0; j <= 20; ++j)
{
column.add(BigInteger.valueOf(0));
}
grid.add(column);
}
System.out.println("Answer: " + numberPaths(grid));

Searching a word in a given string array

You are given a 2D array as a string and a word via keyboard. The word
can be in any way (all 8 neighbors to be considered) but you can’t use
same character twice while matching. Return word's first and last
character's index as (x,y). If match is not found return -1.
That's the question. I'm having trouble with searching. I tried that:
int x=0,y=0;
for(int f=0; f<WordinArray.length; f++){
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
if(matrix[i][j].equals(WordinArray[f])){
x=i; y=j;
System.out.print("("+x+","+y+")");
}
}
}
}
But, That code is not working as it is supposed to. How else I can write this searching code?
Referring to Sixie's code
Assuming this is a valid input/output to your program?
Size:
4x4
Matrix:
a b c d
e f g h
i j k l
m n o p
Word: afkp
(0,0)(3,3)
I edited your code, so that it should work for input on this form (it is case sensitive at the moment, but can easily be changed by setting .toLowerCase()
Scanner k = new Scanner(System.in);
System.out.println("Size: ");
String s = k.nextLine();
s.toUpperCase();
int Xindex = s.indexOf('x');
int x = Integer.parseInt(s.substring(0, Xindex));
int y = Integer.parseInt(s.substring(Xindex + 1));
System.out.println("Matrix:");
char[][] matrix = new char[x][y];
for (int i = 0; i < x; i++) {
for (int p = 0; p < y; p++) {
matrix[i][p] = k.next().charAt(0);
}
}
System.out.print("Word: ");
String word = k.next();
int xStart = -1, yStart = -1;
int xEnd = -1, yEnd = -1;
// looping through the matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
// when a match is found at the first character of the word
if (matrix[i][j] == word.charAt(0)) {
int tempxStart = i;
int tempyStart = j;
// calculating all the 8 normals in the x and y direction
// (the 8 different directions from each cell)
for (int normalX = -1; normalX <= 1; normalX++) {
for (int normalY = -1; normalY <= 1; normalY++) {
// go in the given direction for the whole length of
// the word
for (int wordPosition = 0; wordPosition < word
.length(); wordPosition++) {
// calculate the new (x,y)-position in the
// matrix
int xPosition = i + normalX * wordPosition;
int yPosition = j + normalY * wordPosition;
// if the (x,y)-pos is inside the matrix and the
// (x,y)-vector normal is not (0,0) since we
// dont want to check the same cell over again
if (xPosition >= 0 && xPosition < x
&& yPosition >= 0 && yPosition < y
&& (normalX != 0 || normalY != 0)) {
// if the character in the word is not equal
// to the (x,y)-cell break out of the loop
if (matrix[xPosition][yPosition] != word
.charAt(wordPosition))
break;
// if the last character in the word is
// equivalent to the (x,y)-cell we have
// found a full word-match.
else if (matrix[xPosition][yPosition] == word
.charAt(wordPosition)
&& wordPosition == word.length() - 1) {
xStart = tempxStart;
yStart = tempyStart;
xEnd = xPosition;
yEnd = yPosition;
}
} else
break;
}
}
}
}
}
}
System.out.println("(" + xStart + "," + yStart + ")(" + xEnd + ","
+ yEnd + ")");
k.close();
I think you need to plan your algorithm a bit more carefully before you start writing code. If I were doing it, my algorithm might look something like this.
(1) Iterate through the array, looking for the first character of the word.
(2) Each time I find the first character, check out all 8 neighbours, to see if any is the second character.
(3) Each time I find the second character as a neighbour of the first, iterate along the characters in the array, moving in the correct direction, and checking each character against the word.
(4) If I have matched the entire word, then print out the place where I found the match and stop.
(5) If I have reached the edge of the grid, or found a character that doesn't match, then continue with the next iteration of loop (2).
Once you have your algorithm nailed down, think about how to convert each step to code.
If I understood your question right. This is a quick answer I made now.
int H = matrix.length;
int W = matrix[0].length;
int xStart = -1, yStart = -1;
int xEnd = -1, yEnd = -1;
String word = "WordLookingFor".toLowerCase();
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
if (matrix[i][j] == word.charAt(0)) {
int tempxStart = i;
int tempyStart = j;
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int k = 0; k < word.length(); k++) {
int xx = i+x*k;
int yy = j+y*k;
if(xx >= 0 && xx < H && yy >= 0 && yy < W && (x != 0 || y != 0)) {
if(matrix[xx][yy] != word.charAt(k))
break;
else if (matrix[xx][yy] == word.charAt(k) && k == word.length()-1) {
xStart = tempxStart;
yStart = tempyStart;
xEnd = xx;
yEnd = yy;
}
} else
break;
}
}
}
}
}
}
A little trick I used for checking all the 8 neighbors is to use two for-loops to create all the directions to go in:
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
if(x !=0 || y != 0)
System.out.println(x + ", " + y);
}
}
This creates
-1, -1
-1, 0
-1, 1
0, -1
0, 1
1, -1
1, 0
1, 1
Notice: All but 0,0 (you don't want to revisit the same cell).
The rest of the code is simply traversing though the matrix of characters, and though the whole length of the word you are looking for until you find (or maybe you don't find) a full match.
This time the problem is that how could I print word's first and last
letter's indexes. I tried various ways like printing after each word
was searched. But, all of them didn't work. I am about to blow up.
int[] values = new int[2];
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
if(Character.toString(word.charAt(0)).equals(matrix[i][j]) == true || Character.toString(ReversedWord.charAt(0)).equals(matrix[i][j]) == true ){
System.out.print("("+ i + "," +j+")");
//First letter is found.Continue.
for(int p=1; p<word.length(); p++){
try{
for (int S = -1; S <= 1; S++) {
for (int SS = -1; SS <= 1; SS++) {
if(S !=0 || SS != 0)
if(matrix[i+S][j+SS].equals(Character.toString(word.charAt(p))) && blocksAvailable[i+S][j+SS] == true ||
matrix[i+S][j+SS].equals(Character.toString(ReversedWord.charAt(p))) && blocksAvailable[i+S][j+SS] == true) {
values[0] = i+S;
values[1] = j+SS;
blocksAvailable[i+S][j+SS] = false;
}
}
}
}catch (ArrayIndexOutOfBoundsException e) {}

Math done in a 10x10 two dimensional array does not compute correctly

I set up a two dimensional array, 10 by 10, and each slot is (x*y) for its respective position. I'm trying to add up all numbers in columns 3, 5, and 7 into cTotal and add up all numbers in rows 2, 4, and 6 into rTotal. My coding seems sound but I just can't seem to make it work. Any ideas?
public static void arrayMath()
{
int cTotal = 0;
int rTotal = 0;
//int tDiffValue = (rTotal - cTotal);
int twodimarr[][] = new int[10][10];
int row = 10;
int col = 10;
int x = 0;
int y = 0;
for(x = 0; x < row; x++)
{
for(y = 0; y < col; y++)
{
twodimarr[x][y] = x*y;
}
}
for(x = 0; x < row; x++)
{
for(y = 0; y < col; y++)
{
if( (x+y) < col )
{
//System.out.print( " " );
}
//System.out.print(" " + (twodimarr[x][y]));
}
//System.out.println();
}
for(x = 0; x < twodimarr.length; x++) //Problems start down here.
{
for( y= 0; y<twodimarr.length; y++)
{
if(y == 2 || y == 4 || y == 6)
{
rTotal = ((rTotal + twodimarr[x][y]));
}
}
}
System.out.println("rTotal is " + rTotal + ".");
for(x = 0; x < twodimarr.length; x++)
{
for(y = 0; y < twodimarr.length; y++)
{
if(x == 3 || x == 5 || x == 7)
{
cTotal = ((cTotal + twodimarr[x][y]));
}
}
}
System.out.print("cTotal is " + cTotal + ".");
}
x==3 isn't the third column, it's the 4th(0,1,2,3). That meaning it's the column of 3*0, 3*1, etc. and the 675/540 numbers are correct in that case.
Array indexes start at 0. To get the rows/columns you want you need to subtract 1 from the numbers you are checking. For rows 2, 4, 6 check if y == 1, 3, 5. For columns 3, 5, 7 check if x == 2, 4, 6.

Categories

Resources