I am working on compacting some code, right now I have 4 methods that all do almost the exact same thing except the for loops are modeled a bit differently. I'm passing int's up, down, right, and left as parameters to this compact method, which coincides with the 4 methods I used to have.
By passing 1 for one of the parameters and 0 for the rest, I am able to do different this in a single loop, I'm just having trouble with switching a < or > sign.
This is the line of code I'm trying to work with:
for (int i = (right*3)+(up*3); i <= (left*3)+(down*3); i= i + (left) + (down) - (up) - (right)) {
Everything works except I need to switch the i <= (left... part to i >= (left... if right == 1, is there a way in Java to do this in for for loop?
If this isn't possible I could make 2 different for loops, I just don't like having almost identical code being repeated.
Thanks!
Edit: Here are the 4 methods:
public boolean moveRight() {
boolean didMove = false;
for (int a = 0; a <= 3; a++) {
for (int i = 3; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
if (i != 3) {
if (valueArray[i + 1][j] == 0 && valueArray[i][j] != 0) {
valueArray[i + 1][j] = valueArray[i][j];
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
} else if (valueArray[i + 1][j] == valueArray[i][j] && valueArray[i][j] != 0) {
valueArray[i + 1][j] = valueArray[i][j] * 2;
Score += valueArray[i][j] * 2;
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
}
}
}
}
}
return didMove;
}
public boolean moveLeft() {
boolean didMove = false;
for (int a = 0; a <= 3; a++) {
for (int i = 0; i <= 3; i++) {
for (int j = 0; j < 4; j++) {
if (i != 0) {
if (valueArray[i - 1][j] == 0 && valueArray[i][j] != 0) {
valueArray[i - 1][j] = valueArray[i][j];
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
} else if (valueArray[i - 1][j] == valueArray[i][j] && valueArray[i][j] != 0) {
valueArray[i - 1][j] = valueArray[i][j] * 2;
Score += valueArray[i][j] * 2;
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
}
}
}
}
}
return didMove;
}
public boolean moveDown() {
boolean didMove = false;
for (int a = 0; a <= 3; a++) {
for (int i = 0; i < 4; i++) {
for (int j = 3; j >= 0; j--) {
if (j != 3) {
if (valueArray[i][j + 1] == 0 && valueArray[i][j] != 0) {
valueArray[i][j + 1] = valueArray[i][j];
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
} else if (valueArray[i][j + 1] == valueArray[i][j] && valueArray[i][j] != 0) {
valueArray[i][j + 1] = valueArray[i][j] * 2;
Score += valueArray[i][j] * 2;
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
}
}
}
}
}
return didMove;
}
public boolean moveUp() {
boolean didMove = false;
for (int a = 0; a <= 3; a++) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j <= 3; j++) {
if (j != 0) {
if (valueArray[i][j - 1] == 0 && valueArray[i][j] != 0) {
valueArray[i][j - 1] = valueArray[i][j];
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
} else if (valueArray[i][j - 1] == valueArray[i][j] && valueArray[i][j] != 0) {
valueArray[i][j - 1] = valueArray[i][j] * 2;
Score += valueArray[i][j] * 2;
valueArray[i][j] = 0;
didMove = true;
button[i][j].setSize(80, 80);
}
}
}
}
}
return didMove;
}
Math; multiplying both sides of the comparison with -1, turns <= into >=.
int sw = Math.abs(Math.signum(right - 1)) * 2 - 1; // -1 when right == 1 else 1
sw*i <= sw*((left*3)+(down*3))
Whether this is more optimal or rather cryptoprogramming...
Related
I did some research on what causes a stack overflow errors, and I can conclude it is being caused by a recursive function in a program that is supposed to "count the number of islands" in an array. I understand what is causing the issue, but not sure why this is happening, or my main question is what to actually do about it. I found that if I slow down the program by having it repeatedly printing out something to the console, it works, but it takes forever to complete. Is there a way I can keep the program speed without the error, or a better way to solve the problem (search up "number of islands" to find the problem). Also, the array is two dimensional with a size of 1050 by 800.
public class NumOfIslands {
static boolean[][] dotMap = new boolean[1050][800];
static boolean visited[][] = new boolean[1050][800];
static int total = 0;
public static void main(String args[]) {
defineArrays();
run();
}
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
findObjects(x,y);
//System.out.println("test");
}
}
}
}
}
public static void defineArrays() {
for(int y = 0; y < 800; y++) {
for(int x = 0; x < 1050; x++) {
dotMap[x][y] = true;
}
}
}
public static int run() {
//dotMap = DisplayImage.isYellow;
System.out.println(dotMap.length + " " + dotMap[0].length);
int objects = 0;
for(int y = 439; y < 560/*dotMap[0].length*/; y++) {
for(int x = 70; x < 300/*dotMap.length*/; x++) {
if(dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
objects++;
findObjects(x,y);
}
}
}
System.out.println("total" + total);
System.out.println(objects);
return objects;
}
}
StackOverflowError reasons. In your example each call to findObjects adds 2 variables to the stack int x and int y from loops.
One of the fastest solution:
class Solution {
int m, n;
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
m = grid.length;
n = grid[0].length;
int counter = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
visit(grid, i, j);
counter++;
}
}
}
return counter;
}
public void visit(char[][] grid, int i, int j) {
if (i < 0 || i >= m || j < 0 || j >= n) {
return;
}
if (grid[i][j] == '0') {
return;
}
grid[i][j] = '0';
visit(grid, i - 1, j);
visit(grid, i + 1, j);
visit(grid, i, j - 1);
visit(grid, i, j + 1);
}
}
All recursive algorithms can be implemented with loops. One of the example is below. The Solution implements BFS (Breadth-first search) algorithm, more details on wikipedia.
class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int nr = grid.length;
int nc = grid[0].length;
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
grid[r][c] = '0'; // mark as visited
Queue<Integer> neighbors = new LinkedList<>();
neighbors.add(r * nc + c);
while (!neighbors.isEmpty()) {
int id = neighbors.remove();
int row = id / nc;
int col = id % nc;
if (row - 1 >= 0 && grid[row-1][col] == '1') {
neighbors.add((row-1) * nc + col);
grid[row-1][col] = '0';
}
if (row + 1 < nr && grid[row+1][col] == '1') {
neighbors.add((row+1) * nc + col);
grid[row+1][col] = '0';
}
if (col - 1 >= 0 && grid[row][col-1] == '1') {
neighbors.add(row * nc + col-1);
grid[row][col-1] = '0';
}
if (col + 1 < nc && grid[row][col+1] == '1') {
neighbors.add(row * nc + col+1);
grid[row][col+1] = '0';
}
}
}
}
}
return num_islands;
}
}
the problem is in this function
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
findObjects(x,y);
//System.out.println("test");
}
}
}
}
}`
at here you are builiding a stack of recursive calls to findobjects and ultimately it has no termination condition so it ends up at infinite stacks of findobjects, so my solution is if you are just checking that if x and y varaibles are not equal and visited[x][y] is not true then there is no need to call for recursion just comment the recursive call, because your loop already do what you want the recursive call to do.
public static void findObjects(int xCord, int yCord) {
for(int y = yCord - 1; y <= yCord + 1; y++) {
for(int x = xCord - 1; x <= xCord + 1; x++) {
if(x > -1 && y > -1 && x < dotMap[0].length && y < dotMap.length) {
if((x != xCord || y != yCord) && dotMap[x][y] == true && visited[x][y] != true) {
visited[x][y] = true;
//findObjects(x,y);
//System.out.println("test");
}
}
}
}
}
public static int EncontrarCadena(char arrayTriangulo[][]) {
int aux = 0;
int area = 0;
int cantidadFilas = arrayTriangulo.length;
for (int i = 0; i < cantidadFilas; i++) {
int cantidadColumnas = arrayTriangulo[i].length;
for (int k = 0; k < cantidadColumnas; k++) {
if (arrayTriangulo[i][k] == '-') {
aux++;
} else if (arrayTriangulo[i][k] == '#') {
aux = 0;
}
if (aux%2!=0) {
int aux2 = ((aux + 1) / 2) - 1;
int aux4 = ((aux + 1) / 2) - 1;
int aux3 = aux;
int aux5 = aux3;
int a = 0;
int k2 = k;
while (aux2 != 0) {
for (int i2 = i + 1; i2 < cantidadFilas; i2++) {
for (int j = k2 - aux5 + 1; j < 2 * aux2 - 1; j++) {
if (arrayTriangulo[i2][j] == '-') {
aux3++;
} else if (arrayTriangulo[i2][j] == '#') {
break;
}
}
if (aux3 == aux + 2 * aux4 - 1) {
a++;
k2 = k2 + aux3 + 1;
aux2 = aux2 - 1;
aux4 = aux4 + 2 * ((aux + 1) / 2) - a;
aux5 = aux3;
}
}
}
if (aux2 == 0 && area < aux3) {
area = aux3;
}
}
}
aux = 0;
}
return area;
}
public static void main(String[] args) {
int filas = 5;
int columnas = 2 * filas - 1;
char arrayTriangulo[][] = new char[filas][columnas];
for (int i = (filas - 1); i > -1; i--) {
int aux = 2 * (filas - i) - 1;
for (int k = 0; k < columnas; k++) {
if (aux < 2 * filas - 1) {
if (k > (2 * filas - (aux)) / 2 && k < (columnas - (aux)) / 2 + aux) {
arrayTriangulo[i][k] = '-';
} else {
arrayTriangulo[i][k] = '-';
}
}
}
}
int area = EncontrarCadena(arrayTriangulo);
System.out.println(area);
}
So, This code get a Triangle made inside a 2d Array with the Following Format
---------
-------
-----
---
-
It's Supposed to count the area of smaller Triangles Inside of it and then return the are of the biguest triangle wich would be 25 (The sum of all the '-'). thing is the code isn't working and i have no idea why.
while (aux2 != 0) {
for (int i2 = i + 1; i2 < cantidadFilas; i2++) {
for (int j = k2 - aux5 + 1; j < 2 * aux2 - 1; j++) {
if (arrayTriangulo[i2][j] == '-') {
aux3++;
} else if (arrayTriangulo[i2][j] == '#') {
break;
}
}
if (aux3 == aux + 2 * aux4 - 1) {
a++;
k2 = k2 + aux3 + 1;
aux2 = aux2 - 1;
aux4 = aux4 + 2 * ((aux + 1) / 2) - a;
aux5 = aux3;
}
}
}
fails arround this part if i'm not mistaken
Like many other person as I see, I have a problem with my implementation of the Minmax algorithm for the game Connect4. In the example below, the algorithm doesn't try to block the player two and I don't understand why. My evaluation function is really basic: a binary function. Maybe it's because of the depth, but I don't think so.
Code:
public class Moteur {
public static void addPawn(int[][] game, int column, int player) {
int i = 0;
while (i < 6 && game[i][column] == 0) {
i++;
}
game[(i==6)?5:i-1][column] = player;
}
public static void kickPawn(int[][] game, int column) {
int i = 0;
while (i < 6 && game[i][column] == 0) {
i++;
}
game[i][column] = 0;
}
public static void AI_play(int[][] game, int depth) {
int max = -10000;
int tmp = 0;
int maxj = -5;
int j;
for (j = 0; j < 7; j++) {
if(game[0][j] == 0) {
addPawn(game, j, 1);
tmp = Min(game, depth - 1);
if (tmp > max) {
max = tmp;
maxj = j;
}
kickPawn(game, j);
}
}
addPawn(game, maxj, 1);
}
public static int Max(int[][] game, int depth) {
if(depth == 0 || winner(game) != 0) {
return eval(game);
}
int max = -10000;
int j, tmp;
for(j = 0; j < 7; j++) {
if(game[0][j] == 0) {
addPawn(game, j, 2);
tmp = Min(game, depth - 1);
if(tmp > max) {
max = tmp;
}
kickPawn(game, j);
}
}
return max;
}
public static int Min(int[][] game, int depth) {
if(depth == 0 || winner(game) != 0) {
return eval(game);
}
int min = 10000;
int j, tmp;
for(j = 0; j < 7; j++) {
if(game[0][j] == 0) {
addPawn(game, j, 1);
tmp = Max(game, depth - 1);
if(tmp < min) {
min = tmp;
}
kickPawn(game, j);
}
}
return min;
}
public static int eval(int[][] game) {
int gameWinner, nb_pawns = 0;
for (int i = 0; i < game.length; i++) {
for (int j = 0; j < game[0].length; j++) {
if(game[i][j] != 0) {
nb_pawns++;
}
}
}
gameWinner = winner(game);
if(gameWinner == 1) {
return 1000 - nb_pawns;
} else if (gameWinner == 2) {
return -1000 + nb_pawns;
} else {
return 0;
}
}
public static int winner(int[][] game) {
Integ e = new Integ();
for (int j = 0; j < game[0].length; j++) {
if(game[5][j]!= 0 && testWinner(game, j, e)) {
return e.getI();
}
}
return 0;
}
public static boolean testWinner(int[][] game, int lastColumn, Integ e) {
int lastRow = 0;
while (lastRow < 6 && game[lastRow][lastColumn] == 0) {
lastRow++;
}
lastRow = lastRow;
int i = 0;
int j = 0;
int currentPlayer = game[lastRow][lastColumn];
e.setI(currentPlayer);
int sequence = 0;
i = lastRow;
boolean b = i < 3
&& game[i][lastColumn] == currentPlayer
&& game[i+1][lastColumn] == currentPlayer
&& game[i+2][lastColumn] == currentPlayer
&& game[i+3][lastColumn] == currentPlayer;
if(b) {
return true;
}
sequence = 0;
j = lastColumn;
do {
j--;
} while(0 < j && game[lastRow][j] == currentPlayer);
if(j < 0 || game[lastRow][j] != currentPlayer) {
j++;
}
while(j <= 6 && game[lastRow][j] == currentPlayer) {
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i--;
j--;
} while(0 < i && 0 < j && game[i][j] == currentPlayer);
if(i < 0 || j < 0 || game[i][j] != currentPlayer) {
i++;
j++;
}
while(i <= 5 && j <= 6 && game[i][j] == currentPlayer) {
i++;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i++;
j--;
} while(i < 5 && 0 < j && game[i][j] == currentPlayer);
if (5 < i || j < 0 || game[i][j] != currentPlayer) {
i--;
j++;
}
while(0 <= i && j <= 6 && game[i][j] == currentPlayer) {
i--;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
return false;
}
public static void main(String[] args) {
int[][] game = new int[6][7];
int depth = 5;
game[5][3] = 2;
game[4][3] = 2;
game[3][3] = 2;
AI_play(game, depth);
//game[4][0] = 2;
//AI_play(game, depth);
//game[5][2] = 2;
//AI_play(game, depth);
//game[5][3] = 2;
//AI_play(game, depth);
//game[1][0] = 2;
//AI_play(game, depth);
//game[5][4] = 2;
//AI_play(game, depth);
for (int i = 0; i < game.length; i++) {
for (int j = 0; j < game[0].length; j++) {
System.out.print(game[i][j]);
}
System.out.println("");
}
}
private static class Integ {
private int i;
public Integ() {
this.i = 0;
}
public void increment() {
this.i = this.i + 1;
}
public int getI() {
return this.i;
}
public void setI(int i) {
this.i = i;
}
}
}
I have used Libgdx to generate a dungeon out of keyboard characters. I have decided to print out the array as a text file.
However this is what I got:
Furthermore, It isn't consistent
I don't get what is wrong?
I checked over my algorithm and didn't find anything wrong.
Here is my code:
public class test1 extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
int X = 50;
int Y = 25;
////////// # wall
////////// . ground
char[][][] mapChars = new char[1000][1000][1000];
private void genDung() {
int clearance = 4;
for (int i = 0; i < Y; i++) {
for (int j = 0; j <= X; j++) {
if(j == X)
mapChars[0][i][j] = '\n';
else
mapChars[0][i][j] = '#';
}
}
int roomCount = MathUtils.random(2, 2);
int[] roomPosX = new int[roomCount];
int[] roomPosY = new int[roomCount];
int[] roomCenterPosX = new int[roomCount];
int[] roomCenterPosY = new int[roomCount];
int[] roomSizeX = new int[roomCount];
int[] roomSizeY = new int[roomCount];
for (int i = 0; i < roomCount; i++) {
int attempts = 0;
while(true) {
boolean rePosition = false;
roomPosX[i] = MathUtils.random(1, X-1);
roomPosY[i] = MathUtils.random(1, Y-1);
roomSizeX[i] = MathUtils.random(2, 12);
roomSizeY[i] = MathUtils.random(2, 8);
for(int j = 0; j <= i; j++) {
if(i != j) {
if(roomPosX[i] >= roomPosX[j] && roomPosX[i] <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if(roomPosY[i] >= roomPosY[j] && roomPosY[i] <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
if((roomPosX[i]+roomSizeX[i]) >= roomPosX[j] && (roomPosX[i]+roomSizeX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if((roomPosY[i]+roomSizeY[i]) >= roomPosY[j] && (roomPosY[i]+roomSizeY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
if((roomPosX[i]) >= roomPosX[j] && (roomPosX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if((roomPosY[i]+roomSizeY[i]) >= roomPosY[j] && (roomPosY[i]+roomSizeY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
if((roomPosX[i]+roomSizeX[i]) >= roomPosX[j] && (roomPosX[i]+roomSizeX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if((roomPosY[i]) >= roomPosY[j] && (roomPosY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
}
else if(roomPosX[j] + roomSizeX[j] >= X-1){
rePosition = true;
}
else if(roomPosY[j] + roomSizeY[j] >= Y-1){
rePosition = true;
}
}
attempts++;
if(attempts >= 10000) break;
if(!rePosition) break;
}
}
for(int r = 0; r < roomCount; r++) {
for (int a = roomPosX[r]; a <= (roomPosX[r] + roomSizeX[r]); a++) {
for (int b = roomPosY[r]; b <= (roomPosY[r] + roomSizeY[r]); b++) {
mapChars[0][b][a] = '.';
}
}
}
Gdx.app.log("roomCount", String.valueOf(roomCount)+"\n\n\n");
for(int i =0; i< roomCount; i++) {
roomCenterPosX[i] = roomPosX[i] + roomSizeX[i]/2;
roomCenterPosY[i] = roomPosY[i] + roomSizeY[i]/2;
Gdx.app.log("room", String.valueOf(i)+"\n");
Gdx.app.log("roomPosX", String.valueOf(roomPosX[i]));
Gdx.app.log("roomPosY", String.valueOf(roomPosY[i]));
Gdx.app.log("roomSizeX", String.valueOf(roomSizeX[i]));
Gdx.app.log("roomSizeY", String.valueOf(roomSizeY[i])+"\n");
Gdx.app.log("RoomCenterPosX", String.valueOf(roomCenterPosX[i]));
Gdx.app.log("RoomCenterPosY", String.valueOf(roomCenterPosY[i])+"\n\n");
}
int difference = X;
int[] roomNum = new int[2];
for(int i = 0; i < roomCount; i++) {
for(int j = 0; j < roomCount; j++) {
if(i != j) {
if(abs(roomCenterPosX[i] - roomCenterPosX[j]) < difference) {
difference = abs(roomCenterPosX[i] - roomCenterPosX[j]);
roomNum[0] = i;
roomNum[1] = j;
}
}
}
}
Gdx.app.log("FarthestRooms", String.valueOf(roomNum[0]));
Gdx.app.log("FarthestRooms", String.valueOf(roomNum[1]));
int differenceX = X;
int differenceY = Y;
int[] connectRooms = new int[2];
// int[] roomsConnected = new int[roomCount];
connectRooms[0] = MathUtils.random(0, roomCount - 1);
// roomsConnected[0] = connectRooms[0];
int count;
for(int i = 0; i < roomCount-1; i++) {
int j;
while(true) {
connectRooms[1] = MathUtils.random(0, roomCount - 1);
/* while (true) {
connectRooms[1] = MathUtils.random(0, roomCount - 1);
count = 0;
for (j = 0; j < i; j++) {
if (connectRooms[1] != roomsConnected[j] && connectRooms[0] != roomsConnected[j]){
count++;
}
}
if(count >= i-2)
break;
}*/
if(connectRooms[0] != connectRooms[1])
break;
}
// roomsConnected[i+1] = connectRooms[1];
differenceX = roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]];
differenceY = roomCenterPosY[connectRooms[0]] - roomCenterPosY[connectRooms[1]];
if(roomCenterPosX[connectRooms[0]] < roomCenterPosX[connectRooms[1]])
differenceX *= -1;
if(roomCenterPosY[connectRooms[0]] < roomCenterPosY[connectRooms[1]])
differenceY *= -1;
int k;
try {
if (differenceX > 0) {
for (k = 0; k < differenceX; k++) {
mapChars[0][roomCenterPosY[i]][roomCenterPosX[i] + k] = '.';
}
} else if (differenceX < 0) {
for (k = 0; k > differenceX; k--) {
mapChars[0][roomCenterPosY[i]][roomCenterPosX[i] + k] = '.';
}
} else k = 0;
if (differenceY < 0) {
for (int z = 0; z > differenceY; z--) {
mapChars[0][roomCenterPosY[i] + z][roomCenterPosX[i] + k] = '.';
}
} else if (differenceY > 0) {
for (int z = 0; z < differenceY; z++) {
mapChars[0][roomCenterPosY[i] + z][roomCenterPosX[i] + k] = '.';
}
} else {
}
}
catch (ArrayIndexOutOfBoundsException e) {
Gdx.app.log("Non Fatal Exception", String.valueOf(e));
}
Gdx.app.log("Connect", String.valueOf(connectRooms[0]));
Gdx.app.log("Connect", String.valueOf(connectRooms[1]));
Gdx.app.log("DifferenceX", String.valueOf(differenceX));
Gdx.app.log("DifferenceY", String.valueOf(differenceY)+"\n");
}
for(int q = 0; q < Y; q++) {
mapChars[0][q][X] = '\n';
}
for(int w = 0; w < Y; w++) {
mapChars[0][w][X-1] = '#';
}
for(int e = 0; e < Y; e++) {
mapChars[0][Y-1][e] = '#';
}
}
private void export() {
if(Gdx.files.isLocalStorageAvailable()) {
FileHandle fileHandle = Gdx.files.local("map.txt");
if(Gdx.files.local("map.txt").exists())
fileHandle.writeString("", false);
for(int i = 0; i<= Y; i++) {
for (int j = 0; j <= X; j++) {
fileHandle.writeString(""+mapChars[0][i][j] , true);
}
}
}
}
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
// genMap();
// for(int i = 0; i< 4; i++)
// refineMap();
genDung();
export();
}
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
if(Gdx.input.isTouched()) {
// genMap();
// for(int i = 0; i< 4; i++)
// refineMap();
genDung();
export();
}
}
}
I want the two rooms to connect properly every time.
As you can see, one of the time, the rooms connected
The other time the rooms don't connect.
Thanks in advance
The whole thing can be simplified and definitely needs refactoring. Regarding the 2 room connection - check this piece carefully
differenceX = roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]];
differenceY = roomCenterPosY[connectRooms[0]] - roomCenterPosY[connectRooms[1]];
if(roomCenterPosX[connectRooms[0]] < roomCenterPosX[connectRooms[1]])
differenceX *= -1;
if(roomCenterPosY[connectRooms[0]] < roomCenterPosY[connectRooms[1]])
differenceY *= -1;
As #kiheru pointed out it is equivalent to Math.abs(roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]]) (same for Y). So you always "dig" to right and down, never up or left.
Drop that invertion and have fun with the rest of your algorithm :)
I'm working on sudoku project and I found this:
http://www.codeproject.com/Articles/23206/Sudoku-Algorithm-Generates-a-Valid-Sudoku-in
I converted that code into java but I just can't see where I have made mistake...
It almost works but it still places few numbers on same lines.
I have been stuggling with this sudoku generator for some time, I just can't see where I have done mistake, first I converted that vb.net code to C# and it worked fine.
Here is my java code (I left out code that produces grid):
private static JTextField sudoku[][] = new JTextField[9][9];
public static List<Square> sudokuGrid = new ArrayList<Square>();
public static void GenerateGrid(){
Square[] Squares = new Square[81];
for(int i = 0; i <= 80; i++){
Squares[i] = new Square();
}
List<List<Integer>> available = new ArrayList<List<Integer>>();
int c = 0;
for(int x = 0; x <= 80; x++){
available.add(new ArrayList<Integer>());
for(int i = 1; i <= 9; i++){
available.get(x).add(i);
}
}
while(!(c == 81)){
if(available.get(c).size() != 0){
int i = GetRan(0, available.get(c).size() - 1);
int z = available.get(c).get(i);
if (Conflicts(Squares, Item(c, z)) == false){
Squares[c] = Item(c, z);
available.get(c).remove(i);
c += 1;
}else{
available.get(c).remove(i);
}
}else{
for (int y = 1; y <= 9; y++){
available.get(c).add(y);
}
Squares[c - 1] = new Square();
c -= 1;
}
int j = 0;
for (j = 0; j <= 80; j++)
{
sudokuGrid.add(Squares[j]);
}
}
}
private static boolean Conflicts(Square[] CurrentValues, Square test){
for (Square s : CurrentValues){
if ((s.Across != 0 && s.Across == test.Across) || (s.Down != 0 && s.Down == test.Down) || (s.Region != 0 && s.Region == test.Region)){
if (s.Value == test.Value){
return true;
}
}
}
return false;
}
private static Square Item(int n, int v){
Square functionReturnValue = new Square();
n += 1;
functionReturnValue.Across = GetAcrossFromNumber(n);
functionReturnValue.Down = GetDownFromNumber(n);
functionReturnValue.Region = GetRegionFromNumber(n);
functionReturnValue.Value = v;
functionReturnValue.Index = n - 1;
return functionReturnValue;
}
public static int GetAcrossFromNumber(int n){
int k = 0;
k = n % 9;
if (k == 0)
return 9;
else
return k;
}
public static int GetDownFromNumber(int n){
int k = 0;
if (GetAcrossFromNumber(n) == 9)
{
k = n / 9;
}
else
{
k = n / 9 + 1;
}
return k;
}
private static int GetRegionFromNumber(int n){
int k = 0;
int a = GetAcrossFromNumber(n);
int d = GetDownFromNumber(n);
if (1 <= a && a < 4 && 1 <= d && d < 4) {
k = 1;
} else if (4 <= a && a < 7 && 1 <= d && d < 4) {
k = 2;
} else if (7 <= a && a < 10 && 1 <= d && d < 4) {
k = 3;
} else if (1 <= a && a < 4 && 4 <= d && d < 7) {
k = 4;
} else if (4 <= a && a < 7 && 4 <= d && d < 7) {
k = 5;
} else if (7 <= a && a < 10 && 4 <= d && d < 7) {
k = 6;
} else if (1 <= a && a < 4 && 7 <= d && d < 10) {
k = 7;
} else if (4 <= a && a < 7 && 7 <= d && d < 10) {
k = 8;
} else if (7 <= a && a < 10 && 7 <= d && d < 10) {
k = 9;
}
return k;
}
public static int GetRan(int lower, int upper){
Random rand = new Random();
return rand.nextInt((upper - lower) + 1) + lower;
}
public void newGame() {
for (int x = 0; x <= 8; x++) {
for (int y = 0; y <= 8; y++) {
sudoku[x][y].setEditable(true);
sudoku[x][y].setText("");
}
}
sudokuGrid.clear();
GenerateGrid();
for(Square s : sudokuGrid){
for(int x = 0; x <= 8; x++){
for(int y = 0; y <= 8; y++){
int index = s.Index;
if(sudoku[x][y].getName().equals(String.valueOf(index))){
sudoku[x][y].setText(String.valueOf(s.Value));
}
}
}
}
}
class Square{
public int Across;
public int Down;
public int Region;
public int Value;
public int Index;
}
Some help please :)
If you look closely at the linked code in GenerateGrid:
int j = 0;
for (j = 0; j <= 80; j++)
{
sudokuGrid.add(Squares[j]);
}
should come after the while(c != 81) loop. In your code, it is inside the loop.
This means that you're adding too many squares to sudokuGrid. To check that this is happening, print the size of sudokuGrid at the end of the method -- it'll be a lot greater than 81.
Edit:
Also, there might be problems with the way you're displaying the board. Try this at the end of newGame, after the GenerateGrid call:
for(int x = 0; x <= 8; x++) {
for(int y = 0; y <= 8; y++) {
sudoku[x][y].setText("" + sudokuGrid.get(x * 9 + y).Value);
}
}