I have this assignment due within 40 minutes from now... I submit it to this online thing and it tests the methods etc and I'm getting this error. I know what out of bounds is, but I don't understand where it is occurring in the code it specifies:
public int countNeighbours(int x, int y) {
int neighbourCount = 0;
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells.length; j++) {
if ((cells[x][y].isAlive() == true) && (x < cells.length) && (y < cells.length) && (x >= 0)
&& (y >= 0)) {
neighbourCount++;
}
else if ((cells[x][y].isAlive() == false) && (x < cells.length) && (y < cells.length) && (x >= 0)
&& (y >= 0)) {
neighbourCount--;
}
else if (!(x < cells.length) || !(y < cells.length) || !(x >= 0) || !(y >= 0)) {
return 0;
}
else {
neighbourCount = neighbourCount;
}
}
}
return neighbourCount;
}
I don't know if it actually even works, I had a different code for this, but had issues with it.
Anyway, the online thing basically tests for an invalid coordinate and makes sure my code returns the correct value for an invalid coordinate (i.e. returns 0).
So I don't know why there is an out of bounds error, I feel like I have specified the bounds completely.
I also have a sub question, it also fails a test where the cell has 8 neighbours but my code returns -9. So obviously it's only going through the one which returns neighbourCount-- but I really don't understand why. Have I missed something in the specifications? Or perhaps it's related to a completely different part of my code.
Expressions are evaluated from left to right, so you should check the values of x and y are inside the valid range before accessing cell[x][y] :
if ((x < cells.length) && (y < cells.length) && (x >= 0)
&& (y >= 0) && (cells[x][y].isAlive() == true))
BTW, this test assumes that cells is a square matrix (i.e. it has the same number of columns and rows).
PS, it's unclear why you iterate over i and j and then don't use them at all inside your loops.
Related
Here's the code I have a question about:
package project;
import java.util.Scanner;
public class PostOffice {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("User input: ");
String input = sc.nextLine();
String[] determineinput = input.split(",");
String regular = "Regular Postcard";
String large = "Large Postcard";
String envelope = "Envelope";
String largeenvenlope = "Large Envelope";
String packagee = "Package";
String largepackage = "Large Package";
String unmailable = "Unmailable";
double height = Double.parseDouble(determineinput[0]);
double length = Double.parseDouble(determineinput[1]);
double thickness = Double.parseDouble(determineinput[2]);
if (3.5 < height && height < 4.25) {
if (3.5 < length && length < 6) {
if (0.007 < thickness && thickness < 0.016) {
System.out.println(regular);
}
}
} else if (4.25 < height && height < 6) {
if (6 < length && length < 11.5) {
if (0.007 < thickness && thickness < 0.016) {
System.out.println(large);
}
}
} else if (3.5 < height && height < 6.125) {
if (5 < length && length < 11.5) {
if (0.25 < thickness && thickness < 0.5) {
System.out.println(envelope);
}
}
} else if (6.125 < height && height < 24) {
if (11 < length && length < 18) {
if (0.25 < thickness && thickness < 0.5) {
System.out.println(largeenvenlope);
}
}
} else if (height < 6.125 || height > 24) {
if (length < 11 || length > 18) {
if (thickness < 0.25 || thickness > 0.5) {
if ((height * 2 + length * 2) <= 84) {
System.out.println(packagee);
}
}
}
} else if (height < 6.125 || height > 24) {
if (length < 11 || length > 18) {
if (thickness < 0.25 || thickness > 0.5) {
if ((height + length) > 84 && (height + length) < 130) {
System.out.println(largepackage);
}
}
}
}
if ((height < 3.5 || height > 24)
&& (thickness < 0.07 || thickness > 0.25)
&& (length < 3.5 || length > 18)) {
System.out.println(unmailable);
}
System.out.println("Input doesn't match any result");
}
}
When I run this particular code, I get this error:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at project.PostOffice.main(PostOffice.java:8)
What is wrong? I included the conditions to match the initialized variables and print that variable when the conditions return true. The system does print "User input:" but beneath it, the error pops up. I got rid of what could have become the problem but it doesn't change. I'm pretty sure I made the code pretty explicit and simple to read for the system but it keeps complaining. I see no other way of fixing this problem. Is it something with my for loops? Or is it something else?
(Apologies, this should really go in the comments but my reputation isn't yet high enough for me to do that).
I have tried running your code on IntelliJ and it seems to work for me (I used inputs of 4, 4, 4. Is your error coming up immediately after the User input line prints, or are you able to put in some figures first? If the latter, what is your input?
Not related to your problem, but something which may make your code easier to read: Where a variable name is made of multiple words, try using camel case (capitalise the first letter in each word apart from the first, e.g. largeevelope becomes largeEnvelope). I do like that you haven't used cryptically abbreviated names :)
I can't figure out what the difference is between the two if conditions. It seems the same to me.
Adding parentheses so that it is ((field[i][j] != -1) does not change anything either.
if (field[i][j] != -1 && i>=0 && i< numRows && j >= 0 && j < numCols){}
//wrong version
is NOT the same as
if (0 <= i && i < numRows && 0 <= j && j < numCols && field[i][j] != -1){}
//right version
if (field[i][j] != -1 && i>=0 && i< numRows && j >= 0 && j < numCols){} //wrong version
is NOT the same as
if (0 <= i && i < numRows && 0 <= j && j < numCols && field[i][j] != -1){} //right version
Without seeing additional code, it's hard to say. && short circuits (Short circuit evaluation) mean the code will stop running the instant something is false. In the right version, I am guessing one of the boolean checks is false before field[i][j] != -1 is ultimately reached. Likely, there is some sort of bounds exception happening there.
&& is lazy operator.
If the left side is evaluated as false, then there is no need to evaluate the right side because the result of the overall operation is already known.
It may lead to a difference between a && b and b && a.
Lets look at a && b. In this case b suffers a side effect (like throwing an exception as in your code). If a is evaluated to false, then b will not be evaluated at all.
I am new to my Intro to Java course and am struggling with a program. I have posted about this program before but this is a different question. My program is supposed to model a race between a hare and a tortoise. I think I have everything I need but I am having trouble with my JOptionPane phrase. I think my phrase is Ok, but I am experiencing problems with the while portion of my statement. Here is the error message: cannot find symbol - Variable OK.
I use Blue J to write and compile my program. Is there any reason why its not working? I thought the variable OK was the thing that the program user chooses to start the program. Am I mistaken? Can anyone help with this problem? Is there anything else you see in my program that needs fixing? Thanks
import java.util.Random;
import javax.swing.JOptionPane;
class Race
{
int [] race = new int[70];
int tortoise;
int hare;
Random randomGenerator = new Random();
public boolean again = true;
public void StartRace()
{
tortoise = 1;
hare = 1;
System.out.println("AND THEY'RE OFF!!!!");
while (tortoise < race.length && hare < race.length)
{
moveHare();
moveTortoise();
DisplayCurrentLocation();
String request;
}
if
(tortoise > hare)
{
System.out.println("\n TORTOISE WINS!!");
}
else if
(hare > tortoise)
{
System.out.println("\n HARE WINS!!!");
}
else if
(hare == tortoise)
{
System.out.println("TIE!!!");
}
}
public void moveTortoise()
{
int n = randomGenerator.nextInt(10) + 1;
//fast plod
if ( n > 0 && n< 6)
tortoise += 3;
//slip
else if (n > 10 && n< 11)
tortoise -= 6;
//slow plod
else if (n > 6 && n< 9)
++tortoise;
// protect from going past start
if (tortoise < 1)
tortoise = 1;
// to make sure game ends
else if (tortoise > 70)
tortoise = 70;
}// end tortoise
public void moveHare()
{
int m = randomGenerator.nextInt(10) + 1;
//big hop
if (m > 0 && m<3)
hare += 9;
//big slip
else if (m < 6)
hare -= 12;
// small hop
else if (m > 3 && m< 5)
++hare;
// )small slip
else if (m < 9)
hare -= 2;
else if (m < 11)
hare += 0;
//ensure hare doesn't go past start
if (hare < 1)
hare = 1;
// ensure hare doesnt go past end
else if (hare > 70)
hare = 70;
} // end movehare
public void DisplayCurrentLocation()
{
//this is the location of each on the array
for (int count = 1; count <= 70; count++)
// when at same location
if (count ==tortoise && count ==hare)
{
System.out.println("OUCH");
}
else if (count == hare)
{
System.out.println("H");
}
else if (count == tortoise)
{
System.out.println("T");
}
else
System.out.println();
}
public static void main ( String[] args)
{
Race Application = new Race();
int startRaceRequest;
while(startRaceRequest != JOptionPane.OK_OPTION)
{
JOptionPane.showConfirmDialog(null, "Select OK To Begin the Race!:");
}
do
{
Application.StartRace();
} while(startRaceRequest != JOptionPane.OK_OPTION);
}
}
To your question with the JOptionPane: I suggest you to use
JOptionPane.showConfirmDialog(null, "Message");
instead of
JOptionPane.showMessageDialog(null, "Message");
because it allows you to do this:
int startRaceRequest;
while(startRaceRequest != JOptionPane.OK_OPTION)
JOptionPane.showConfirmDialog(null, "Hit OK to start the race!");
I don't really understand what you mean by "Ok" later on in your code, but if you refer to the confirmed dialog, try using JOptionPane.OK_OPTION wich represents an int.
Also some help with your code: At the beginning you initialize the int[] race with the length of 70. Whenever you check if one of the racers is at or above 70, you do it like this
if(tortoise < 70 && hare < 70){}
wich is called hard-coding and you should try to avoid that as much as possible, to keep your code as dynamic as possible.
If you do this
if(tortoise < race.length && hare < race.length)
you don't have to rewrite half your code just because you changed the length of the race.
Another thing to the methods MoveTortoise and MoveHare. Conventionally the should be named moveTortoise and moveHare because method ins Java begin with lower case (that goes for all your methods!). Within those two methods inside your if conditions you write way too much code. for example this:
if (m == 1 || m == 2)
hare += 9;
else if (m == 6)
hare -= 12;
else if (m == 3 && m == 5) //there is something wrong here, m cant be 5 and 3 ;)
++hare;
else if (m == 7 || m == 8)
hare -= 2;
else if (m == 9 || m == 10)
hare += 0;
could be cut to this:
if(m > 0 && m < 3){ // if a number is > 0 and < 3 -> number is 1 or 2
} else if(m < 6){ // if a number is > 0 and > 3 -> if number is < 6 -> number could be 3, 4 or 5
} else if(m == 6){
} else if(m < 9){ // -> 7 or 8
} else if(m < 11){ // 9 or 10
}
In Addition, you use a random number generator and I think you are aiming for a number between 1 to 10, however this
int m = randomGenerator.nextInt(11);
will return a number from 0 to 10. Instead, try this:
int m = randomGenerator.nextInt(10) + 1;
wich will return a number from 0 to 9, adding one will result in a number between 1 and 10.
Hope this helps. Please remember to give feedback and mark a solution if your question was answered.
How does a statement like this execute?
int x = 2, y = 3;
if (x != 0) if (x < 10) if (y < 10) {
x++;
y++;
System.out.printf("X and Y are: %d, and %d", x, y);
}
If it could be compiled, it would get executed exactly like this:
if (x != 0)
if (x < 10)
if (y < 1o) {
x++;
y++;
System.out.println(x, y);
}
However, it's not very readable. You could improve its readability by using logical operators or proper line breaks and indentation.
Like this:
int x = 2, y = 3;
if ((x != 0) && (x < 10) && (y < 10))
{
x++;
y++;
System.out.println(x, y);
}
It operates like a Nested if. Why dont you check all condtion in the first if using a conditional AND. This way you would not need others.
However its a good practice to have braces for each if. This way its more readable and less error prone when the code undergoes changes in the future
if () if() if() is just short hand
what it is really doing is
if(x != 0){
if(x < 10){
if(y < 1o){
x++;
y++;
System.out.println(x, y);
}else{}
}else{}
}else{}
this is similar to
if (x != 0) {
if (x < 10) {
if (y < 10) {
x++;
y++;
System.out.println(x, y);
}
}
}
in an alternate way you can write
if((x != 0) && (x < 10) && (y < 10)) {
x++;
y++;
System.out.println(x, y);
}
Just use the && operator
int x = 2, y = 3;
if (x != 0 && x < 10 && y < 10) {
x++;
y++;
System.out.println(x, y);
}
It operates like a nested if as said by Andy. Instead of using this write all the conditions in one if statement and use && operator.
They're nested. Basically, the curly brace is optional for one line statement blocks. I assume y < 1o should be y < 10, also your println looks suspicious.
if (x != 0) {
if (x < 10) {
if (y < 10) {
x++;
y++;
// System.out.println(x, y);
System.out.println(Integer.toString(x) + " " + y);
}
}
}
You could certainly combine those into a single if (and even one line) with an and like
if (x != 0 && x < 10 && y < 10) {
System.out.printf("%d %d%n", x++, y++);
}
Using Java Logical Operators will resolve your problem.
Click this link to learn more
http://www.cafeaulait.org/course/week2/45.html
I have been looking over this flood fill implementation for some time now and keep running into the dreaded stack overflow. I am dropping pieces randomly on a 12x10 grid and calling the checkMatches method after each random piece drop to check for groups of three or more, hence the flood fill use.
EDIT: See comment
public void checkMatches(int x, int y, int type)
{
if (x < 0 || x >= PIECES_WIDE || y < 0 || y >= PIECES_TALL || type == 0)
return;
if (grid[x][y].getType() != type)
return;
int checkL = x;
while (checkL >= 0 && grid[checkL][y].getType() == type)
{
grid[checkL][y].setDestroy(true);
numMatches++;
checkL--;
}
checkL++;
int checkR = x;
while (checkR < PIECES_WIDE - 1 && grid[checkR][y].getType() == type)
{
grid[checkR][y].setDestroy(true);
numMatches++;
checkR++;
}
checkR--;
for (int i = checkL; i <= checkR; i++)
{
if (y > 0 && grid[i][y - 1].getType() == type)
checkMatches(i, y - 1, type);
if (y < PIECES_TALL - 1 && grid[i][y + 1].getType() == type)
checkMatches(i, y + 1, type);
}
}
Then the relevant code to call the method and destroy the pieces if there have been three matched pieces:
checkMatches(x, y, type);
if (numMatches >= 3)
{
for (int i = 0; i < PIECES_WIDE; i++)
{
for (int j = 0; j < PIECES_TALL; j++)
{
if (grid[i][j].isDestroy())
destroyPiece(grid[i][j]);
}
}
} else
{
numMatches = 0;
for (int i = 0; i < PIECES_WIDE; i++)
{
for (int j = 0; j < PIECES_TALL; j++)
{
grid[i][j].setDestroy(false);
}
}
}
My eyes and brain hurt. I know that the recursion is causing the overflow, but I also know that this implementation is possible in some form. Therefore I'm doing something wrong. Thanks in advance.
You need to put a mark on the pieces that you have already found matching. Then you can make a loop to extend your matchings, until you notice that no more pieces have been marked. Then you can stop.