Java - using logical OR in do while - java

I'm fairly new at this programming, so please do bear with me.
In teaching myself I'm attempting to write a Batteleships game; not OO at the moment, but rather procedural - little steps at a time.
I have a method to read the coordinates to fire at, these coordinates I want to then validate to make sure that, well, they're valid.
There is one method that checks that they are numbers and within the correct range, the other method is 'supposed' to check through what has already been entered.
The issue I'm finding is that I'm not breaking out of the do while loop to progress, the while bit is using logical OR on the two aforementioned methods. In writing these methods, they both do what they're supposed to do, well I'm not entirely sure about the method that checks whether a coordinate has already been fired at.
Some pointers would be really appreciated (on any aspect of it), thanks!
Code:
public static String inputCoords(List<String> coordsFired){
Scanner sc = new Scanner(System.in);
//Console c = System.console();
String coordsEntered;
do {
System.out.println("in do\\while");
System.out.println("Enter coordinates as 'x, y': ");
coordsEntered = sc.nextLine();
System.out.println("end of do\\while loop");
} while(!validateCoords(coordsEntered)
|| !coordsFiredAt(coordsEntered, coordsFired));
coordsFired.add(coordsEntered);
System.out.println("contents of List<String> coordsFired" + coordsFired);
return coordsEntered;
}
public static boolean validateCoords(String coordsEntered){
boolean results;
int x, y;
String strx = splitCoordsString(coordsEntered, 'x');
String stry = splitCoordsString(coordsEntered, 'y');
if (numericCheckCoordsFire(strx) && numericCheckCoordsFire(stry)) {
x = Integer.parseInt(strx);
y = Integer.parseInt(stry);
if (x > 25 || y > 25) {
results = false;
System.out.println("The dimensions of the board are 25 x 25, 'x,y' entered must be less than this. You entered '" + strx + "' for x and '" + stry + "' for y.");
} else {
results = true;
}
} else {
results = false;
System.out.println("Coords are supposed to be numbers... You entered '" + strx + "' for x and '" + stry + "' for y.");
}
System.out.println(results);
return results;
}
public static boolean coordsFiredAt(String coordsEntered, List<String> coordsFired) {
boolean results = false;
// go through each item in the list and compare against coordsEntered
for (String s : coordsFired) {
System.out.println("in for loop, printing iterated var" + s);
if (s.equals(coordsEntered)) {
// put these matched coordsFire into listHit
results = false;
} else {
System.out.println("already fired at " + coordsEntered);
results = true;
}
}
return results;
}

