Checking Left/Right in an int array for Tetris, Android/Java - java

I'm trying to make a tetris game for android to help learn game programming for android. My goLeft/Rights break right when the button is pressed, the code for going left is in a class separate of the fields int array, and the list parts array. The fields array is accessed by a referenced variable (TetrisWorld tetrisworld;). While part list array is public so accessed through a variable(part) code for which is in the goLeft() code. It breaks at: if(tetrisworld.fields[x][part.y] != 0) Code for left:
public void goLeft() {
int x = 0;
for(int i = 0; i < 4; i++) {
TetrisParts part = parts.get(i);
x = part.x - 1;
if(tetrisworld.fields[x][part.y] != 0) {
noleft = true;
break;
}
}
if(noleft == false) {
for(int i = 0; i < 4; i++) {
TetrisParts part = parts.get(i);
part.x--;
}
}
}
The code for the fields int array:
int fields[][] = new int[WORLD_WIDTH][WORLD_HEIGHT];
WORLD_WIDTH and WORLD_HEIGHT are both static final ints, width being 9 and height being 19
I've tried putting if(tetrisworld.fields[0][0] == 0) and it still crashes so I don't think it has to do with the variables. Also It doesn't go out of bound even if I haven't added the code to check for that yet because I have the teroid spawning around x = 5 and since I can't go left/right once there's not a chance of that happening
I've tried moving the goLeft/Right methods to the gamescreen class which has a "world = TetrisWorld();" and it still bugs out at the same spot
UPDATE:
Ok just adding:
tetrisworld != null
to the first if statement fixed it, my question now is, why did it fix it? Why can't I move without this check? It clearly isn't null cause as far as I know; it's fully responsive now.
But an easier way to have solved this which is SOOOO easy is changing fields to static... then access it lika so: TetrisWorld.fields so my updated code is:
public void goLeft()
{
noleft = false;
for (int i = 0; i < 4; i++)
{
part = parts.get(i);
if (part.x - 1 < 0 || TetrisWorld.fields[part.x - 1][part.y] != 0)
{
noleft = true;
break;
}
}
if (noleft == false)
{
for (int i = 0; i < 4; i++)
{
part = parts.get(i);
part.x--;
}
}
}

