I'm trying to create a basic RTS style grid. The grid works perfectly and I can place object by setting a number to anything other than 0.
That's the easy part. currently im trying to allow each object that is placed to be rotated. The objects that can be rotated can be any size e.g. 1x1, 2x1, 3x4 etc, and all object have an entry block which needs to be rotated with the object.
For example.
My grid is empty
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 0 0 0 0
and I can place an object shown below:
1 2 1
1 1 1
which will place like
0 0 0 0 0 0 0
0 1 2 1 0 0 0 1 2 1
0 1 1 1 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 0
but when rotated it should place like
1 2 1 0 1 1 0 1 2 1 1 1
1 1 1 0 1 2 0 1 1 1 1 2
0 0 0 0 1 1 0 1 1
0 1 1 0 0 0 0 1 1
0 2 1 0 1 1 1 2 1 1 1 1
0 1 1 0 1 2 1 1 1 1 2 1
Im trying to figure out how this could be acheived in code considering that the object can be of different shapes? :(
1 1 2 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 2 1 1 1 1 1
1 1 1 1 1 1
I figured out how to accomplish this from another board on here.
First thing I did was store the object in a 2 dimensional array e.g.
1 2 1 1
1 1 1 1
I then transposed the array leaving me with this array
1 1
2 1
1 1
1 1
And then I rotated each row leaving me with my final rotated object
1 1
1 2
1 1
1 1
And for 180+ rotations I just use this technique again to reach the desired rotation :)
My final Array Class in Unity3D C#
using UnityEngine;
using System.Collections;
namespace Arrays {
public class Array {
public static int[,] Rotate(int[,] array)
{
return Rotate90 (array);
}
public static int[,] Rotate90(int[,] array)
{
return RotateArrayRow( Transpose(array) );
}
public static int[,] Rotate180(int[,] array)
{
return Rotate90(Rotate90(array));;
}
public static int[,] Rotate270(int[,] array)
{
return Rotate90(Rotate180(array));;
}
private static int[,] RotateArrayRow(int[,] array){
int x = array.GetLength(1);
int y = array.GetLength(0);
int[,] temp = new int[y,x];
for(int i=0; i<y; i++)
{
for(int j=0; j<x; j++)
{
temp[i,x-j-1] = array[i,j];
}
}
return temp;
}
public static int[,] Transpose(int[,] array){
int x = array.GetLength(1);
int y = array.GetLength(0);
int[,] temp = new int[x,y];
for(int i=0; i<y;i++){
for(int j=0; j<x; j++){
temp[j,i] = array[i,j];
}
}
return temp;
}
public static void Log(int[,] array){
for(int i=0; i<array.GetLength(0); i++)
{
string line = "";
for(int j=0; j<array.GetLength(1); j++)
{
line += array[i,j] + " ";
}
Debug.Log(line);
}
}
}
}
One thing to think about first is that to rotate your objects you only need to implement one rotation function: 90 degrees in one direction. The other rotations just repeat this operation 2 or 3 times, simplifying your logic.
There are two mappings from original to rotated array you need to consider:
How do the dimensions map?
How do the indices map?
1 is easy: the dimensions are swapped. A rotated 1x4 becomes 4x1.
2 depends on your implementation, but if you're using 2d coordinates [x, y] => [y, -x] or [-y, x] depending on direction of rotation.
Related
I am trying for hours to print DFS trace (including when you get stuck and you have to backtrack) but my output is always missing a 0 and having double numbers
My input matrix is like this
0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 1 0 1 0
1 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 1 0 0
0 0 0 0 0 1 1 0
My output is like this
0 0 1 0 2 2 4 4 5 2 6 3 7
But it should be like this
0 1 0 2 4 5 4 2 6 2 0 3 7
My algoritem is this one
public void DFSDriver(int[][] adjMatrix)
{
int[] visitMatrix = new int[adjMatrix[0].length];
DftRecursive(adjMatrix, visitMatrix, 0); //Visit all nodes you can
//Visit the ones you cannot because they are separate
for(int i = 0; i < adjMatrix.length; i++) {
if(visitMatrix[i] != 1) {
DftRecursive(adjMatrix, visitMatrix, i); //Visit the ones you cannot because they are separate
}
}
}
public void DftRecursive(int[][] srcMatrix, int[] visitMatrix, int vertex)
{
visitMatrix[vertex] = 1;
System.out.print(vertex + " ");
for (int neighbour = 0; neighbour < srcMatrix[0].length; neighbour++)
{
if (srcMatrix[vertex][neighbour] == 1 && visitMatrix[neighbour] == 0)
{
System.out.print(vertex + " "); //If I don't print this DFS by itself works fine, but I want to print this because I want to backtrack when I get stuck
DftRecursive(srcMatrix, visitMatrix, neighbour);
}
}
}
Hope someone can figure out what I am doing wrong here (the problem is that I also need to print the backtracking, printing only DFS is fine, but backtracking is harder to do)
exchanging the print line and the DftRecursive line.
like this:
if (srcMatrix[vertex][neighbour] == 1 && visitMatrix[neighbour] == 0)
{
DftRecursive(srcMatrix, visitMatrix, neighbour);
System.out.print(vertex + " ");
}
Solving problem of 8 queens i am actually stuck in how to access the diagonals of a particular cell to set it to 1 when placing a queen. There is simple logic for the cells which are in vertical or horizontal of the selected cell where queen has to be placed.
Here is the code of my function to set the cells for the queen to 1 which that queen can attack.
static int[][] SetPos(int csp[][],int row,int col){
int count = 0, n = csp.length;
for (int i = 0; i < csp.length; i++) {
for (int j = 0; j < csp.length; j++) {
if(i==row || j==col){
csp[i][j]=1;
}
if(row==col && i==j){
//csp[row][col]=1;
csp[i][j]=1;
}
if(row+count==i && col+count==j){
csp[i][j]=1;
}
}
count++;
}
return csp;
}
How can this condition be improved:
if(row+count==i && col+count==j){
csp[i][j]=1;
}
So that i get result for cell(5,5) as :
1 0 0 0 0 1 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 1 0 0
0 0 0 1 0 1 0 1
0 0 0 0 1 1 1 0
1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 0
0 0 0 1 0 1 0 1
not like this :
1 0 0 0 0 1 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 1 0 0
0 0 0 1 0 1 0 0
0 0 0 0 1 1 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 1 1 0
0 0 0 0 0 1 0 1
Backtracking is not the concern right now.
Your condition
if(row==col && i==j){
//csp[row][col]=1;
csp[i][j]=1;
}
should only work if row==col.
Otherwise you will only get the horizontal and vertical numbers.
If you want to mark the diagonals starting from row and col, this code should work:
if(i-j==row-col){ //diagonal up_left to down_right
csp[i][j]=1;
}
if(i+j==row+col) { //diagonal down_left to up_right
csp[i][j]=1;
}
I am working on a project to implement a DFS for a given adjacency matrix. I have the file reading in correctly and I have the program outputting a list of first encountered vertices, however, I am not getting the correct list. I am getting 1 2 6 5 7 3 4 8 but I need to get 1 2 6 7 4 3 5 8. I am not sure where I am going wrong, but any suggestions would help. Below I have attached the part of code the outputs the encountered vertices and the file with the adjacency matrix.
Code with the output:
public static void dfs(int vertex, boolean[] visitArray, ArrayList<Integer> DFSvertexList, ArrayList<Integer> DFSdeadEndList, int[][] DFStreeEdgeGraph, ArrayList<Integer> vertexList, ArrayList<Integer> iList, boolean[] visitArray2){
int ver = 0;
DFSvertexList.add(vertex);
visitArray[vertex] = true;
for(int i = 0; i <= dim-1; i++){
if(graph[vertex][i] == 1){
if(!visitArray[i]){
ver = i;
DFStreeEdgeGraph[vertex][i] = 1;
dfs(i, visitArray, DFSvertexList, DFSdeadEndList, DFStreeEdgeGraph, vertexList, iList, visitArray2);
DFSdeadEndList.add(i);
}
else if(i >= vertex && i != ver){
vertexList.add(vertex+1);
iList.add(i+1);
}
}
}
}
Here is the adjacency matrix:
0 1 0 0 1 1 0 0
1 0 0 0 0 1 1 0
0 0 0 1 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0
1 1 0 0 1 0 0 0
0 1 1 0 0 0 0 1
0 0 0 1 0 0 1 0
Please let me know if more code is needed.
I have a file with some values in it:
11
8
0 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 0 0 0
0 0 1 1 1 1 1 1 1 0 0
0 1 1 0 1 1 1 0 1 1 0
1 1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 0 1
1 0 1 0 0 0 0 0 1 0 1
0 0 0 1 1 0 1 1 0 0 0
I need to read those values into a 2D ArrayList. The fist two values (11 and 8) would be the number of rows and columns respectively. So here is the code:
Scanner scanner = new Scanner(file);
int x, y;
x = scanner.nextInt();
System.out.println(x + " has been read");
y = scanner.nextInt();
System.out.println(y + " has been read");
ArrayList<ArrayList<Boolean>> pixelMap;
pixelMap = new ArrayList<ArrayList<Boolean>>();
ArrayList<Boolean> buffer_line = new ArrayList<Boolean>();
Boolean buffer;
for (int i = 0; i < x; i++){
for (int j = 0; j < y; j++){
buffer = scanner.nextBoolean();
System.out.println(buffer + " has been read");
//buffer_line.add(buffer);
}
//pixelMap.add(buffer_line);
//buffer_line.clear();
}
The problem is - the program reads first two numbers successfully, and when it comes to boolean values, it throws InputMismatch exception on line
buffer = scanner.nextBoolean();
so I can't undersand why. 0 should be read next and it is boolean - so what's actually mismatching?
I also point out that if change buffer type to integer and then assign scanner.nextInt(), the program would read all the values properly, so in the output I would see all of them. So then of course, I can change ArrayList to Integer to make that work, but it would be semantically wrong as it would hold only boolean values.
Can anyone help me to find out the problem?
In your code you have this statement:
buffer = scanner.nextBoolean();
But I do not see boolean values true or false in the input file.
In Java, 0 and 1 are not treated as boolean values like in other languages such as C.
You need to read these values as int and then manually map them to boolean values.
Logic something like this:
int val = scanner.nextInt();
boolean buffer = (val == 1) ? true : false;
I am trying to walk through a 2D array and count all diagonal neighbors that equal 0, then set the current position equal to the number of neighbors. For example:
0 5 0 9
0 5 0 3
1 9 4 6
7 0 0 9
Should change to
0 2 0 1
0 3 1 2
1 3 1 2
0 1 1 1
I am using the following code (I catch exceptions because there will be index out of bounds exceptions for all parameter numbers) :
int row, col, count;
count = 0;
// Standard for-loop used in walking through a 2D array
for (row = 0; row < NUM; row++) {
for (col = 0; col < NUM; col++) {
// Check top left neighbor
try {
if (grid[row - 1][col - 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Check bottom left neighbor
try {
if (grid[row - 1][col + 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Check top right neighbor
try {
if (grid[row + 1][col - 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Check bottom right neighbor
try {
if (grid[row + 1][col + 1] == 0) {
count++;
}
} catch (IndexOutOfBoundsException e) {
} // Set current place in the array equal to number of 0 neighbors
grid[row][col]=count;
count = 0;
}
}
The issue is that my output is wrong. Instead of the supposed code, it changes to the following:
0 2 0 1
0 3 1 2
1 2 1 1
0 0 0 0
So the first two lines work , then the 3rd line has several OBO errors. Not sure what's even wrong with the last line, and I'm not sure where this is going wrong.
Summary
Original is:
0 5 0 9
0 5 0 3
1 9 4 6
7 0 0 9
That should change to:
0 2 0 1
0 3 1 2
1 3 1 2
0 1 1 1
But I'm getting:
0 2 0 1
0 3 1 2
1 2 1 1
0 0 0 0
Another Example Would Be:
Original:
5 0 0 3 9 5
0 0 9 5 3 0
0 0 0 9 7 3
7 0 5 0 9 5
0 0 3 0 0 0
9 5 0 3 7 0
Updated:
1 1 1 0 1 0
1 2 2 1 2 0
1 0 2 0 2 0
2 1 4 1 4 1
0 1 0 1 1 0
0 2 0 1 1 0
Any suggestions would be very much appreciated.
You start with
0 5 0 9
0 5 0 3
1 9 4 6
7 0 0 9
You start traversing from the top left and simultaneously modifying the matrix.
So after 2 rows have been modified, the intermediate matrix is
0 2 0 1
0 3 1 2
1 9 4 6
7 0 0 9
Now take into consideration the element at index [2][1]. In the original matrix, it had 3 zero neighbors, but this matrix only has 2, hence the difference in expected and obtained output.
Make a separate matrix to store the modified values.