Why does this continue to ask for strings? - java

I am working on a program that is supposed to help students study the presidents. I am using a stack. It is supposed to ask for user input and then it compares the input to the top of the stack. If it is correct it removes the top item. otherwise it asks for the next president. When I get to the end it asks again for the next president even though the stack should be empty.
Here is my main program.
package namepresidents;
import java.util.Scanner;
public class NamePresidents
{
//=========================MAIN=============================================
public static void main(String[] args)
{
UnboundedStackInterface<String> presidents;
presidents = new LinkedStack<String>();
presidents.push("George Washington");
presidents.push("John Adams");
presidents.push("Thomas Jefferson");
presidents.push("James Madison");
presidents.push("James Monroe");
presidents.push("John Quincy Adams");
presidents.push("Andrew Jackson");
presidents.push("Martin Van Buren");
presidents.push("James Madison");
presidents.push("William Henry Harrison");
presidents.push("John Tyler");
presidents.push("James K Polk");
presidents.push("Zachary Taylor");
presidents.push("James Madison");
presidents.push("Millard Fillmore");
presidents.push("Franklin Pierce");
presidents.push("James Buchanan");
presidents.push("Abraham Lincoln");
presidents.push("Andrew Johnson");
presidents.push("Ulysses S Grant");
presidents.push("Rutherford B. Hayes");
presidents.push("James A Garfield");
presidents.push("Chester A Arthur ");
presidents.push("Grover Cleveland");
presidents.push("Benjamin Harrison");
presidents.push("Grover Cleveland");
presidents.push("William McKinley");
presidents.push("William H Taft");
presidents.push("Woodrow Wilson");
presidents.push("Warren G Harding");
presidents.push("Calvin Coolidge");
presidents.push("Herbert Hoover");
presidents.push("Franklin D Roosevelt");
presidents.push("Harry S Truman");
presidents.push("Dwight D Eisenhower");
presidents.push("John F Kennedy");
presidents.push("Lyndon B Johnson");
presidents.push("Richard M Nixon");
presidents.push("Gerald R Ford");
presidents.push("Jimmy Carter");
presidents.push("Ronald Reagan");
presidents.push("George Bush");
presidents.push("Bill Clinton");
presidents.push("George W Bush");
presidents.push("Barack Obama");
UnboundedStackInterface<String> wrongAnswer;
wrongAnswer = new LinkedStack<String>();
String menu = "Would you like to study: \n"
+ "1. All the presidents \n"
+ "2. The first half \n"
+ "3. The second half \n"
+ "4. In reverse \n"
+ "0. Exit \n";
System.out.print(menu);
Scanner in = new Scanner(System.in);
int option = in.nextInt();
String studentPresidents = in.nextLine();
switch(option)
{
case 1:
do
{
System.out.print("Enter the next president: ");
studentPresidents = in.nextLine();
if(studentPresidents.equalsIgnoreCase(presidents.top()))
{
presidents.pop();
}
else
{
wrongAnswer.push(studentPresidents);
System.out.println("That is not correct. Try Again!");
}
}while(!presidents.isEmpty());
do
{
System.out.print("You missed: \n" + wrongAnswer.top());
wrongAnswer.pop();
}while(!wrongAnswer.isEmpty());
break;
case 2: UnboundedStackInterface<String> firstHalf;
firstHalf = new LinkedStack<String>();
firstHalf.push("George Washington");
firstHalf.push("John Adams");
firstHalf.push("Thomas Jefferson");
firstHalf.push("James Madison");
firstHalf.push("James Monroe");
firstHalf.push("John Quincy Adams");
firstHalf.push("Andrew Jackson");
firstHalf.push("Martin Van Buren");
firstHalf.push("James Madison");
firstHalf.push("William Henry Harrison");
firstHalf.push("John Tyler");
firstHalf.push("James K Polk");
firstHalf.push("Zachary Taylor");
firstHalf.push("James Madison");
firstHalf.push("Millard Fillmore");
firstHalf.push("Franklin Pierce");
firstHalf.push("James Buchanan");
firstHalf.push("Abraham Lincoln");
firstHalf.push("Andrew Johnson");
firstHalf.push("Ulysses S Grant");
firstHalf.push("Rutherford B Hayes");
firstHalf.push("James A Garfield");
do
{
System.out.print("Enter the next president: ");
studentPresidents = in.nextLine();
if(studentPresidents.equalsIgnoreCase(firstHalf.top()))
{
firstHalf.pop();
}
else
{
wrongAnswer.push(studentPresidents);
System.out.println("That is not correct. Try Again!");
}
}while(!presidents.isEmpty());
do
{
System.out.print("You missed: \n" + wrongAnswer.top());
wrongAnswer.pop();
}while(!wrongAnswer.isEmpty());
break;
case 3: UnboundedStackInterface<String> lastHalf;
lastHalf = new LinkedStack<String>();
lastHalf.push("Chester A Arthur");
lastHalf.push("Grover Cleveland");
lastHalf.push("Benjamin Harrison");
lastHalf.push("Grover Cleveland");
lastHalf.push("William McKinley");
lastHalf.push("William H Taft");
lastHalf.push("Woodrow Wilson");
lastHalf.push("Warren G Harding");
lastHalf.push("Calvin Coolidge");
lastHalf.push("Herbert Hoover");
lastHalf.push("Franklin D Roosevelt");
lastHalf.push("Harry S Truman");
lastHalf.push("Dwight D Eisenhower");
lastHalf.push("John F Kennedy");
lastHalf.push("Lyndon B Johnson");
lastHalf.push("Richard M Nixon");
lastHalf.push("Gerald R Ford");
lastHalf.push("Jimmy Carter");
lastHalf.push("Ronald Reagan");
lastHalf.push("George Bush");
lastHalf.push("Bill Clinton");
lastHalf.push("George W Bush");
lastHalf.push("Barack Obama");
do
{
System.out.print("Enter the next president: ");
studentPresidents = in.nextLine();
if(studentPresidents.equalsIgnoreCase(lastHalf.top()))
{
lastHalf.pop();
}
else
{
wrongAnswer.push(studentPresidents);
System.out.println("That is not correct. Try Again!");
}
} while(!presidents.isEmpty());
do
{
System.out.print("You missed: \n" + wrongAnswer.top());
wrongAnswer.pop();
}while(!wrongAnswer.isEmpty());
break;
case 4: UnboundedStackInterface<String> reversePres;
reversePres = new LinkedStack<String>();
do
{
reversePres.push(presidents.top());
presidents.pop();
}while(!presidents.isEmpty());
do
{
System.out.print("Enter the next president: ");
studentPresidents = in.nextLine();
if(studentPresidents.equalsIgnoreCase(reversePres.top()))
{
reversePres.pop();
}
else
{
wrongAnswer.push(studentPresidents);
System.out.println("That is not correct. Try Again!");
}
}while(!reversePres.isEmpty());
do
{
System.out.print("You missed: \n" + wrongAnswer.top());
wrongAnswer.pop();
}while(!wrongAnswer.isEmpty());
break;
case 0: System.out.println("Exit!");
break;
default: break;
}
}
}
Here is my LinkedStack class
package namepresidents;
public class LinkedStack<T> implements
UnboundedStackInterface<T>
{
protected LLNode<T> top;
//=================================constructor==============================
public LinkedStack()
{
top = null;
}
//===================================push===================================
public void push(T element)
{
LLNode<T> newNode = new LLNode<>(element);
newNode.setLink(top);
top = newNode;
}
//====================================pop===================================
public void pop()
{
if (!isEmpty())
{
top = top.getLink();
}
else
{
throw new StackUnderflowException("Pop"
+ "Attempted on empty stack.");
}
}
//=====================================top==================================
public T top()
{
if (!isEmpty())
{
return top.getInfo();
}
else
{
throw new StackUnderflowException("top"
+ "Attempted on empty stack.");
}
}
//======================================isEmpty=============================
public boolean isEmpty()
{
if (top == null)
{
return true;
}
else
{
return false;
}
}
}
Here is my LLNODE class
package namepresidents;
public class LLNode<T>
{
private T info;
private LLNode<T> link;
public LLNode(T info)
{
this.info = info;
link = null;
}
public void setInfo(T info)
{
this.info = info;
}
public T getInfo()
{
return info;
}
public void setLink(LLNode<T> link)
{
this.link = link;
}
public LLNode<T> getLink()
{
return link;
}
}