Looks like you are hitting IndexOutOfBoundsException.
When you are doing x = part.x - 1;, your x variable can become lesser tan zero, thus your code will act like if(tetrisworld.fields[-1][part.y] != 0

It looks like you're getting a java.lang.NullPointerException when trying to access the array in tetrisworld. In the line you mention there are several ways that this could occur:
if(tetrisworld.fields[x][part.y] != 0) {
tetrisworld could be null.
The fields member of tetrisworld could be null.
The second array that you're looking up by using tetrisworld.fields[x].
The value of part could be null.
Having a quick look through your source code it looks to me like you never initialise tetrisworld, either at declaration using:
TetrisWorld tetrisworld = new TetrisWorld();
Or at some other point which is certain to have happened before your goLeft() method is called.

Ok I believe I found the answer, referencing: http://en.wikipedia.org/wiki/Null_Object_pattern
Apparently java will throw an NPE if you don't check for it first if you have a null reference? Is there any way to initialize it without doing a TetrisWorld tetrisworld = new TetrisWorld(); because it's already created in a different class so i get a thousand errors, an actual stack overflow! lul... Still not 100% positive. Please comment to verify and possibly suggest a better way to go about this.

Related

Cant find the mistake

The task was to write a method to return the least value of an array.
Would someone quickly look over my code?
public static int findMinimum (int [] array) {
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
for (int zwiebel= 0; zwiebel < array.length; zwiebel ++) {
if (array [zwiebel] < array [kohlrabi]) {
kohlrabi = zwiebel -1;
break;
}
int spinat = array [kohlrabi];
if (zwiebel == array.length-1) {
return spinat;
}
}
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: This method must return a result of type int
at Abgabe7.ArrayExercises.findMinimum(ArrayExercises.java:38)
It's a homework for my school and I definitely understood the logic behind it but cannot find my fault.
Thanks Max
I don't think you need to have two loops. One loop would work.
Simply loop though the array keeping a variable which is the lowest you've found.
You should declare a global variable before the loop then use only one for loop in your code as follows:
int zwiebel= 0;
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
if (kohlrabi == 0){
zwiebel = array[kohlrabi];
}
if (array[kohlrabi] < zwiebel) {
zwiebel = array[kohlrabi];
}
}
The lowest value in your array is now stored in the variable zwiebel.
The real mistake is that you are not taking the possibility of an empty array into account. One thing to learn in programming is to think of all possibilities (maybe you’ve discovered that already). An array in Java (and most other languages) can have length 0, that is, have no elements in it. When array.length is 0, your outer for loop doesn’t execute, so we get down to the bottom of the method without having returned anything and without having anything to return.
Java is dumb, but nevertheless smart enough to discover this problem for you. When your method is declared to return an int, it insists that it too can see that it will return an int in all cases. In your method it cannot, which is what the following message is trying to tell you:
This method must return a result of type int
One possible fix — and I may be showing you something that you haven’t learned in school yet — is to insert the following statement in the end of your method:
throw new IllegalArgumentException("Cannot find the minimum of an empty array");
Throwing an exception is an alternative to returning a value, so this statement will make Java happy. If you actually try to find the minimum of an empty array, your program will crash and give you the message “Cannot find the minimum of an empty array”. But finding the minimum of an array that has numbers in it should work now.
That said the others are correct: Your way of finding the minimum is overly complex. I have been staring at your code and still have not understood how it works. Such code is not good. In real life you will be writing code that others will need to read and change after you, and no one can change code they don’t understand, so your code would not be useful. More important than writing code that works correctly is writing readable code.
Edit: There are variations on how to do this in a simple way. For a school exercise using a for loop I would write:
public static int findMinimum (int [] array) {
if (array.length == 0) {
return 42; // or whichever value is desired in this case
}
int niedrichsteSoWeit = array[0];
for (int index = 1; index < array.length; index++) {
if (array[index] < niedrichsteSoWeit) {
niedrichsteSoWeit = array[index];
}
}
return niedrichsteSoWeit;
}
For production code I probably would not write a method but use the built-in functionality, for example:
IntStream.of(myIntArray)
.min()
.ifPresentOrElse(min -> {
// do something with min
}, () -> {
// do whatever you want to do when the array is empty
});
Don’t worry if you don’t understand a bit of this snippet. It’s mostly for more experienced programmers who might happen to read this answer.

Count elements of a list using While loop in java

I am passing some parameters in the URL and then I add them in a list. My list has a limit of 5 elements. So if someone adds 6th element in the URL the list would simply ignore it. So I am trying to use a counter but the logic is not working as desired. I am using While loop to achieve this. So if list size is smaller than 5 set the agencyCds otherwise just return the list.
private List<IUiIntegrationDto> generateViewIntegrationReportData(ESignatureIntegrationConfig eSignConfig) throws Exception {
int counter = 1;
if(eSignConfig.getAdditionalAgencyCds() != null ) {
List<String> combinedAgencyCds = new ArrayList<String>();
for(String agencyCd : eSignConfig.getAgencyCd()) {
combinedAgencyCds.add(agencyCd);
}
StringTokenizer token = new StringTokenizer(eSignConfig.getAdditionalAgencyCds().toString(), StringConstants.COMMA);
while(token.hasMoreTokens()) {
combinedAgencyCds.add(token.nextToken());
}
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
// eSignConfig.setAgencyCd(combinedAgencyCds);
}
List<IUiIntegrationDto> intgList = getUiIntegrationManager().retrieveUiIntegrationReportData(eSignConfig.getAgencyCd(), eSignConfig.getCreatedDays(),
eSignConfig.getLob(), eSignConfig.getTransactionStatus(), eSignConfig.getAccounts(), eSignConfig.getSortKey(), eSignConfig.getSortOrder());
return intgList;
}
I am not completely sure about this logic if it is correct or if there is nay better approach.
Thanks
Try this instead of the last while in your code:
if(combinedAgencyCds.size() <= 5) {
eSignConfig.setAgencyCd(combinedAgencyCds);
} else {
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, 5));
}
The full combined list will then be used if it is less than 5 in size. Otherwise, only the first 5 elements are used.
Edit: Or even better:
eSignConfig.setAgencyCd(combinedAgencyCds.subList(0, Math.min(5, combinedAgencyCds.size())));
Ok so let's break down what your code is currently doing.
int counter = 1;
while(combinedAgencyCds.size() < 5) {
counter = counter + 1;
eSignConfig.setAgencyCd(combinedAgencyCds);
}
This snippet of code has a couple things wrong best I can tell. First, this loop has the possibility of running forever or not at all. Because combinedAgencyCds is never being manipulated, the size won't ever change and the logic being checked in the while loop never does anything. Second, there's a more efficient loop for doing this, assuming you don't need the counter variable outside of its usage in the while loop and that is using for loops.
Example syntax is as follows:
for (int i = 0; i < combinedAgencyCds.size(); i++) {
if (i < 5) {
// Do your logic here.
}
else {
break; // Or handle extra values however you want.
}
}
Notice there is no need for the explicit declaration for a counter variable as "i" counts for you.
Now in your actual logic in the loop, I'm not sure what the setAgencyCd method does, but if it simply sets a list variable in the eSignConfig like it appears to, repeating it over and over isn't going to do anything. From what I can see in your code, you are setting a variable with the same value 5 times. If you need any more explanation just let me know and I will be happy to revise the answer.