I propose you add OOP a little and create a class for Coords:
public class Coords {
private final int x;
private final int y;
public Coords(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
/**
* This method is used for Coords comparison
*/
#Override
public boolean equals(Object o) {
Coords coords = (Coords) o;
return y == coords.y && coords.x ==x;
}
/**
* This method is used to output coords.
*/
#Override
public String toString() {
return "(" + x + "," + y + ")";
}
}
So you code will look somethink like this:
public static Coords inputCoords(List<Coords> coordsFired) {
Scanner sc = new Scanner(System.in);
//Console c = System.console();
Coords coords;
do {
System.out.println("in do\\while");
System.out.println("Enter coordinates as 'x, y': ");
String coordsEntered = sc.nextLine();
coords = parseCoords(coordsEntered);
System.out.println("end of do\\while loop");
} while (coords == null || !areCoordsValid(coords) || !areCoordsNotFired(coords, coordsFired));
coordsFired.add(coords);
System.out.println("contents of List<String> coordsFired" + coordsFired);
return coords;
}
public static boolean areCoordsValid(Coords coords) {
boolean result = true;
if (coords.getX() > 25 || coords.getY() > 25) { // I think you also need to validate that it is possible values
result = false;
System.out.println("The dimensions of the board are 25 x 25, 'x,y' entered must be less than this. " +
"You entered '" + coords.getX() + "' for x and '" + coords.getY() + "' for y.");
}
return result;
}
public static boolean areCoordsNotFired(Coords coords, List<Coords> firedCoards) {
boolean result = true;
if (firedCoards.contains(coords)) {
result = false;
System.out.println("You already fired at " + coords.getX() + "," + coords.getY());
}
return result;
}
public static Coords parseCoords(String coordsEntered) {
Coords coords = null;
try {
String[] splittedCoords = coordsEntered.split(","); // Method splits values by comma. It should return an array of Strings with x value at the first element and y at the second one;
if (splittedCoords.length == 2) {
String x = splittedCoords[0].trim(); // Method removes all spaces at the beginning and ending of a passed String
String y = splittedCoords[1].trim();
coords = new Coords(Integer.parseInt(x), Integer.parseInt(y)); //Creates new instance of Coords class. x and y are passed as constructor params.
} else {
System.out.println("Format for coords is wrong. You entered '" + coordsEntered + "'.");
}
} catch (NumberFormatException e) { // Integer.parseInt throws an exception if the string does not contain parsable integer.
// We catch an exception and handle it by writing a message
System.out.println("Coords are supposed to be numbers... You entered '" + coordsEntered + "'.");
}
return coords;
}
Also Set is more applicable in this case. Set contains no duplicate elements and Set.contains() method works faster then List.contains(). But if you want to use Set you should implement both equals() and hashCode() methods.

You want to loop if the coords are invalid or already fired.
So shouldn't the while condition be:
while(!validateCoords(coordsEntered)
|| coordsFiredAt(coordsEntered, coordsFired))

Related

How do I make a class to dynamic check different objects variable?

I'm new to Java, and i'm trying to create an automatic working shift schedule.
I want the code to mix four different employees to handle a morning shift and afternoon shift every work day.
I have made some code that just pick a random employee into a shift:
import java.util.Arrays;
import java.util.Random;
public class CreateNewShift {
public static void main(String[] args) {
int startWeek = 30; //Which week would start from?
int endWeek = 32; //which week will you end on?
generateShift(startWeek, endWeek);
}
private static void generateShift(int startWeek, int endWeek) {
String Employees[] = {"Employee1", "Employee2", "Employee3", "Employee4"};
String morningShift;
String afternoonShift;
for (int x = 0; x <= (endWeek - startWeek); x++) { //This is counting the number of weeks
System.out.println("\nWeek: " + (startWeek+x));
for (int i = 1; i <= 5; i++) { //this is finding the next working shift day
morningShift = p.chooseRandomEmployee(Employees);
afternoonShift = p.chooseRandomEmployee(Employees);
if (i == 1) {
System.out.println("Mon: " + morningShift + " + " + afternoonShift);
}
else if (i == 2) {
System.out.println("Tue: " + morningShift + " + " + afternoonShift);
}
else if (i == 3) {
System.out.println("Wed: " + morningShift + " + " + afternoonShift);
}
else if (i == 4) {
System.out.println("Thu: " + morningShift + " + " + afternoonShift);
}
else {
System.out.println("Fri: " + morningShift + " + " + afternoonShift);
}
}
}
}
public class Employee {
public String chooseRandomEmployee(String[] Employees) {
Random r = new Random();
int randomNumber = r.nextInt(Employees.length);
return Employees[randomNumber];
}
}
However, I now want the code to handle more restictions.
So i'm currently trying to add the option for the employees to choose some specific days that they dont want to have a shift. I have done this by adding this code to the Employee class:
public class Employee {
boolean monShift = true;
boolean tueShift = true;
boolean wedShift = true;
boolean thuShift = true;
boolean friShift = true;
public String chooseRandomEmployee(String[] Employees) {
Random r = new Random();
int randomNumber = r.nextInt(Employees.length);
return Employees[randomNumber];
}
}
And then i had tried to create new objects in my main class:
private static void generateShift(int startWeek, int endWeek) {
Employee Employee1 = new Employee("Employee1");
Employee Employee2 = new Employee("Employee2");
Employee Employee3 = new Employee("Employee3");
Employee Employee4 = new Employee("Employee4");
String Employees[] = {"Employee1", "Employee2", "Employee3", "Employee4"};
String morningShift;
String afternoonShift;
....
Quetions:
How can I improve my code in the Employee class to do a check if the random chosen employee have
monShift = true;
I have tried something like this, but i know it will not work, (and does not work either):
import java.util.Random;
public class Employee {
public String chooseRandomEmployee(String[] Employees) {
Random r = new Random();
int randomNumber = r.nextInt(Employees.length);
**if (("Employee" + randomNumber).monShift == false) {**
// Go back and try find a new random employee
}
else {
return Employees[randomNumber];
}
}
}
So i need a way to make my code dynamic to know which object (employee) it has to check if they are available that specific day or not.
Feel free to ask for a deepening if my question is not clear.
Since this i my first question on this forum, I also appriciate feedback if my question and thoughts are too long, or any other comments.
I dont think that putting the chooseRandomEmployee() function inside the Employee object is a good idea beacuse is not a part of the employee, is not an "action" of it. I think you shiudl put it outside but I want to respect your decision so shoudl check the do while loop.
import java.util.Random;
public class Employee {
public String chooseRandomEmployee(String[] Employees) {
int randomNumber;
do {
//Generate a new random number
Random r = new Random();
randomNumber = r.nextInt(Employees.length);
//The line under is the same that saying "If monSift == false return to
//the beginning and start again generating a new number"
} while ("Employee" + randomNumber).monShift == false);
return Employees[randomNumber];
}
}

Getting error while trying to implement Recursion with arrays

Im working on a school project where I have to implement recursion with arrays and I have done everything but im getting a null error when I am running it. The error points to the Recursion class on Line:
result += packetList[n].idNumber + " " + packetList[n].weight + " " + packetList[n].Destination;
I tried tracing the recursion method to see if it would actually make sense and its looks solid but i'm still getting a null error.
Recursion Class:
import java.io.*;
public class Recursion
{
public String toString(Packet[] packetList, int n)
{
String result = "";
if (n < 0)
{
return result;
}
result += packetList[n].idNumber + " " + packetList[n].weight + " " + packetList[n].Destination; // Uncomment if you want the values from last-to-first (last index to 0 index)
result += toString(packetList, n-1);
//result += packetList[n].idNumber + " " + packetList[n].weight + " " + packetList[n].Destination; // Uncomment if you want the values from first-to-last (0 index to last index)
return result;
}
}
Packet Class
public class Packet
{
public int idNumber;
public double weight;
public String Destination;
public Packet(int id, double w, String D)
{
idNumber = id;
weight = w;
Destination = D;
}
public boolean isHeavy()
{
if (weight > 10)
return true;
else
return false;
}
public String toString()
{
return idNumber + " " + weight + " " + Destination;
}
public double getWeight()
{
return weight;
}
public String getDestination()
{
return Destination;
}
}
Test Class
import java.io.*;
import java.util.*;
import java.util.Scanner;
public class TestPackages
{
public static void main (String[] args) throws IOException
{
Packet[] packetList = new Packet[100];
int idNumber;
double weight;
String Destination;
Scanner fileInput;
fileInput = new Scanner (new File("packetData.txt"));
int counter = 0;
while (fileInput.hasNextLine())
{
idNumber = fileInput.nextInt();
weight = fileInput.nextDouble();
Destination = fileInput.nextLine();
Packet myPacket = new Packet (idNumber, weight, Destination);
packetList[counter++] = myPacket;
}
Recursion recursion = new Recursion();
System.out.println(recursion.toString(packetList, packetList.length - 1));
recursion.displayHeavyPackages(packetList, packetList.length - 1);
recursion.displayPacketsToDest(packetList, packetList.length - 1, "CT");
recursion.countPacketsToDest(packetList, packetList.length - 1, "CT");
}
}
It looks like you are sending the length of the array to your toString() function, but it might not have the 100 elements initialized, try sending your ´counter´ instead :
System.out.println(recursion.toString(packetList, counter-1))
Please verify that packetData.txt has exactly 100 lines otherwise the program will throw a null pointer Exception.
The displayHeavyPackage method should validate if n==0 to avoid Array Index Out Bound exception
displayHeavyPackage
public void displayHeavyPackages(Packet[] packetList, int n) {
if (packetList[n].isHeavy() == true && n>0) {
System.out.println(packetList[n]); displayHeavyPackages(packetList, n-1);
} else if (packetList[n].isHeavy() == true && n==0){
System.out.println(packetList[n]);
}
}
My final suggestion is try to debug your code, it will help a lot to clarify the root cause of the exceptions.

Java array of queues printing out only last element within for loop in print method

I spent several hours working on this and even had my professor look at this and it seems to be printing out just the last element in the for loop. It seems to allows me to add the data structure information and initialize the array queue but it only print out the last element. Here is the sufficient code to assist with the question.
static int MAX;
static final int amount = 6;
static boolean [] openflag;
static queue [] Clinic;
static String [] Doctor;
final static String HEADING = "The clinic moniter of Dylan Rychlik";
public static void Listpaitents( ) {
Paitent[] array;
int queuechoice;
JOptionPane.showMessageDialog(null, "Which doctor would you like to
print?");
String InputString = JOptionPane.showInputDialog(null,Doctor, HEADING,
JOptionPane.QUESTION_MESSAGE);
queuechoice = Integer.parseInt(InputString);
if (openflag[queuechoice -1 ] == false){
JOptionPane.showMessageDialog(null, "Sorry, that doctor is not aviable");
}
else {
//Paitent[] array = null;
int limit;
limit = Clinic[queuechoice -1 ].getSize();
array = Clinic[queuechoice -1 ].toArray();
System.out.println(array[0]);
System.out.println(array[1].Print());
System.out.println(array[2].Print());
//int size = Clinic[queuechoice -1].getSize();
//System.out.println(limit);
int x; String out = " Members of the list are: \n";
// boolean exit = false;
for(x = 0; x < limit; x++) {
out += array[x].Print() + "\n";
//System.out.println(out);
// System.out.println(Clinic[queuechoice].toString() + "\n");
}
System.out.println(limit);
JOptionPane.showMessageDialog(null,out);
}
}
Here this is the array() method in the queue clas
public Paitent[] toArray() {
int x;
Paitent[] Array = new Paitent[Length];
queuenode Current = rear;
for (x = 1; ((Current != null) && (x <= Length));x++) {
Array[x-1] = new Paitent();
Array[x-1].update(Current.info);
Current = Current.next;
// System.out.println( Array[x-1].Print());
}
//System.out.println( Array[x-1].Print());
return Array;
}
Any finally here this is the print method
public String Print() {
String outputString;
outputString = "Paitent: " + "-" + name + "\n" + " Telephone number
telephone + " ID " + ID;
return outputString;
}
Any help you can give is really appreciated. I really have spent hours analyzing the code to come up a solution. Its a bulky program.

How do I change the value of a boolean within a method - Java?

I read in a book that when you change the value of a method parameter that's a boolean or other basic datatype within the method it only is changed within the method and remains the same outside. I want to know if there is some way for me to actually change it within the method. For example:
public class Change {
void convert(boolean x, boolean y, boolean z) { //i want to set x,y, and z to false in this
x = false;
y = false;
z = false;
}
}
//Now in my main class:
public static void main(String[] args) {
boolean part1 = true;
boolean part2 = true;
boolean part3 = true;
System.out.println(part1 + " " + part2 + " " + part3);
Change myChange = new Change();
myChange.convert(part1,part2,part3);
System.out.println(part1 + " " + part2 + " " + part3);
}
EDIT1: These answers were good but not quite what i want to acheive. I want to put in part1, part2, and part3 when i call the method than i want them to be set to false within the method. The specific reason i asked this question was because im trying to code a battleship and i have a subroutine class with a method that when its called it checks if a ship has been sunk. If the there was a sink than the method will set a ton of boolean variables to false.
EDIT2: Just to clarify, I want something like this:
void convert(thing1,thing2,thing3,thing4) {
//some code here that sets thing1,thing2,thing3, and thing4 to false
}
// than in main:
boolean test1 = true;
boolean test2 = true;
boolean test3 = true;
boolean test4 = true;
convert(test1,test2,test3,test4);
System.out.println(test1 + " " + test2 + "....");
//and that should print out false, false, false, false
You can do it with this methodology
// these are called instance variables
private boolean x = false;
private boolean y = false;
private boolean z = false;
// this is a setter
public static void changeBool(boolean x, boolean y, boolean z) {
this.x = x;
this.y = y;
this.z = z;
}
Call the method like this
changeBool(true, true, false);
The values for x, y, and z are now changed.
This is a common problem in Java - pass-by-value vs. pass-by-reference. Java is always pass-by-value, where you're thinking of it as pass-by-reference.
Like #Rafael has said, you need to use instance variables to do what you want. I've gone a bit further and edited your source code to do what you want:
public class Change {
boolean part1;
boolean part2;
boolean part3;
Change(boolean x, boolean y, boolean z) {
part1 = x;
part2 = y;
part3 = z;
}
void convert(boolean x, boolean y, boolean z) { //this now sets the class variables to whatever you pass into the method
part1 = x;
part2 = y;
part3 = z;
}
// Now in my main class:
public static void main(String[] args) {
Change myChange = new Change(true, true, true);
System.out.println(myChange.part1 + " " + myChange.part2 + " "
+ myChange.part3);
myChange.convert(false, false, false);
System.out.println(myChange.part1 + " " + myChange.part2 + " "
+ myChange.part3);
}
}

Infinite while loop in java, not reading in sentinel

I've had this problem throughout multiple programs, but I can't remember how I fixed it last time. In the second while loop in my body, the second sentinel value is never read in for some reason. I've been trying to fix it for a while now, thought I might see if anyone had any clue.
import java.text.DecimalFormat; // imports the decimal format
public class Car {
// Makes three instance variables.
private String make;
private int year;
private double price;
// Makes the an object that formats doubles.
public static DecimalFormat twoDecPl = new DecimalFormat("$0.00");
// Constructor that assigns the instance variables
// to the values that the user made.
public Car(String carMake,int carYear, double carPrice)
{
make = carMake;
year = carYear;
price = carPrice;
}
// Retrieves variable make.
public String getMake()
{
return make;
}
// Retrieves variable year.
public int getYear()
{
return year;
}
// Retrieves variable price.
public double getPrice()
{
return price;
}
// Checks if two objects are equal.
public boolean equals(Car c1, Car c2)
{
boolean b = false;
if(c1.getMake().equals(c2.getMake()) && c1.getPrice() == c2.getPrice() &&
c1.getYear() == c2.getYear())
{
b = true;
return b;
}
else
{
return b;
}
}
// Turns the object into a readable string.
public String toString()
{
return "Description of car:" +
"\n Make : " + make +
"\n Year : " + year +
"\n Price: " + twoDecPl.format(price);
}
}
import java.util.Scanner; // imports a scanner
public class CarSearch {
public static void main(String[] args)
{
// initializes all variables
Scanner scan = new Scanner(System.in);
final int SIZE_ARR = 30;
Car[] carArr = new Car[SIZE_ARR];
final String SENT = "EndDatabase";
String carMake = "";
int carYear = 0;
double carPrice = 0;
int count = 0;
int pos = 0;
final String SECSENT = "EndSearchKeys";
final boolean DEBUG_SW = true;
// Loop that goes through the first list of values.
// It then stores the values in an array, then uses the
// values to make an object.
while(scan.hasNext())
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car car1 = new Car(carMake, carYear, carPrice);
carArr[count] = car1;
count++;
}
// Calls the method debugSwitch to show the debug information.
debugSwitch(carArr, DEBUG_SW, count);
// Calls the method printData to print the database.
printData(carArr, count);
// Loops through the second group of values and stores them in key.
// Then, it searches for a match in the database.
**while(scan.hasNext())**
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SECSENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car key = new Car(carMake, carYear, carPrice);
// Stores the output of seqSearch in pos.
// If the debug switch is on, then it prints these statements.
if(DEBUG_SW == true)
{
System.out.println("Search, make = " + key.getMake());
System.out.println("Search, year = " + key.getYear());
System.out.println("Search, price = " + key.getPrice());
}
System.out.println("key =");
System.out.println(key);
pos = seqSearch(carArr, count, key);
if(pos != -1)
{
System.out.println("This vehicle was found at index = " + pos);
}
else
{
System.out.println("This vehicle was not found in the database.");
}
}
}
// This method prints the database of cars.
private static void printData(Car[] carArr, int count)
{
for(int i = 0; i < count; i++)
{
System.out.println("Description of car:");
System.out.println(carArr[i]);
}
}
// Searches for a match in the database.
private static int seqSearch(Car[] carArr, int count, Car key)
{
for(int i = 0; i < count; i++)
{
boolean b = key.equals(key, carArr[i]);
if(b == true)
{
return i;
}
}
return -1;
}
// Prints debug statements if DEBUG_SW is set to true.
public static void debugSwitch(Car[] carArr, boolean DEBUG_SW, int count)
{
if(DEBUG_SW == true)
{
for(int i = 0; i < count; i++)
{
System.out.println("DB make = " + carArr[i].getMake());
System.out.println("DB year = " + carArr[i].getYear());
System.out.println("DB price = " + carArr[i].getPrice());
}
}
}
}
I think this is your problem, but I might be wrong:
Inside your while loop, you have these calls:
next()
nextInt()
nextDouble()
The problem is that the last call (nextDouble), will not eat the newline. So to fix this issue, you should add an extra nextLine() call at the end of the two loops.
What happens is that the next time you call next(), it will return the newline, instead of the CarMake-thing.

Categories