You have a mistake in options 2 and 3. Look at this reduced loop code:
do
{
if(studentPresidents.equalsIgnoreCase(firstHalf.top()))
{
firstHalf.pop(); // pops firstHalf
}
}while(!presidents.isEmpty()); // tests presidents
This is why copy and paste programming is bad. It is prone to errors.

For cases 2 and 3 your while() test should be checking the half lists, rather than presidents list.

Related

purchase management program that shows error on specific inputs in java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
Improve this question
The code works on a linkedlist principle, and has worked alright thus far, however the code outputs an error when input is add, 1, a, 10, 5, add, 1, b, 2, 2, add, 2, b, 2, 1, inc, 2, b, print, done
the code:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;
class Prece {
private String nosaukums;
private double cena;
private int daudzums;
public Prece(String n, double c, int d) {
nosaukums = n;
cena = c;
daudzums = d;
}
public String getNosaukums() {
return nosaukums;
}
public double getCena() {
return cena;
}
public int getDaudzums() {
return daudzums;
}
public void setDaudzums(int d) {
daudzums = d;
}
public static Prece inputPrece(Scanner sc) {
String n = sc.next();
double c = sc.nextDouble();
int d = sc.nextInt();
return new Prece(n, c, d);
}
public void outputPrece() {
System.out.printf("%-20s%-10.2f%-10d\n", nosaukums, cena, daudzums);
}
}
public class Main {
public static Scanner sc;
public static void main(String[] args) {
HashMap<String, LinkedList<Prece>> pasutijumi = new HashMap<String, LinkedList<Prece>>();
sc = new Scanner(System.in);
String cmd = "";
while (!cmd.equals("done")) {
cmd = sc.next();
switch (cmd) {
case "add":
add(pasutijumi);
break;
case "print":
print(pasutijumi);
break;
case "sum":
sum(pasutijumi);
break;
case "inc":
inc(pasutijumi);
break;
case "del":
delete(pasutijumi);
break;
case "done":
System.out.println("good bye");
break;
default:
System.out.println("unknown command");
break;
}
}
sc.close();
}
public static void print(HashMap<String, LinkedList<Prece>> pasutijumi) {
LinkedList<Prece> grozs;
for (String id : pasutijumi.keySet()) {
System.out.println("ID: " + id);
grozs = pasutijumi.get(id);
String str = String.format("%-20s%-10s%-10s", "nosaukums", "cena", "daudzums");
System.out.println(str);
for (Prece prece : grozs) {
prece.outputPrece();
}
}
}
public static void inc(HashMap<String, LinkedList<Prece>> pasutijumi) {
String id = sc.next();
String productName = sc.next();
double amount = sc.nextDouble();
LinkedList<Prece> grozs = pasutijumi.get(id);
if (grozs == null) {
System.out.println("unknown client");
} else {
boolean productFound = false;
for (Prece prece : grozs) {
if (prece.getNosaukums().equals(productName)) {
prece.setDaudzums(prece.getDaudzums() + (int) amount);
productFound = true;
break;
}
}
if (!productFound) {
System.out.println("not found");
}
}
}
public static void add(HashMap<String, LinkedList<Prece>> pasutijumi) {
LinkedList<Prece> grozs;
String id = sc.next();
Prece p = Prece.inputPrece(sc);
grozs = pasutijumi.get(id);
if (grozs != null) {
grozs.add(p);
} else {
grozs = new LinkedList<Prece>();
grozs.add(p);
pasutijumi.put(id, grozs);
}
}
public static void sum(HashMap<String, LinkedList<Prece>> pasutijumi) {
for (String id : pasutijumi.keySet()) {
LinkedList<Prece> grozs = pasutijumi.get(id);
if (grozs != null) {
double sum = 0.0;
for (Prece prece : grozs) {
sum += prece.getCena() * prece.getDaudzums();
}
System.out.println("ID: " + id + " sum: " + sum);
} else {
System.out.println("unknown client");
}
}
}
public static void delete(HashMap<String, LinkedList<Prece>> pasutijumi) {
String id = sc.next();
String nosaukums = sc.next();
LinkedList<Prece> grozs = pasutijumi.get(id);
if (grozs != null) {
int index = -1;
for (int i = 0; i < grozs.size(); i++) {
if (grozs.get(i).getNosaukums().equals(nosaukums)) {
index = i;
break;
}
}
if (index >= 0) {
Prece prece = grozs.remove(index);
System.out.println("Prece " + prece.getNosaukums() + " noņemta no klienta ar ID " + id + " pasūtījuma");
} else {
System.out.println("Prece " + nosaukums + " nav atrasta klienta ar ID " + id + " pasūtījumā");
}
} else {
System.out.println("Klienta ID " + id + " nav atrasts");
}
}
}
Sorry that the code is in latvian.
I have tried changing the list types and tried bug fixing however it still shows an error.

Error message when I attach a textfile to my code