Copying i value from arraylist to array

So I am making a program that needs to be overwrite value i from ArrayList to value i in array. For the life of me I cannot figure out what I should do. I've tried looking for similar problems here, but can't seem to find them. Obviously, my loop is very wrong as it is, as it is just overwriting the entire loop, but I can't figure it out. Any kind-hearted person want to help me?
BTW, I am using Java with Processing
Dot[] dots = new Dot[16];
ArrayList<Dot> extraDots = new ArrayList<Dot>();
Fill them with values and later ...
for (int i = 0; i < dots.length; ++i) {
if (dots[i].timeRemain == 0 && !dotTouch)
{
//arrayCopy(extraDots, i, dots, i, 1);
//this is basically what I want, but from an arraylist to the array
dots = extraDots.toArray(new Dot[i]); //So, so wrong, I know
dotTouch = true;
}
dotTouch = false;
You mean
dots[i] = extraDots.get(i);
???
i didn't get your problem..
simply you can do like below to copy from arraylist to array
why you are using dots[i].timeRemain and dotTouch. can you clarify??
for (int i = 0; i < dots.length; ++i) {
dots[i] = extraDots.get(i);
}

Why are variable not recognised from inside for-statements?

What I am trying to do is create an array that pulls even numbers from another array. I'm not sure if I have gone about it the right way. I've look for ways of returning from statements like you would functions/methods and I can't find anything, not even sure if it is possible.
Anyway, the issue I am having here is the 'return evenArray' below 'cannot find symbol.' I am not sure what this means?
public static int[] getEvenArray(int[] array)
{
int dividedBy = 2;
int evenElement;
int evenCount = 0;
for(int i = 0; i < array.length; i++)
{
int[] evenArray;
evenElement = array[i] % dividedBy;
if(evenElement == 0)
{
evenCount++;
}
else
{
array[i] = 0;
}
evenArray = new int[evenCount];
for(int x = 0; x < evenArray.length; x++)
{
if(array[i] != 0)
{
evenArray[x] = array[i];
}
}
}
return evenArray;
}
This is for a tutorial from one of my lectures, it's a little bit challenging to say the least :-)0
evenArray is defined within the scope of the for loop. (Actually a little worse than that; you're redeclaring it on each iteration so discarding the previous contents).
So once you're outside the for loop you can't refer to it.
Quickest fix is to use a std::vector<int> for this type, and declare it at the start of the function. Also change the return type of the function to the same. Don't forget to size the vector appropriately.
(Moving on, a smart lecturer will ask you about returning a std::vector which could potentially take a deep copy of that vector. Pre C++11 you'd mention return value optimisation, now you can talk about r-value references. No deep copy will be taken since the move constructor will be used).
Variable declared inside a block is not visible outside of it; move this int[] evenArray; to very start of function.

Index out of bounds exception in homework

I'm trying to do a homework assignment. I have to use dynamic programming to display whether the next person to move is in a win/loss state. I don't need help with the actual problem, I need help with an index out of bounds exception I'm getting that baffles me. I'm only going to paste part of my code here, because I only need the for loops looked at. I also don't want anyone in my class seeing all my code and copying it. If you need more data please let me know. So here is the code:
if(primeArray[x] == true){
for(int i = 1; i <= x; i++){
if(primeArray[i]== true){
newRowNumber = x - i;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
}
//COMPOSITE CASE FOR X!
else{
for(int k = 1; k <= x; k++){
if((primeArray[k] == false)){
newRowNumber = x - k;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
For some reason the if(primeArray[i] == true runs correctly, but I'm getting index out of bounds exception on if(primeArray[k] == false. The only difference between these two is the use of the variable k over i in the for loop.(the for loops are identical) I haven't used either variables anywhere else in my code. I have no idea why this occurs for one but not the other. In both cases, x remains the same number.
I am also getting an index out of bounds exception on the second minimum = dynaProgram[newRowNumber][columnNumber], while the first doesn't encounter an error. I know it's probably a stupid error, but I can't figure it out. If I change the 'k' for loop to k < x the index of out bounds exception in the if(primeArray[k] == false line goes away, but then it isn't correct. (The error on the second minimum = dynaProgram[newRowNumber][columnNumber] doesn't go away however.)
All this code is in a nested for loop which iterates through the rows and columns in the table to fill them in. If I remove the above code and just put dynaProgram[rowNumber][columnNumber] = 1 I don't have an issue, so I don't believe that is the problem.
When accessing an array of length 5 (for example)
int[] fred = new int[5];
the first element will be fred[0] and the last will be fred[4]
So when doing something like:
if(primeArray[i]== true){
Make sure that i is less than the array length. Using a value of i equal to the array length will throw an exception.

Categories