I need to create program to offer the user the ability to produce the report as show about in alphabetical order by
township name or in size order by township square mile.
But I get error message when I run the text file with the code.
Without the text file, my code works, but when I try to use the text file with the code, I get this error.
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:678)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at Main.main(Mice.java:76)
My code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
// create mice class
class Mice {
private final double micepopulation;
private final int sizetown;
private final String town;
// =-=-=-=-=-=-=-=-=--==-=
public Mice(double population, int sizetown, String town) {
this.town = town;
this.micepopulation = population;
this.sizetown = sizetown;
}
// --==--=-=-=-=-=-=-=-=-=--=
public String miceelseif() {
if (micepopulation > 75) {
return "Blue";
} else if (micepopulation > 65) {
return "Green";
} else if (micepopulation > 50) {
return "Yellow";
} else if (micepopulation > 35) {
return "Orange";
} else {
return "Red";
}
// -=-=-=-=-=-=-=-=-=-=-=-=-
}
public String getTOWN() {
return town;
}
public String toString() {
return String.format("%-25s%-20.2f%-20d%-20s", town, micepopulation, sizetown, miceelseif());
}
}
public class Main {
public static void main(String[] args) {
int numRecords = getNumRecords();
String[] township = new String[numRecords];
double[] population = new double[numRecords];
int[] townsize = new int[numRecords];
try {
Scanner fileScanner = new Scanner(new File("Micepopulation.txt"));
int index = 0;
while (fileScanner.hasNextLine()) {
township[index] = fileScanner.nextLine();
String[] popTwonSizeContents = fileScanner.nextLine().trim().split("");
population[index] = Double.parseDouble(popTwonSizeContents[0]);
townsize[index] = Integer.parseInt(popTwonSizeContents[1]);
// increment the index
index++;
}
fileScanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Mice[] micePop = new Mice[numRecords];
for (int index = 0; index < micePop.length; index++) {
micePop[index] = new Mice(population[index], townsize[index], township[index]);
}
Scanner scanner = new Scanner(System.in);
int choice;
do {
System.out.println("1: Mice by Town");
System.out.println("2: Mice by size");
System.out.println("3- Town name");
System.out.println("0- Exit");
System.out.print(" Please enter your choice: ");
choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 0 -> System.out.println("thank you, have a good day");
case 1, 2 -> bytown(micePop);
case 3 -> {
System.out.print("please enter town ");
String town = scanner.nextLine();
int foundIndex = townLookUp(micePop, town);
if (foundIndex == -1) {
System.out.println("no town");
} else {
System.out.printf("%-25s%-20s%-20s%-20s\n", "Town", "Mice Population", "Town Size",
"Alerts");
System.out.println(micePop[foundIndex].toString());
}
}
default -> System.out.println("Invalid choice");
}
System.out.println();
} while (choice != 0);
scanner.close();
}
// ==-=-=-===--==-=-=-=-=-=-=-=-=-=--==-
private static void bytown(Mice[] micePop) {
for (int index = 0; index < micePop.length; index++) {
for (int innerIndex = 0; innerIndex < micePop.length - index - 1; innerIndex++) {
if (micePop[innerIndex].getTOWN().compareTo(micePop[innerIndex + 1].getTOWN()) > 0) {
Mice temp = micePop[innerIndex];
micePop[innerIndex] = micePop[innerIndex + 1];
micePop[innerIndex + 1] = temp;
}
}
}
System.out.println("\nREPORT BY TOWN");
printMicePopulation(micePop);
}
// -=-===-=-=-=--==-=-=--==-=-
// =-=--=-==-=-=-=--==-=-=-=-=-=-=--==-=-=--
private static int townLookUp(Mice[] micePop, String township) {
for (int index = 0; index < micePop.length; index++) {
if (micePop[index].getTOWN().equalsIgnoreCase(township)) {
return index;
}
}
return -1;
}
// -=-==-=-=-=--==--==-=-==-=-=-=-=-=-=--==-=-=-----=
private static void printMicePopulation(Mice[] micePop) {
System.out.printf("%-25s%-20s%-20s%-20s\n", "Town", "Mice Population", "Town Size", "Threat Alert");
for (Mice mice : micePop) System.out.println(mice.toString());
}
// -=-==--==--==-==-=-=-===-=-=-=-=-=-=-=-
public static int getNumRecords() {
try {
Scanner scanner = new Scanner(new File("Micepopulation.txt"));
int numRecords = 0;
while (scanner.hasNextLine()) {
numRecords++;
scanner.nextLine();
}
scanner.close();
return numRecords / 2;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return 0;
}
}
Text File I'm trying to attach
City of Red
70.81 2137
Boro of Orange
101.77 71
Yellow City
83.13 1034
Green Town
54.79 1819
Blueville
45.71 1514
Indigo Village
4.15 1442
Violeton
119.27 2225
Redburg
7.46 977
Orange Park
16.72 133
Yellow Falls
94.5 4556
Green Haven
326.12 1105242
Blue City
44.69 1979
Indigo Township
113.56 365
Violet Point
35.27 4161
java.lang.NumberFormatException: For input string: "" means you are trying to parse a number that isn't a valid number. In your case, you are trying to convert an empty string to an integer.
You are running into this problem because population and townSize numbers have one or more spaces in your text file. Just using split(" ") will not be sufficient, you will have to use split("\\s+) to split on one or more spaces.
Blueville's numbers have two spaces, whereas Indigo Village's numbers have one space.

Using .split to process user input

I am creating a text-adventure game in Java in which the user enters commands such as 'H' for help or 'N' to move North. In certain cases, the user will need to enter something such as 'T key' to take a key that is in that room. So because of this I need to use the split method to split the command and the item that the user wants to take. I'm getting really stuck in the return part as in some cases the string returned will only be the command if they enter one letter and in other cases it will be both the command and item. All help is appreciated!
This is my code in the main class:
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
public class GameEngine {
private Scanner userInput = new Scanner(System.in);
private Player player1 = new Player("playerName", 0);
private int currentLocation = player1.currentRoom;
private boolean stillPlaying = true; //When this is true, the game continues to run
private Item[] items = {
new Item ("map","a layout of your house", 10 ),
//new Item ("battery", "a double A battery", 5),
new Item ("battery", "a double A battery", 5),
new Item ("flashlight", "a small silver flashlight", 10),
new Item ("key", "this unlocks some door in your house", 15),
};
//Locations {roomName, description, item}
private Locale[] locales = {
new Locale("bedroom","You see the outline of a bed with your childhood stuffed bear on it.",items[0]),
new Locale("hallway","A carpeted floor and long pictured walls lie ahead of you.",null),
new Locale("kitchen","The shining surface of your stove reflects the pale moonlight coming in the window over the sink.",items[1]),
new Locale("bathroom","You find yourself standing in front of a mirror, looking back at yourself.",items[2]),
new Locale("living room","You stub your toe on the sofa in the room, almost falling right into the TV.",null),
new Locale("dining room","You bump the china cabinet which holds your expensive dishes and silverware.",items[3]),
new Locale("office","The blinking light from the monitor on your desk can be seen in the dark",null),
new Locale("library","The smell of old books surrounds you.",null),
new Locale("basement","You reach the top of some stairs and upon descending down, you find the large metal generator.",null),
};
//Matrix for rooms
private int[][] roomMap = {
// N,E,S,W
{6,1,-1,-1}, //Bedroom (room 0)
{4,2,3,0}, //Hallway (room 1)
{-1,-1,5,1}, //Kitchen (room 2)
{1,-1,-1,-1}, //Bathroom (room 3)
{-1,7,1,-1}, //Living Room (room 4)
{2,-1,-1,-1}, //Dining Room (room 5)
{-1,-1,0,-1}, //Office (room 6)
{8,-1,-1,4}, //Library (room 7)
{-1,-1,7,-1} //Basement (room 8)
};
private BreadcrumbTrail trail = new BreadcrumbTrail();
//Move method
private String[] dirNames = {"North", "East", "South", "West"};
//Welcome Message
public void displayIntro(){
System.out.println("\tWelcome to Power Outage!");
System.out.println("=================================================");
System.out.print("\tLet's start by creating your character.\n\n\tWhat is your name? ");
//Will read what name is entered and return it
player1.playerName = userInput.nextLine();
System.out.println("\n\tHello, " +player1.playerName+ ". Let's start the game! \n\n\tPress any key to begin.");
System.out.print("=================================================");
//Will move to next line when key is pressed
userInput.nextLine();
System.out.println("\tYou wake up in your bedroom. \n\n\tThe power has gone out and it is completely dark.");
System.out.println("\n\tYou must find your way to the basement to start the generator.");
}
private void displayMoveInfo(){
System.out.println("\n\tMove in any direction by typing, 'N', 'S', 'E', or 'W'.");
System.out.println("\n\tTake an item from a room by pressing 'T'.");
System.out.println("\n\tTo go back to the room you were just in type 'B'.");
System.out.println("\n\tType 'H' at any time for help and 'Q' to quit the game. Good luck!");
System.out.println("\n\tPress any key.");
}
private void move(int dir) {
int dest = roomMap[currentLocation][dir];
if (dest >= 0 && dest != 8) {
System.out.println("=================================================");
System.out.println("\tYou have moved " + dirNames[dir]);
currentLocation = dest;
System.out.println("\n\tYou are in the "+locales[currentLocation].roomName+".");
System.out.println("\n\t"+locales[currentLocation].description);
Locale locale = locales[currentLocation];
itemPresent();
//Drop breadcrumb at current location
trail.dropCrumb(currentLocation);
}
//If the player reaches the basement and wins
else if (dest == 8){
System.out.println("\tCongratulations!! You have found the basement and turned on the generator! \n\n\tYou have won the game!");
System.out.println("\n\tTHANKS FOR PLAYING!!!!!!");
System.out.println("\n\tCopyright 2016 \n\n");
stillPlaying = false;
}
//If dest == -1
else {
System.out.println("\tThere is no exit that way, please try again.");
}
}//End of Move
private void itemPresent(){
Locale locale = locales[currentLocation];
if(locale.item != null){
System.out.println("\n\tThere is a " + locale.item + " in this room.");
}
else{
System.out.println("\n\tThere is no item in this room.");
}
}
public Command getCommandFromResponse(String response) throws IllegalArgumentException{
String[] split = response.split(" ");
if(split.length < 1){
throw new IllegalArgumentException("Invalid command.");
}
Command command = new Command(split[0]);
if(split.length >= 2) {
command.setItem(split[1]);
}
return command;
}
//All possible responses to keys pressed
public void processInput(){
displayMoveInfo();
Command userCommand = getCommandFromResponse(userInput.nextLine());
while(stillPlaying){
if(player1.currentRoom != 8 && !"Q".equalsIgnoreCase(userCommand.getCommand()) ){
//Map
if(userCommand.command.equalsIgnoreCase("M")){
//only print if the player has the map
//String[] inventory = player1.inventory;
int mapFoundAt = -1;
if(player1.inventory != null){
for(int i=0; i < player1.inventory.size(); i++){
Item checkItem;
checkItem = player1.inventory.get(i);
if(checkItem.itemName.equals("map")){
mapFoundAt = i;
break;
}
}
if(mapFoundAt >=0 ){
System.out.println("Here is your map: \n\n\t\t\tbasement\n\noffice\t living room\tlibrary\n\nbedroom\t hallway\tkitchen\n\n\t bathroom \tdining room");
}
else{
System.out.println("\tYou do not have the map in your inventory.");
}
}
else{
System.out.println("\tYou don't have any items in your inventory.");
}
break;
}//End of Map
//Take
else if(userCommand.command.equalsIgnoreCase("T")){
Locale locale = locales[currentLocation];
if(userCommand.command.equalsIgnoreCase("T")){
}
if(locale.item != null){
//-User must enter item name with the command
System.out.println("Enter the command and item you would like to take.");
userCommand = getCommandFromResponse(userInput.nextLine());
if(userCommand.command.equals(locale.item.itemName)){
//-add the item to the player's inventory
player1.inventory.add(locale.item);
System.out.println("\tA " + locale.item + " was added to your inventory");
if(locale.item.itemName.equals("map")){
System.out.println("\n\tTo view the map press 'M'.");
}
//-remove the item from the current location
locale.item = null;
System.out.println("\n\tYou can view your inventory by pressing 'I' or drop an item by pressing 'D'.");
//-Add the item's worth to the score and set the items worth to zero to prevent double scoring
player1.score += locale.item.value;
System.out.println(locale.item.value + " points have been added to your score.");
System.out.println("\n\tThis is your current score: "+player1.score);
}
else{
System.out.println("That item is not at this location.");
}
}
else{
System.out.println("There is no item to pick up here");
}
}//End of Take
//Help
else if(userCommand.command.equalsIgnoreCase("H")){
displayMoveInfo();
break;
}
//Inventory
else if(userCommand.command.equalsIgnoreCase("I")){
if(player1.inventory != null){
System.out.println("\tThese are the items in your inventory: "+player1.inventory+".");
}
else{
System.out.println("\tYou currently have no items in your inventory.");
System.out.println("\tTo pick up an item in a room, press 'T'.");
}
break;
}
//Drop
else if(userCommand.command.equalsIgnoreCase("D")){
//Show the list of items in the player's inventory with numbers associated with them
if(player1.inventory.size() != 0){
System.out.println("\tThese are the items available to drop: " +player1.inventory);
}
else if(player1.inventory.size() == 0){
System.out.println("\tYou have no items in your inventory to drop.");
break;
}
System.out.println("\tEnter the name of the item you would like to drop.");
String itemToDrop = userInput.nextLine();
Locale locale = locales[currentLocation];
if(locale.item == null){
for(int i=0; i < player1.inventory.size(); i++){
Item checkItem;
checkItem = player1.inventory.get(i);
if(checkItem.itemName.equalsIgnoreCase(itemToDrop)){
//Remove item entered from a player's inventory
System.out.println("\tYou have dropped the " +checkItem.itemName+ ".");
player1.inventory.remove(i);
//Place the item at the player's current location so it can be picked up again
locale.item = checkItem;
//Subtract five points from the player's score
player1.score -= 5;
System.out.println("\tFive points have been subtracted from your score.");
System.out.println("\n\tThis is your current score: "+player1.score);
}
else if(i==player1.inventory.size() && checkItem.itemName != itemToDrop){
System.out.println("\tThat is not an item in your inventory.");
break;
}
}
}
else{
System.out.println("\tThere is already an item at this location, you can't drop an item.");
}
break;
}//End of Drop
//Backtrack
else if(userCommand.command.equalsIgnoreCase("B")){
//Pick up breadcrumb
trail.pickupCrumb();
if(trail.hasMoreCrumbs() == false){
//Move to previous crumb
currentLocation = trail.currentCrumb();
System.out.println("\n\tYou are in the "+locales[currentLocation].roomName+".");
System.out.println("\n\t"+locales[currentLocation].description);
itemPresent();
}
//When the trail is empty, drop the last breadcrumb, don't move the player again
else{
trail.dropCrumb(currentLocation);
System.out.println("\tYou are at the beginning of your breadcrumb trail, you can't backtrack any more.");
}
break;
}//End of Backtrack
//North
else if(userCommand.command.equalsIgnoreCase("N")){
move(0);
break;
}
//East
else if(userCommand.command.equalsIgnoreCase("E")){
move(1);
break;
}
//South
else if(userCommand.command.equalsIgnoreCase("S")){
move(2);
break;
}
//West
else if(userCommand.command.equalsIgnoreCase("W")){
move(3);
break;
}
//If any key is pressed other than those above
else{
System.out.println("\tInvalid command!");
break;
}
}//End of Quit if statement
else if(userCommand.command.equalsIgnoreCase("Q")){
System.out.println("Thanks for playing!\n\n");
stillPlaying = false;
}
}//End of while
}//End of pressedKey method
public void play(){
displayIntro();
System.out.println("=================================================");
System.out.println("\tYou are in the bedroom.");
Locale locale = locales[currentLocation];
itemPresent();
trail.dropCrumb(currentLocation);
//This makes the game continue to loop
while(stillPlaying){
System.out.println("=================================================");
System.out.println("\tMove in any direction.");
processInput();
} //End of while
}
public static void main(String[] args) {
GameEngine game = new GameEngine();
game.play();
} //End of main
} //End of class
This is my Player Class:
import java.util.ArrayList;
public class Player {
//Player class must have name, location, inventory, and score
public String playerName;
public ArrayList<Item> inventory;
public int score;
public int currentRoom;
public Player(String playerName, int currentRoom){
this.playerName = playerName;
this.inventory = new ArrayList<Item>();
this.score = 0;
this.currentRoom = currentRoom;
}
}
This is the Command class:
class Command{
String command;
String item;
public Command(String comm){
command = comm;
}
public Command(String comm, String item){
this.command = comm;
this.item = item;
}
public void setCommand(String command){
this.command = command;
}
public void setItem(String item){
this.item = item;
}
public String getCommand(){
return this.command;
}
public String getItem(){
return this.item;
}
public String toString(){
return this.command + ":" + this.item;
}
}
This is my Locale class:
public class Locale {
//Locale must have name, description, and Item
public static int roomNumber;
public String roomName;
public String description;
public Item item;
public Locale(String roomName, String description, Item item){
this.roomName = roomName;
this.description = description;
this.item = item;
}
}
This is my Item class:
public class Item {
//item must have a name and a description (both strings)
public String itemName;
public String itemDes;
public boolean isDiscovered;
public int value;
public Item (String itemName, String itemDes, int value){
this.itemName = itemName;
this.itemDes = itemDes;
this.isDiscovered = false;
this.value = value;
}
public String toString(){
return itemName + "(" + itemDes + ")";
}
}
This is my BreadcrumbTrail class:
public class BreadcrumbTrail {
//dropCrumb (push)
//pickupCrumb (pop)
//currentCrumb (peek)
//hasMoreCrumbs (empty)
//Drop a new breadcrumb whenever the player arrives at a local
class Node{
int data;
Node link;
Node(int s, Node l){
this.data = s; //element stored at the node
this.link = l; //link to another node
}
}//End of Node class
private Node currentCrumb;
//Constructor
public BreadcrumbTrail(){
this.currentCrumb = null;
}
//pop
public void pickupCrumb(){
this.currentCrumb = this.currentCrumb.link;
}
//push
public void dropCrumb(int s){
Node newNode = new Node(s, this.currentCrumb);
this.currentCrumb = newNode;
}
//top or peek
public int currentCrumb(){
return this.currentCrumb.data;
}
//isEmpty
public boolean hasMoreCrumbs(){
return this.currentCrumb == null;
}
}
In the pressedkey method now the if else statements obviously don't work as I now need to change the part in front of .equals.
All previous answers are decent. However, I think you are better off validating the user input and if the user enters the incorrect number of objects, throw an exception to indicate invalid input instead of just logging it. It makes the code more manageable, reads better, and give you an opportunity to deal with invalid input properly:
public Command getCommandFromResponse(String response) throws IllegalArgumentException{
String[] split = response.split(" ");
if(split.length < 1){
throw new IllegalArgumentException("Invalid command.");
}
if(split.length < 2){
throw new IllegalArgumentException("You must enter an item.");
}
return new Command(split[0], split[1]);
}
class Command{
String command;
String item;
public Command(){
command = null;
item = null;
}
public Command(String comm, String item){
this.command = comm;
this.item = item;
}
public void setCommand(String command){
this.command = command;
}
public void setItem(String item){
this.item = item;
}
public String getCommand(){
return this.command;
}
public String getItem(){
return this.item;
}
public String toString(){
return this.command + ":" + this.item;
}
}
Create a class like this:
class UserInput {
private String command;
private String item;
public UserInput() {
command = "";
item = "";
}
public void setCommand(String command) {
this.command = command;
}
public void setItem(String item) {
this.item = item;
}
}
And return an instance of it.
String response = userInput.nextLine();
String[] split = response.split(" ");
UserInput input = new UserInput();
if (split.length > 0) {
input.setCommand(split[0]);
if (split.length == 2) {
input.setItem(split[1]);
}
return input;
}
System.out.println("Invalid command");
return null;
Scanner userInput = new Scanner(System.in);
String response = userInput.nextLine();
String command = null;
String item = null;
String[] split = response.split(" ");
if (split.length == 1) {
command = split[0];
} else if (split.length == 2) {
command = split[0];
item = split[1];
} else {
System.out.println("Invalid command");
}
System.out.println(command + "/" + item);
userInput.close();
if user input contains only command, then don't run the loop. Move your
if(split.length == 0){
String command = split[0];
return command;
}
before the loop.
String response = userInput.nextLine();
String[] split = response.split(" ");
if(split.length == 0){
String command = split[0];
return command;
}
for(int i=0; i < split.length; i++){
//use simple java class to store the result
if(split.length == 1){
String item = split[1];
return item;
}
else{
System.out.println("Invalid command");
}
}

Displaying Pictures in Array

In drjava I'm trying to acquire pictures in hold them in the array, and then print out a description of each picture. Right now everything compiles but when I run it has me choose the folder that contains the pictures and then the interactions pane disappears. The code I have so far is in my House app for acquiring the pictures and printing the descriptions is
SSCCEE
HOUSE.java
public class House
{
String owner;
public final static int CAPACITY = 6;
Picture[ ] pictArray = new Picture[CAPACITY];
public House(String pString)
{
this.owner = pString;
}
public String toString()
{
return("The House owned by " + this.owner);
}
public void acquire( int position, Picture pRef )
{
this.pictArray[ position ] = pRef;
}
public void printPictures()
{
for (int i=0; i < this.pictArray.length;i++)
{
System.out.print("The Picture in position " + i + " is ");
System.out.println( this.pictArray[ i ]);
}
}
public void swap( int positionA, int positionB )
{
System.out.println("NOTHING DONE. THIS IS JUST A swap's STUB");
}
public void showOff()
{
System.out.println("NOTHING DONE. THIS IS JUST showOff's STUB");
}
}
Test.java
import java.util.Scanner;
public class Test
{
public static void main(String[] a)
{
House h = new House("Justin Chaisetseree");
Scanner sc = new Scanner(System.in);
FileChooser.pickMediaPath();
for( int i = 0; i < 6; i++)
{
h.acquire(i,new Picture(FileChooser.pickAFile()));
}
h.printPictures();
h.showOff();
Boolean done = false;
while( ! done )
{
System.out.println("Which two do you want to swap?");
System.out.print("Type in two numbers from 0 to ");
System.out.print( 5 );
System.out.println(" or two -1s to stop.");
int userInput1 = sc.nextInt();
int userInput2 = sc.nextInt();
if( userInput1 < 0 || userInput2 < 0)
{
done = true;
}
else
{
h.swap( userInput1, userInput2 );
}
}
h.showOff();
}
}

Deleting a node in a family tree

I'm trying to calclulate the best way to delete a node in a family tree. First, a little description of how the app works.
My app makes the following assumption:
Any node can only have one partner. That means that any child a single node has, it will also be the partner nodes child too. Therefore, step relations, divorces etc aren't compensated for. A node always has two parents - A mother and father cannot be added seperately. If the user doesn't know the details - the nodes attributes are set to a default value.
Also any node can add parents, siblings, children to itself. Therefore in law relationships can be added.
EDIT: After studying Andreas' answer, I have come to realise that my code may need some re-working. I'm trying to add my source but it exceeds the limit of charracters...Any advice?
Here is the FamilyTree Class:
package familytree;
import java.io.PrintStream;
public class FamilyTree {
private static final int DISPLAY_FAMILY_MEMBERS = 1;
private static final int ADD_FAMILY_MEMBER = 2;
private static final int REMOVE_FAMILY_MEMBER = 3;
private static final int EDIT_FAMILY_MEMBER = 4;
private static final int SAVE_FAMILY_TREE = 5;
private static final int LOAD_FAMILY_TREE = 6;
private static final int DISPLAY_ANCESTORS = 7;
private static final int DISPLAY_DESCENDANTS = 8;
private static final int QUIT = 9;
private Input in;
private Family family;
private PrintStream out;
public FamilyTree(Input in, PrintStream out) {
this.in = in;
this.out = out;
family = new Family();
}
public void start() {
out.println("\nWelcome to the Family Tree Builder");
initialise();
while (true) {
displayFamilyTreeMenu();
int command = getCommand();
if (quit(command)) {
break;
}
executeOption(command);
}
}
private int getCommand() {
return getInteger("\nEnter command: ");
}
private int getInteger(String message) {
while (true) {
out.print(message);
if (in.hasNextInt()) {
int n = in.nextInt();
in.nextLine();
return n;
} else {
in.nextLine();
out.println("Your input was not understood. Please try again.");
}
}
}
//good
private void displayFamilyTreeMenu() {
out.println("\nFamily Tree Menu");
out.println(DISPLAY_FAMILY_MEMBERS + ". Display Family Members");
out.println(ADD_FAMILY_MEMBER + ". Add Family Member");
out.println(REMOVE_FAMILY_MEMBER + ". Remove Family Member");
out.println(EDIT_FAMILY_MEMBER + ". Edit Family Member");
out.println(SAVE_FAMILY_TREE + ". Save Family Tree");
out.println(LOAD_FAMILY_TREE + ". Load Family Tree");
out.println(DISPLAY_ANCESTORS + ". Display Ancestors");
out.println(DISPLAY_DESCENDANTS + ". Display Descendants");
out.println(QUIT + ". Quit");
}
//good
private boolean quit(int opt) {
return (opt == QUIT) ? true : false;
}
//good
private void executeOption(int choice) {
switch (choice) {
case DISPLAY_FAMILY_MEMBERS:
displayFamilyMembers();
break;
case ADD_FAMILY_MEMBER:
addFamilyMember();
break;
case REMOVE_FAMILY_MEMBER:
removeMember();
break;
case EDIT_FAMILY_MEMBER:
editMember();
break;
case SAVE_FAMILY_TREE:
saveFamilyTree();
break;
case LOAD_FAMILY_TREE:
loadFamilyTree();
break;
case DISPLAY_ANCESTORS:
displayAncestors();
break;
case DISPLAY_DESCENDANTS:
displayDescendants();
break;
default:
out.println("Not a valid option! Try again.");
break;
}
}
private void removeMember() {
displayFamilyMembers();
int choice = selectMember();
if (choice >= 0) {
FamilyMember f = family.getFamilyMember(choice);
if (f.getIndex() == 0) {
out.println("Cannot delete yourself!");
return;
}
deleteMember(f);
}
}
private void deleteMember(FamilyMember f) {
//remove from tree
family.removeMember(f);
//remove all links to this person
if (f.hasParents()) {
f.getMother().removeChild(f);
f.getFather().removeChild(f);
}
if(f.getPartner()!=null){
f.getPartner().setPartner(null);
f.setPartner(null);
}
if (f.hasChildren()) {
for (FamilyMember member : f.getChildren()) {
if (f == member.getMother()) {
member.setMother(null);
}
if (f == member.getFather()) {
member.setFather(null);
}
if (f == member.getPartner()) {
member.setPartner(null);
}
}
}
}
private void saveFamilyTree() {
out.print("Enter file name: ");
String fileName = in.nextLine();
FileOutput output = new FileOutput(fileName);
family.save(output);
output.close();
saveRelationships();
}
private void saveRelationships() {
FileOutput output = new FileOutput("Relationships.txt");
family.saveRelationships(output);
output.close();
}
private void loadFamilyTree() {
out.print("Enter file name: ");
String fileName = in.nextLine();
FileInput input = new FileInput(fileName);
family.load(input);
input.close();
loadRelationships();
}
private void loadRelationships() {
FileInput input = new FileInput("Relationships.txt");
family.loadRelationships(input);
input.close();
}
//for selecting family member for editing adding nodes etc
private void displayFamilyMembers() {
out.println("\nDisplay Family Members");
int count = 0;
for (FamilyMember member : family.getFamilyMembers()) {
out.println();
if (count + 1 < 10) {
out.println((count + 1) + ". " + member.getFirstName() + " " + member.getLastName());
out.println(" " + member.getGender());
out.println(" " + member.getDob());
out.println(" Generation: " + (member.getGeneration() + 1));
} else {
out.println((count + 1) + ". " + member.getFirstName() + " " + member.getLastName());
out.println(" " + member.getGender());
out.println(" " + member.getDob());
out.println(" Generation: " + (member.getGeneration() + 1));
}
count++;
}
}
private int selectRelative() {
out.println("\nSelect Relative");
out.println("1. Add Parents");
out.println("2. Add Child");
out.println("3. Add Partner");
out.println("4. Add Sibling");
//out.print("\nEnter Choice: ");
//int choice = in.nextInt();
int choice = getInteger("\nEnter Choice: ");
if (choice > 0 && choice < 5) {
return choice;
}
return (-1);
}
private void addFamilyMember() {
if (family.getFamilyMembers().isEmpty()) {
out.println("No Members To Add To");
return;
}
int memberIndex = selectMember();
if (memberIndex >= 0) {
FamilyMember member = family.getFamilyMember(memberIndex);
int relative = selectRelative();
if (relative > 0) {
out.println("\nAdd Member");
//if choice is valid
switch (relative) {
case 1:
//adding parents
FamilyMember mum, dad;
if (!member.hasParents()) {
out.println("Enter Mothers Details");
mum = addMember(relative, "Female");
out.println("\nEnter Fathers Details");
dad = addMember(relative, "Male");
member.linkParent(mum);
member.linkParent(dad);
mum.linkPartner(dad);
mum.setGeneration(member.getGeneration() - 1);
dad.setGeneration(member.getGeneration() - 1);
sortGenerations();
} else {
out.println(member.getFirstName() + " " + member.getLastName() + " already has parents.");
}
break;
case 2:
//adding child
if (member.getPartner() == null) {
FamilyMember partner;
if (member.getGender().equals("Male")) {
out.println("Enter Mothers Details");
partner = addMember(1, "Female");
} else {
out.println("Enter Fathers Details");
partner = addMember(1, "Male");
}
//create partner
member.linkPartner(partner);
partner.setGeneration(member.getGeneration());
out.println();
}
out.println("Enter Childs Details");
FamilyMember child = addMember(relative, "");
child.linkParent(member);
child.linkParent(member.getPartner());
child.setGeneration(member.getGeneration() + 1);
sortGenerations();
break;
case 3:
//adding partner
if (member.getPartner() == null) {
out.println("Enter Partners Details");
FamilyMember partner = addMember(relative, "");
member.linkPartner(partner);
partner.setGeneration(member.getGeneration());
} else {
out.println(member.getFirstName() + " " + member.getLastName() + " already has a partner.");
}
break;
case 4:
//adding sibling
if (member.getFather() == null) {
out.println("Enter Mothers Details");
mum = addMember(1, "Female");
out.println("\nEnter Fathers Details");
dad = addMember(1, "Male");
member.linkParent(mum);
member.linkParent(dad);
mum.linkPartner(dad);
mum.setGeneration(member.getGeneration() - 1);
dad.setGeneration(member.getGeneration() - 1);
sortGenerations();
out.println("\nEnter Siblings Details");
} else {
out.println("Enter Siblings Details");
}
FamilyMember sibling = addMember(relative, "");
//create mum and dad
mum = member.getMother();
dad = member.getFather();
sibling.linkParent(mum);
sibling.linkParent(dad);
sibling.setGeneration(member.getGeneration());
break;
}
} else {
out.println("Invalid Option!");
}
} else {
out.println("Invalid Option!");
}
}
private int selectMember() {
displayFamilyMembers();
//out.print("\nSelect Member: ");
//int choice = in.nextInt();
int choice = getInteger("\nSelect Member: ");
if (choice > 0 && choice <= family.getFamilyMembers().size()) {
return (choice - 1);
}
return -1;
}
private void editMember() {
int choice = selectMember();
if (choice >= 0) {
out.println("Select Detail To Edit: ");
out.println("1. Name");
out.println("2. Gender");
out.println("3. Date of Birth");
//out.print("\nEnter Choice: ");
//int opt = in.nextInt();
int opt = getInteger("\nEnter Choice: ");
if (opt > 0 && opt < 4) {
switch (opt) {
case 1: //name
out.print("Enter New First Name: ");
String fName = in.nextLine();
out.print("Enter New Last Name: ");
String lName = in.nextLine();
family.changeName(fName, lName, choice);
break;
case 2: //Gender
FamilyMember f = family.getFamilyMember(choice);
String gender = f.getGender();
if (f.getChildren().isEmpty()) {
gender = selectGender();
family.changeGender(gender, choice);
} else {
//swap genders
//swap mother father relationships for kids
swapGenders(f, choice);
}
break;
case 3:
String dob = enterDateOfBirth();
family.changeDOB(dob, choice);
}
} else {
out.println("Invalid Choice!");
}
}
}
private FamilyMember addMember(int option, String gender) {
out.print("Enter First Name: ");
String fName = formatString(in.nextLine().trim());
out.print("Enter Last Name: ");
String lName = formatString(in.nextLine().trim());
//String gender;
if (option != 1) { //if not adding parents
gender = selectGender();
}
String dob = enterDateOfBirth();
FamilyMember f = family.getFamilyMember(family.addMember(fName, lName, gender, dob));
f.setIndex(family.getFamilyMembers().size() - 1);
return (f);
}
private String selectGender() {
String gender = null;
out.println("Select Gender");
out.println("1. Male");
out.println("2. Female");
//out.print("Enter Choice: ");
//int gOpt = in.nextInt();
int gOpt = getInteger("Enter Choice: ");
if (gOpt == 1) {
gender = "Male";
} else if (gOpt == 2) {
gender = "Female";
} else {
out.println("Invalid Choice");
}
return gender;
}
private void swapGenders(FamilyMember f, int choice) {
String gender;
out.println("\nNOTE: Editing A Parent Nodes Gender Will Swap Parents Genders\n"
+ "And Swap Mother/Father Relationships For All Children.");
out.println("\nContinue:");
out.println("1. Yes");
out.println("2. No");
//out.print("\nEnter Choice: ");
//int select = in.nextInt();
int select = getInteger("\nEnter Choice: ");
if (select > 0 && select < 3) {
switch (select) {
case 1:
//swap relationships
gender = selectGender();
//if selected gender is different
if (!gender.equals(f.getGender())) {
//swap
String g = f.getGender();
family.changeGender(gender, choice);
family.changeGender(g, f.getPartner().getIndex());
if (g.equals("Male")) {
for (FamilyMember m : f.getChildren()) {
m.setMother(f);
m.setFather(f.getPartner());
}
} else {
for (FamilyMember m : f.getChildren()) {
m.setFather(f);
m.setMother(f.getPartner());
}
}
}
break;
case 2:
break;
}
} else {
out.println("Invalid Choice");
}
}
private String formatString(String s) {
String firstLetter = s.substring(0, 1);
String remainingLetters = s.substring(1, s.length());
s = firstLetter.toUpperCase() + remainingLetters.toLowerCase();
return s;
}
private String enterDateOfBirth() {
out.print("Enter Year Of Birth (0 - 2011): ");
String y = in.nextLine();
out.print("Enter Month Of Birth (1-12): ");
String m = in.nextLine();
if (m.trim().equals("")) {
m = "0";
}
if (Integer.parseInt(m) < 10) {
m = "0" + m;
}
m += "-";
out.print("Enter Date of Birth (1-31): ");
String d = in.nextLine();
if (d.trim().equals("")) {
d = "0";
}
if (Integer.parseInt(d) < 10) {
d = "0" + d;
}
d += "-";
String dob = d + m + y;
while (!DateValidator.isValid(dob)) {
out.println("Invalid Date. Try Again:");
dob = enterDateOfBirth();
}
return (dob);
}
private void displayAncestors() {
out.print("\nDisplay Ancestors For Which Member: ");
int choice = selectMember();
if (choice >= 0) {
FamilyMember node = family.getFamilyMember(choice);
FamilyMember ms = findRootNode(node, 0, 2, -1);
FamilyMember fs = findRootNode(node, 1, 2, -1);
out.println("\nPrint Ancestors");
out.println("\nMothers Side");
if(ms==null){
out.println("Member has no mother");
}else{
printDescendants(ms, node, ms.getGeneration());
}
out.println("\nFathers Side");
if(fs==null){
out.println("Member has no father");
}else{
printDescendants(fs, node, fs.getGeneration());
}
} else {
out.println("Invalid Option!");
}
}
private void displayDescendants() {
out.print("\nDisplay Descendants For Which Member: ");
int choice = selectMember();
if (choice >= 0) {
FamilyMember node = family.getFamilyMember(choice);
out.println("\nPrint Descendants");
printDescendants(node, null, 0);
} else {
out.println("Invalid Option!");
}
}
private FamilyMember findRootNode(FamilyMember node, int parent, int numGenerations, int count) {
FamilyMember root;
count++;
if (count < numGenerations) {
if (parent == 0) {
if(node.hasMother()){
node = node.getMother();
}else{
return node;
}
} else {
if(node.hasFather()){
node = node.getFather();
}else{
return node;
}
}
root = findRootNode(node, 1, numGenerations, count);
return root;
}
return node;
}
private int findHighestLeafGeneration(FamilyMember node) {
int gen = node.getGeneration();
for (int i = 0; i < node.getChildren().size(); i++) {
int highestChild = findHighestLeafGeneration(node.getChild(i));
if (highestChild > gen) {
gen = highestChild;
}
}
return gen;
}
private void printDescendants(FamilyMember root, FamilyMember node, int gen) {
out.print((root.getGeneration() + 1) + " " + root.getFullName());
out.print(" [" + root.getDob() + "] ");
if (root.getPartner() != null) {
out.print("+Partner: " + root.getPartner().getFullName() + " [" + root.getPartner().getDob() + "] ");
}
if (root == node) {
out.print("*");
}
out.println();
if (!root.getChildren().isEmpty() && root != node) {
for (int i = 0; i < root.getChildren().size(); i++) {
for (int j = 0; j < root.getChild(i).getGeneration() - gen; j++) {
out.print(" ");
}
printDescendants(root.getChild(i), node, gen);
}
} else {
return;
}
}
//retrieve highest generation
public int getRootGeneration() {
int min = family.getFamilyMember(0).getGeneration();
for (int i = 0; i < family.getFamilyMembers().size(); i++) {
min = Math.min(min, family.getFamilyMember(i).getGeneration());
}
return Math.abs(min);
}
public void sortGenerations() {
int amount = getRootGeneration();
for (FamilyMember member : family.getFamilyMembers()) {
member.setGeneration(member.getGeneration() + amount);
}
}
//test method - temporary
private void initialise() {
family.addMember("Bart", "Simpson", "Male", "18-03-1985");
family.getFamilyMember(0).setIndex(0);
family.addMember("Homer", "Simpson", "Male", "24-09-1957");
family.getFamilyMember(1).setIndex(1);
family.addMember("Marge", "Simpson", "Female", "20-07-1960");
family.getFamilyMember(2).setIndex(2);
family.addMember("Lisa", "Simpson", "Female", "28-01-1991");
family.getFamilyMember(3).setIndex(3);
family.addMember("Abe", "Simpson", "Male", "10-03-1920");
family.getFamilyMember(4).setIndex(4);
family.addMember("Mona", "Simpson", "Female", "18-09-1921");
family.getFamilyMember(5).setIndex(5);
//set relationships
family.getFamilyMember(0).setMother(family.getFamilyMember(2));
family.getFamilyMember(0).setFather(family.getFamilyMember(1));
family.getFamilyMember(3).setMother(family.getFamilyMember(2));
family.getFamilyMember(3).setFather(family.getFamilyMember(1));
family.getFamilyMember(1).addChild(family.getFamilyMember(3));
family.getFamilyMember(1).addChild(family.getFamilyMember(0));
family.getFamilyMember(2).addChild(family.getFamilyMember(3));
family.getFamilyMember(2).addChild(family.getFamilyMember(0));
family.getFamilyMember(1).setPartner(family.getFamilyMember(2));
family.getFamilyMember(2).setPartner(family.getFamilyMember(1));
family.getFamilyMember(4).setPartner(family.getFamilyMember(5));
family.getFamilyMember(5).setPartner(family.getFamilyMember(4));
family.getFamilyMember(1).setMother(family.getFamilyMember(5));
family.getFamilyMember(1).setFather(family.getFamilyMember(4));
family.getFamilyMember(4).addChild(family.getFamilyMember(1));
family.getFamilyMember(5).addChild(family.getFamilyMember(1));
family.getFamilyMember(0).setGeneration(2);
family.getFamilyMember(1).setGeneration(1);
family.getFamilyMember(2).setGeneration(1);
family.getFamilyMember(3).setGeneration(2);
family.getFamilyMember(4).setGeneration(0);
family.getFamilyMember(5).setGeneration(0);
}
}
All tasks require the same effort. It will always go like this:
public void deleteFamilyMember(FamilyMember member) {
member.mother.children.remove(member);
member.father.children.remove(member);
member.partner.children.remove(member);
for (FamilyMember child:children) {
if (child.father == member) child.father = null;
if (child.mother == member) child.mother = null;
if (child.partner == member) child.partner = null;
}
// now all references to this member are eliminated, gc will do the rest.
}
Example:
Homer.mother = ??
Homer.father = ??
Homer.partner = Marge
Homer.children = {Bart, Lisa, Maggie}
Marge.mother = ??
Marge.father = ??
Marge.partner = Homer
Marge.children = {Bart, Lisa, Maggie}
Bart.mother = Marge
Bart.father = Homer
Bart.partner = null
Bart.children = {}
Lisa.mother = Marge
Lisa.father = Homer
Lisa.partner = null
Lisa.children = {}
Maggie.mother = Marge
Maggie.father = Homer
Maggie.partner = null
Maggie.children = {}
To remove Bart from the familiy tree, we should set Bart's mother and father attribute to null and need to remove Bart from Homer's and Marge's list of children.
To remove Marge, we have to set her partner's partner to null (Homer.partner) and visit all children to clear their mother attribute (that's this child.mother part of the code above)
I would model things differently and do the work in the FamilyMember class. Here's a sample implementation:
public class FamilyMember{
public enum Gender{
MALE, FEMALE
}
private final Set<FamilyMember> exPartners =
new LinkedHashSet<FamilyMember>();
public Set<FamilyMember> getExPartners(){
return new LinkedHashSet<FamilyMember>(exPartners);
}
public FamilyMember getFather(){
return father;
}
public FamilyMember getMother(){
return mother;
}
public Set<FamilyMember> getSiblings(){
final Set<FamilyMember> set =
father == null && mother == null ? Collections
.<FamilyMember> emptySet() : new HashSet<FamilyMember>();
if(father != null){
set.addAll(father.children);
}
if(mother != null){
set.addAll(mother.children);
}
set.remove(this);
return set;
}
public String getName(){
return name;
}
private final Gender gender;
private FamilyMember partner;
private final FamilyMember father;
private final FamilyMember mother;
private final Set<FamilyMember> children =
new LinkedHashSet<FamilyMember>();
private final String name;
public FamilyMember haveChild(final String name, final Gender gender){
if(partner == null){
throw new IllegalStateException("Partner needed");
}
final FamilyMember father = gender == Gender.MALE ? this : partner;
final FamilyMember mother = father == this ? partner : this;
return new FamilyMember(father, mother, name, gender);
}
public Set<FamilyMember> getChildren(){
return new LinkedHashSet<FamilyMember>(children);
}
#Override
public String toString(){
return "[" + name + ", " + gender + "]";
}
public FamilyMember(final String name, final Gender gender){
this(null, null, name, gender);
}
public FamilyMember(final FamilyMember father,
final FamilyMember mother,
final String name,
final Gender gender){
if(name == null){
throw new IllegalArgumentException("A kid needs a name!");
}
if(gender == null){
throw new IllegalArgumentException("Which is it going to be?");
}
this.father = father;
this.name = name;
this.gender = gender;
if(father != null){
father.children.add(this);
}
this.mother = mother;
if(mother != null){
mother.children.add(this);
}
}
public FamilyMember hookUpWith(final FamilyMember partner){
if(partner.gender == gender){
throw new IllegalArgumentException(
"Sorry, same-sex-marriage would make things too complicated");
}
this.partner = partner;
partner.partner = this;
return this;
}
public FamilyMember splitUp(){
if(partner == null){
throw new IllegalArgumentException("Hey, I don't have a partner");
} else{
partner.partner = null;
exPartners.add(partner);
partner.exPartners.add(this);
partner = null;
}
return this;
}
public FamilyMember getPartner(){
return partner;
}
}
And here's the much more expressive code you can write that way:
FamilyMember marge = new FamilyMember("Marge", Gender.FEMALE);
FamilyMember homer = new FamilyMember("Homer", Gender.MALE);
homer.hookUpWith(marge);
FamilyMember bart = homer.haveChild("Bart", Gender.MALE);
FamilyMember lisa = marge.haveChild("Lisa", Gender.FEMALE);
System.out.println("Homer & Marge: " + marge + ", "
+ marge.getPartner());
homer.splitUp();
FamilyMember dolores =
marge
.hookUpWith(new FamilyMember("New Guy", Gender.MALE))
.haveChild("Dolores", Gender.FEMALE);
FamilyMember bruno =
homer
.hookUpWith(new FamilyMember("New Girl", Gender.FEMALE))
.haveChild("Bruno", Gender.MALE);
System.out.println(
"Marge & Partner: " + marge + ", " + marge.getPartner());
System.out.println("Marge's Ex-Partners: " + marge.getExPartners());
System.out.println(
"Homer & Partner: " + homer + ", " + homer.getPartner());
System.out.println("Homer's Ex-Partners: " + homer.getExPartners());
System.out.println("Marge's kids: " + marge.getChildren());
System.out.println("Homer's kids: " + homer.getChildren());
System.out.println("Dolores's siblings: " + dolores.getSiblings());
System.out.println("Brunos's siblings: " + bruno.getSiblings());
Output:
Homer & Marge: [Marge, FEMALE], [Homer, MALE]
Marge & Partner: [Marge, FEMALE], [New Guy, MALE]
Marge's Ex-Partners: [[Homer, MALE]]
Homer & Partner: [Homer, MALE], [New Girl, FEMALE]
Homer's Ex-Partners: [[Marge, FEMALE]]
Marge's kids: [[Bart, MALE], [Lisa, FEMALE], [Dolores, FEMALE]]
Homer's kids: [[Bart, MALE], [Lisa, FEMALE], [Bruno, MALE]]
Dolores's siblings: [[Bart, MALE], [Lisa, FEMALE]]
Brunos's siblings: [[Bart, MALE], [Lisa, FEMALE]]

Categories