Runtime.getRuntime().exec("path to file") runs, but program acts strange - java

I am making a text based launcher for a number of programs. I am using the
Runtime.getRuntime().exec("path//to//file.exe")) method.
The program will run, it always will, but some act weirdly or fail to find critical .dll files that are there. Others have text messed up while running etc. As you can see, these are all games which are complex and use a number of engines I don't understand. Thanks!
Dead Space 3: Screen is black, game runs though. Only display seems to not be working
MW3: TeknoMW3.exe cant find teknomw3.dll even though they are in the same folder(and launching it normally makes it run fine).
Endless Space: Text is displayed strangely. Exit is %getuserexit% or something akin to that for every space where text should and normally is displayed. Only occurs on main menu.
Splinter Cell Blaclist: Dir is correct, cant find the specified file. Ill jut work around that one.
Bioshock 1: Straight up crashes(might be due to a .dll problem again, I dont actualy know though)
Bioshock 2: Never runs. file is executed but doesnt run.
public class Main {
static int launcherNum = 14;
static Launchers launchers[] = new Launchers[launcherNum];
static Launchers assassinsCreed3 = new Launchers("G://Games//ROMS//Assassins Creed III//AC3SP.exe", "Assassians Creed III (AC3)");
static Launchers bioshock = new Launchers("G://Games//ROMS//Bioshock//Builds//Release//Bioshock.exe", "Bioshock");
static Launchers bioshock2 = new Launchers("G://Games//ROMS//Bioshock 2//SP//Builds//Binaries//Bioshock2.exe", "Bioshock 2");
static Launchers bioshock3 = new Launchers("G://Games//ROMS//Bioshock Infinite//Binaries//Win32//BioShockInfinite.exe", "Bioshock Infinite");
static Launchers borderlands2 = new Launchers("G://Games//ROMS//Borderlands 2//Binaries//Win32//Borderlands2.exe", "Borderlands 2");
static Launchers mw3 = new Launchers("G://Games//ROMS//Call of Duty- Modern Warfare 3//TeknoMW3.exe", "Call of Duty: Modern Warefare 3 (MW3)");
static Launchers deadSpace3 = new Launchers("G://Games//ROMS//Dead Space 3//deadspace3.exe", "Dead Space 3");
static Launchers endlessSpace = new Launchers("G://Games//ROMS//Endless Space//EndlessSpace.exe", "Endless Space");
static Launchers prototype2 = new Launchers("G://Games//ROMS//PROTOTYPE 2//Prototype2.exe", "Prototype 2");
static Launchers leagueOfLegends = new Launchers("G://Games//ROMS//lol.launcher.exe", "League of Legends");
static Launchers rct3 = new Launchers("G://Games//ROMS//RCT3//RCT3plus.exe", "Rollercoaster Tycoon 3");
static Launchers splitSecond = new Launchers("G://Games//ROMS//Split Second//SplitSecond.exe", "Split Second");
static Launchers skyrim = new Launchers("G://Games//ROMS//The Elder Scrolls V Skyrim//TESV.exe", "The Elder Scrolls: Skyrim");
static Launchers tcSplinterCell = new Launchers("G://Games//ROMS//Tom Clancys Splinter Cell Blacklist//src//SYSTEM//Blacklist_DX11_game.exe", "Tom Clancy's: Splinter Cell Blacklist");
public static void initLauncher() {
//adds AC3
launchers[0] = assassinsCreed3;
//Adds all 3 Bioshocks. God its hard to write "Bioshock"
launchers[1] = bioshock;
launchers[2] = bioshock2;
launchers[3] = bioshock3;
//Adds Borderlands 2
launchers[4] = borderlands2;
//Adds MW3
launchers[5] = mw3;
//Adds Dead Space 3
launchers[6] = deadSpace3;
//Adds Endless Space
launchers[7] = endlessSpace;
//Adds Prototype 2
launchers[8] = prototype2;
//Adds League of Legends... yeah, I know.
launchers[9] = leagueOfLegends;
//Adds RCT3
launchers[10] = rct3;
//Adds Split Second
launchers[11] = splitSecond;
//Adds skyrim
launchers[12] = skyrim;
//Adds Splinter Cell
launchers[13] = tcSplinterCell;
}
public static void runLaunchers() {
boolean done = false;
String input1;
Scanner input = new Scanner(System.in);
while(done == false) {
System.out.println("Welcome to the Cracked Game Launcher, also know as CSteam. This is a product of the labors of ASIGTX. Do not redistribute.\n Ever");
System.out.println("Please select a game from our libraires.");
System.out.println();
for (Launchers l: launchers) {
if (l.launcherName != null) {
System.out.println(l.launcherName);
System.out.println();
}//end of if loop
}//end of for loop
input1 = input.nextLine();
switch (input1) {
case "Assassins Creed 3":
case "AC3":
launchers[0].launchEXE();
if (launchers[0].hasLaunched == true) {
done = true;
}//end of if
break;
case "Bioshock":
launchers[1].launchEXE();
if (launchers[1].hasLaunched == true) {
done = true;
}//end of if
break;
case "Bioshock 2":
launchers[2].launchEXE();
if (launchers[2].hasLaunched == true) {
done = true;
}//end of if
break;
case "Bioshock Infinite":
launchers[3].launchEXE();
if (launchers[3].hasLaunched == true) {
done = true;
}//end of if
break;
case "Borderlands 2":
launchers[4].launchEXE();
if (launchers[4].hasLaunched == true) {
done = true;
}//end of if
break;
case "MW3":
case "Call of Duty: Modern Warefare 3":
launchers[5].launchEXE();
if (launchers[5].hasLaunched == true) {
done = true;
}//end of if
break;
case "Dead Space 3":
launchers[6].launchEXE();
if (launchers[6].hasLaunched == true) {
done = true;
}//end of if
break;
case "Endless Space":
launchers[7].launchEXE();
if (launchers[7].hasLaunched == true) {
done = true;
}//end of if
break;
case "Prototype 2":
launchers[8].launchEXE();
if (launchers[8].hasLaunched == true) {
done = true;
}//end of if
break;
case "League of Legends":
launchers[9].launchEXE();
if (launchers[9].hasLaunched == true) {
done = true;
}//end of if
break;
case "Rollercoaster Tycoon 3":
launchers[10].launchEXE();
if (launchers[10].hasLaunched == true) {
done = true;
}//end of if
break;
case "Split Second":
launchers[11].launchEXE();
if (launchers[11].hasLaunched == true) {
done = true;
}//end of if
break;
case "The Elder Scrolls: Skyrim":
case "Skyrim":
launchers[12].launchEXE();
if (launchers[12].hasLaunched == true) {
done = true;
}//end of if
break;
case "Tom Clancy's: Splinter Cell Blacklist":
case "Splinter Cell Blacklist":
launchers[13].launchEXE();
if (launchers[13].hasLaunched == true) {
done = true;
}//end of if
break;
}//end of switch
}//end of while loop
}
public static void main(String[] args) {
initLauncher();
runLaunchers();
}//end of main
}//end of class
public class Launchers {
public boolean hasLaunched = false;
public String launcherName;
private String dir;
public Launchers(String dir, String namein) {
setName(namein);
this.dir = dir;
}//end of constructor
public void setName(String s) {
launcherName = s;
}//end of setname
public String getDir() {
return dir;
}
public void launchEXE() {
String runtimeName = launcherName;
try {
Runtime.getRuntime().exec( getDir() );
} catch (IOException e) {
System.out.println("Dir is invalid");
e.printStackTrace();
}
hasLaunched = true;
System.out.println(launcherName +" has launched!");
}//end of launchEXE
}

It is likely that the programs have an expectation about their execution context.
From your example, it's likely that every program is being started within the same context/execution location that you run your program from, meaning that they can't find libraries or resources that they need.
Instead of using Runtime#exec directly, try using ProcessBuilder instead. This will allow you to change the execution location of the process.
For example...
String cmd = getDir();
File cmdFile = new File(cmd);
// Maybe check that the cmdFile.exists...;)
File parentFile = cmdFile.getParentFile();
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(parentFile);
pb.redirectError();
Process p = pb.start();
It would also be advisable to read the process's InputStream as some process get upset when you don't ;)
InputStream is = p.getInputStream();
// This simple reads the contents from the InputStream and discards it
// You could change it to actually dump the output if wanted ;)
while (is.read() != -1);
int exitValue = p.waitFor();

Related

(Using BlueJ) In the terminal, when my code runs to a certain point, the user can continuously type in words but nothing will be done with it

I apologize in advance for my rudimentary code--I started coding a couple months ago.
I'm trying to code a text-based baking game where there's a limited number of combos/recipes (16), and the user has to try to unlock all of the cake combos in order to finish the game. When I try to run the code, when asked for the topping the user wants, no matter what input I type in, the code doesn't run past this part. The expected result would be to take both the flavor and topping and add them together to become the new string of cake.
[A screenshot of the described problem][1]
[1]: https://i.stack.imgur.com/bphyO.png
Another problem I had, but can't check if I still have it because the code won't run past the "topping user input" section, is that when the code runs to the section where it checks if the cake combo has already been found or not, inside the terminal it prints out the combo the user first found infinitely.
I'd really appreciate any help, thank you so much.
The code:
import java.util.Arrays;
import java.util.Scanner;
import java.util.ArrayList;
public class Bakery
public ArrayList<String> aList = new ArrayList();
public static int achievements = 0;
static ArrayList<String> foundCakes = new <String>ArrayList();
public static String[] f = {"chocolate", "vanilla", "strawberry", "banana"};
public static String[] t = {"sprinkles", "fruit", "frosting", "nothing"};
public static void main (String[]args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
System.out.println("(To quit the game, type in 'quit')");
delay("Hi, what's your name?", 60L);
String playerName = sc.nextLine();
delay("Your name is: " + playerName, 60L);
delay("Welcome to this Bakery!", 40L);
delay("This Bakery has been without an owner for so long...",40L);
delay("Most of it's recipies have been lost.", 40L);
delay("It's up to you to collect all of the lost recipies!", 40L);
delay("These are the ingredients provided: ", 60L);
delay("Base flavors: " + Arrays.toString(f), 60L);
delay("Toppings: " + Arrays.toString(t), 60L);
while (achievements != 16){
System.out.println("Pick a flavor");
String flavor = sc.nextLine();
if (flavor.equalsIgnoreCase("quit")){
delay("Thanks for playing!", 40L);
System.exit(0);
}
String cuFlavor = flavor.toLowerCase();
boolean oo = false;
while (oo){
if(Arrays.asList(f).contains(cuFlavor)){
oo = true;
}
}
if (Arrays.asList(f).contains(cuFlavor) == false){
delay("Not an option, please pick again.", 40L);
flavor = sc.nextLine();
}
System.out.println("Pick a topping");
String topping = sc.nextLine();
if (topping.equalsIgnoreCase("quit")){
delay("Thanks for playing!", 40L);
System.exit(0);
}
String cuTopping = topping.toLowerCase();
boolean tt = false;
while (tt==false){
if(Arrays.asList(t).contains(cuTopping) == true){
tt = true;
}
}
if (Arrays.asList(t).contains(cuTopping) == false){
delay("Not an option, please pick again.", 40L);
topping = sc.nextLine();
}
String cake = cuFlavor+cuTopping;
boolean bb = false;
while (bb == false){
if(foundCakes.contains(cake)){
delay("Previously found recipe!", 40L);
delay(getRandomResponse(), 40L);
bb = true;
}
}
boolean nc = true;
while(nc == true){
if(foundCakes.contains(cake) == false){
delay("You found a new cake!", 40L);
delay("Unlocked: "+cake, 40L);
foundCakes.add(cake);
achievements++;
delay("Number of recipes found: " + achievements, 40L);
nc = false;
}
}
}
System.exit(0);
}
public int getAchievements(){
return achievements;
}
private static String getRandomResponse()
{
final int NUMBER_OF_RESPONSES = 4;
double r = Math.random();
int whichResponse = (int)(r * NUMBER_OF_RESPONSES);
String response = "";
if (whichResponse == 0)
{
response = "Don't worry! Still delicious.";
}
else if (whichResponse == 1)
{
response = "What a classic cake!";
}
else if (whichResponse == 2)
{
response = "Yummy :)";
}
else if (whichResponse == 3)
{
response = "Smells nice!";
}
return response;
}
public String toString(){
return "Flavors: "+Arrays.toString(f)+" Topping: "+Arrays.toString(t);
}
public static void delay(String s, long delay) throws InterruptedException {
for ( int i= 0; i < s.length(); i++) {
// for loop delays individual String characters
System.out.print(s.charAt(i));
Thread.sleep(delay); //time is in milliseconds
}
System.out.println(""); // this is the space in between lines
}
}
Take a look at your while loops. First:
boolean oo = false;
while (oo){
if (Arrays.asList(f).contains(cuFlavor)) {
oo = true;
}
}
This loop is never entered since oo == false.
Next:
boolean tt = false;
while (tt == false) {
if (Arrays.asList(t).contains(cuTopping) == true) {
tt = true;
}
}
This loop does execute, but what happens if t does not contain cuTopping? In that case, tt never get sets to true and the loop goes on forever.
The next two loops have the same issue.
You need to ensure the loops will end at some point. Example:
while (tt == false) {
if (Arrays.asList(t).contains(cuTopping) == true) {
tt = true;
}
else {
// Do something to change cuTopping
System.out.println("Pick a topping");
cuTopping = sc.nextLine();
// etc....
}
}
You can combine the loops with the gathering of the input:
String cuTopping = null;
do {
if (cuTopping != null) { // Only true after first iteration
System.out.println("That topping is not in the list!");
}
System.out.println("Pick a topping");
cuTopping = sc.nextLine().toLowerCase();
if (cuTopping.equalsIgnoreCase("quit")) {
delay("Thanks for playing!", 40L);
System.exit(0);
}
} while (!Arrays.asList(t).contains(cuTopping));

How to exit all multiple nested methods at once

I've been following Tim Buchalka's course Java Programming Masterclass for Software Developers and I've been modifying his program from lesson 118.
I want to update my list at the runtime while using the list iterator (navigate method). The program runs fine, but if I update my list, Java throws an error: ConcurrentModificationException
I have come up with the following solution:
Whenever a user performs a modification of the list, other methods run, and update the list and pass it to the navigate() method. By doing this, my program enters multi-level nested methods, and the problem comes up when a user wants to exit from the program (case 0: in navigate() method). User has to press 0 as many times as many nested methods were ran.
My initial idea was to count how many times navigate() was nested, then using for loop return as many times as it was nested. But later I understood it does not make sense
What can I do to exit from the program by using case 0: just once?
package com.practice;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Scanner;
public class List extends Traveler {
private LinkedList<String> linkedList;
private String tripName;
public List(String travelerName, int travelerAge, String tripName) {//it has to have same amount of parameters or more with super constructor!
super(travelerName, travelerAge);
this.tripName = tripName;
this.linkedList = new LinkedList<>();
}
public List(){} //it has to have same amount of parameters or more with super constructor!
public LinkedList<String> getLinkedList() {
return linkedList;
}
public String getTripName() {
return tripName;
}
private void removeCity(LinkedList<String> cityList, String deletedCity) {
if(cityList.remove(deletedCity)) {
System.out.println(deletedCity + " has been removed");
} else System.out.println("Could not find the city you want to remove");
List.navigate(cityList);
}
//adds a new city and update the list without an error
private void noExceptionError(LinkedList<String> listOfCities, String cityName) {
ListIterator<String> listIterator = listOfCities.listIterator();
while((listIterator.hasNext())) {
int comparison = listIterator.next().compareTo(cityName);
if(comparison == 0) {
System.out.println(cityName + " has been already added to the list");
return;
} else if(comparison > 0) {
listIterator.previous();
break;
}
}
listIterator.add(cityName);
List.navigate(listOfCities);
}
private void loadToList(LinkedList<String> listOfCities) {
alphabeticallyAdd(listOfCities, "Poznan");
alphabeticallyAdd(listOfCities, "Gdansk");
alphabeticallyAdd(listOfCities, "Szczeczin");
alphabeticallyAdd(listOfCities, "Warszawa");
alphabeticallyAdd(listOfCities, "Lodz");
alphabeticallyAdd(listOfCities, "Wroclaw");
List.navigate(listOfCities);
}
private void alphabeticallyAdd(LinkedList<String> listOfCities, String cityName) {
ListIterator<String> listIterator = listOfCities.listIterator(); //just a setup; doesn't point to the 1st element
while((listIterator.hasNext())) {
//if value is greater, the word that is in the list is alphabetically bigger, thus, put it before the list element
//if equal, it is duplicate! return false
// else it is less, thus, we have to move further in the list
int comparison = listIterator.next().compareTo(cityName); //retrieves the 1st value and goes to the next
if(comparison == 0) {
System.out.println(cityName + " has been already added to the list");
return;
} else if(comparison > 0) {
listIterator.previous(); //because we've used .next() in the int comparison initialization
listIterator.add(cityName); //don't use linkedList.add because it doesn't know the int comparison, so cannot properly add!!!
return;
}
}
listIterator.add(cityName); //adding at the end of the list
}
public static void navigate(LinkedList<String> listOfCities) {
Scanner userChoice = new Scanner(System.in);
List travelListObject = new List();
ListIterator<String> listIterator = listOfCities.listIterator();
boolean goingForward = true;
while(true) {
Main.menu();
int choice = userChoice.nextInt();
userChoice.nextLine(); //takes care of enter key problem
switch(choice) {
case 0:
System.out.println("Goodbye");
//possible improvement
/* for(int i = 0; i <= List.amountNestedMethods; i++) {
return;
}*/
return;
case 1: //moving forward
if(!goingForward) {
if(listIterator.hasNext()) {
listIterator.next();
}
}
if(listIterator.hasNext()) {
System.out.println(listIterator.next());
Traveler.setNumberVisitedCities(Traveler.getNumberVisitedCities() + 1);
goingForward = true;
} else {
System.out.println("No more cities in the list");
goingForward = false;
}
break;
case 2: //moving back
if(goingForward) {
if(listIterator.hasPrevious()) {
listIterator.previous();
}
goingForward = false;
}
if(listIterator.hasPrevious()) {
Traveler.setNumberVisitedCities(Traveler.getNumberVisitedCities() + 1);
System.out.println(listIterator.previous());
} else {
System.out.println("You're at the beginning of the list");
goingForward = true;
}
break;
case 3:
Main.printCities(listOfCities);
break;
case 4:
break;
case 5:
System.out.println("Write new city");
String addedCity = userChoice.next();
travelListObject.noExceptionError(listOfCities, addedCity);
break;
case 6:
System.out.println("Write the city you want to delete");
String deletedCity = userChoice.next();
travelListObject.removeCity(listOfCities, deletedCity);
break;
case 7:
System.out.println("You have been in " + Traveler.getNumberVisitedCities() + " cities in total");
break;
case 9:
travelListObject.loadToList(listOfCities);
break;
default:
System.out.println("Something weird happened. Try to choose an option again");
}
}
}
}
If you want to exit the program you can simply call System.exit(n), where the n is an integer return code (the convention being that code 0 means normal execution and other values indicate some sort of error).

I'm trying to add a value to an int in one class and then use it in another, Java

So as the title says im struggling to add a value to an integer and then pass it to another class that uses it, then this class will pass it to the next and then that one will pass it over to the main class. Its an integer that changes the stat template of the enemies in my small game im writing.
I have tried to make constructors in two of my classes as I thought that was the problem, Ive tried to see if they work by passing some messages in them.
The problem seems to be that when I save something in the "private int l" It dosnt actually change the value of that int and I cant figure out why that is.
Here is my code, its probably not very pretty so if you have any suggestions to structure changes that I might wanna do please feel free too let me know!
Thanks in advance!
import java.util.Scanner;
public class Stor {
public static void main(String[] args) {
Scanner user_Input = new Scanner(System.in);
Menu user = new Menu();
EnemyValue monster = new EnemyValue();
user.namn();
user.AnvNamn = user_Input.next();
user.introMeny();
user.difficulty();
System.out.println(“Your enemy has " + monster.HP + " HP and " +
monster.DMG + " Damage" );
user_Input.close();
}
}
class Menu {
Scanner user_Input = new Scanner(System.in);
String AnvNamn;
String difficultySvar;
String nivåSvar;
int svar;
private int i; /
private int l;
public int getL() {
return l;
}
boolean difficultyLoop = true;
boolean felLoop = true;
void introMeny() {
System.out.println(“Welcome " + AnvNamn + "!");
}
void namn() {
System.out.print(“Pick a name: “);
}
void difficulty() {
do {
System.out.println("\nWhat level do you want ?\n1 = Easy.\n2 =
Medium.\n3 = Hard.”);
svar = user_Input.nextInt();
if (svar == 1) {
System.out.println(“Your not very brave are you ? Are you sure
this is how you wanna play ?”);
difficultySvar = user_Input.next();
if (difficultySvar.equalsIgnoreCase(“Yes”)) {
difficultyLoop = false;
l = 1;
} // If ja 1
else if (difficultySvar.equalsIgnoreCase(“Nej”)) {
System.out.println(“Ahh good! I figuerd you would change
your mind.”);
}
else
System.out.println(“I don’t understand….”);
} // if 1
else if (svar == 2) {
System.out.println(“Not to hard or to easy, a good choice! But
maybe you want to go for something harder ? Or maybe easier ?");
difficultySvar = user_Input.next();
if (difficultySvar.equalsIgnoreCase(“Yes”)) {
difficultyLoop = false;
l = 2;
} // if ja 2
else if (difficultySvar.equalsIgnoreCase(“No”)) {
System.out.println(“I sure hope you don’t pick the easy
way…..”);
}
else
System.out.println("I don’t understand….");
} // Else if 2
else if (svar == 3) {
System.out.println(“Damn! We have a big player here! Are you
sure you can handle this ?");
difficultySvar = user_Input.next();
if (difficultySvar.equalsIgnoreCase(“Yes”)) {
difficultyLoop = false;
l = 3;
} // If ja 3
else if (difficultySvar.equalsIgnoreCase(“No”)) {
System.out.println(“Wuss.”);
}
else
System.out.println(“I don’t understand….”);
} // Else if 3
else {
if (i == 0) {
System.out.println(“Ha you thought you could fool the system?!
The system fools you!”);
System.out.println(“Nah but seriously, you can only choose
between 1-3…..“);
i++;
} // if i 0
else if (i == 1) {
System.out.println(“Alright I get that its hard but
COMEON!”);
i++;
} // if i 1
else if (i == 2) {
System.out.println(“OKEY YOU GET ONE LAST CHANCE!!”);
i++;
} // if i 2
else if (i == 3) {
System.out.println(“Alright thats it…. GET OUT!”);
System.exit(0);
} // if i 3
} // Else
} // do while loop
while(difficultyLoop == true);
} //Difficulty metod.
} // Menu class.
class Nivå {
//Menu level = new Menu();
//int levelChoice = level.getL();
int levelChoice;
private int enemyLife;
public int getenemyLife() {
return enemyLife;
}
private int enemyDMG;
public int getenemyDMG() {
return enemyDMG;
}
Nivå(){
Menu level = new Menu();
levelChoice = level.getL();
System.out.println("testNivå");
}
void fiendeLiv() {
if (levelChoice == 1)
enemyLife = 100;
else if (levelChoice == 2)
enemyLife = 150;
else if (levelChoice == 3)
enemyLife = 200;
} // fiendeliv method
void fiendeDMG() {
if (levelChoice == 1)
enemyDMG = 5;
else if (levelChoice == 2)
enemyDMG = 10;
else if (levelChoice == 3)
enemyDMG = 15;
} // fiendeDMG method
} // Nivå class
class EnemyValue {
public int HP;
public int DMG;
int maxLife;
int maxDMG;
EnemyValue(){
Nivå stats = new Nivå();
maxLife = stats.getenemyLife();
maxDMG = stats.getenemyDMG();
System.out.println("TestEnemyValue");
}
void rank1() {
HP = maxLife;
DMG = maxDMG;
} // rank1 easy method
} // EnemyValue class
You say that when you save something in l (poor choice of a variable name, by the way) it does not save the value. How do you know that? Where in the code do you check whether the value is saved?
In the constructor for class Nivå you create a new Menu and then call getL() on that menu before you have ever set the value of that variable.
Everything runs at the start of your public static void main(String[] args) method, and nothing will run if its instructions are not in there. For example, you are not actually creating any Niva objects in the main method, so the Niva constructor is never called. That is one issue. The other is your constructors are creating new instances of objects and then getting their values; this gives you empty values from a brand new object:
Nivå(){
Menu level = new Menu(); // Don't do this. This is an empty menu
levelChoice = level.getL(); // Getting the blank L value from the empty menu
System.out.println("testNivå");
}
Instead, you need to define constructors with parameters to pass the values into the class like this:
Nivå(int level){ // add an int parameter
levelChoice = level; // Direct assignment
fiendeDMG(); // Call this in the constructor to set up your last value
System.out.println("testNivå");
}
Then, when you call the constructor (which you must if you want it to exist), include the parameter. Inside the Stor class:
public static void main(String[] args) {
Scanner user_Input = new Scanner(System.in);
Menu user = new Menu();
user.namn();
user.AnvNamn = user_Input.next();
user.introMeny();
user.difficulty(); // Run this before creating the other classes; you need the l value
Nivå niva = new Nivå(user.getL()); // Creates new Niva while also assigning l to the levelChoice and then getting DMG
EnemyValue monster = new EnemyValue(/*add some parameters for life and dmg*/);
}
There is still more that needs to be done, like modifying the constructor of the EnemyLevel. Just remember that methods are never called unless they connect to something running from main and use parameters in functions and constructors to pass on data to other objects. Hope this helps.

How to keep asking for a console input running even after program execution

I am trying to execute a program after taking user input from the console. [code block below]. However, I do not want to terminate after the program execution finishes. I want the console to always ask me the INITIAL_MESSAGE after the execution finishes. Effectively, after the execution of the program, I want the console to again ask me the INTIAL_MESSAGE so that I can again enter the inputs as I want and execute the program again.
I am actually calling the interactor() in this method, from the main method as the starting point.
Please tell me how do I achieve this
public class ConsoleInteraction {
/**
* #param args
*/
public static int numberOfJavaTrainees ;
public static int numberOfPHPTrainees ;
Barracks trainingBarrack = new Barracks();
public void interactor() throws IOException {
//reading capability from the consolemessages properties file
ResourceBundle bundle = ResourceBundle.getBundle("resources/consolemessages");
// Create a scanner so we can read the command-line input
Scanner scanner = new Scanner(System.in);
// Prompt for training or viewing camp
System.out.print(bundle.getString("INITIAL_MESSAGE"));
//Get the preference as an integer
int preference = scanner.nextInt();
//Show options based on preference
if(preference == 1)
{
//System.out.println("Whom do you want to train?\n 1.Java Guy \n 2.PHP Guy \n 3.Mix \n Enter You preference:");
System.out.print(bundle.getString("WHO_TO_TRAIN"));
int traineepreference = scanner.nextInt();
if (traineepreference == 1)
{
//System.out.println("How many Java guys you want to train ? : ");
System.out.print(bundle.getString("HOW_MANY_JAVA"));
numberOfJavaTrainees = scanner.nextInt();
trainingBarrack.trainTrainees(numberOfJavaTrainees, 0);
}
else if (traineepreference == 2)
{
//System.out.println("How many PHP guys you want to train ? : ");
System.out.print(bundle.getString("HOW_MANY_PHP"));
numberOfPHPTrainees = scanner.nextInt();
trainingBarrack.trainTrainees(0, numberOfPHPTrainees);
}
else if (traineepreference == 3)
{
System.out.print(bundle.getString("HOW_MANY_JAVA"));
numberOfJavaTrainees = scanner.nextInt();
System.out.print(bundle.getString("HOW_MANY_PHP"));
numberOfPHPTrainees = scanner.nextInt();
trainingBarrack.trainTrainees(numberOfJavaTrainees, numberOfPHPTrainees);
}
else
{
System.out.print(bundle.getString("ERROR_MESSAGE1"));
}
}
else if (preference == 2)
{
System.out.println("Showing Camp to You");
System.out.println("Java trained in Trainee Camp : "+ TraineeCamp.trainedJavaGuys);
System.out.println("PHP trained in Trainee Camp : "+ TraineeCamp.trainedPHPGuys);
}
else
{
System.out.print(bundle.getString("ERROR_MESSAGE2"));
}
scanner.close();
}
}
Consider these changes quickly drafted to your class. Might not compile. Might not work as you planned.
Some highlights of what I think you should change:
Use constants for the choice values. Makes your code way more better to read.
Initialize Bundle and Scanner outside of the method. Might be reused.
instead of coding lengthy parts of code inside of the if-else-if cascade, call methods there - angain increasing your readability a long way
public class ConsoleInteraction {
public static int numberOfJavaTrainees ;
public static int numberOfPHPTrainees ;
//Don't read that every time...
ResourceBundle bundle = ResourceBundle.getBundle("resources/consolemessages");
public static void main(String[] args) {
//Moving Scanner out of loop
try {
Scanner scanner = new Scanner(System.in);
ConsoleInteraction ci = new ConsoleInteraction();
//Loop until this returns false
while(ci.interactor(scanner)) {
System.out.println("=== Next iteration ===");
}
} catch (IOException e) {
e.printStackTrace();
}
}
//Constant values to make code readable
public final static int PREF_TRAINING = 1;
public final static int PREF_SHOW_CAMP = 2;
public final static int PREF_QUIT = 99;
public boolean interactor(Scanner scanner) throws IOException {
// Prompt for training or viewing camp
System.out.print(bundle.getString("INITIAL_MESSAGE"));
//Get the preference as an integer
int preference = scanner.nextInt();
//Show options based on preference.
if(preference == PREF_TRAINING) {
//LIKE YOU DID BEFORE OR calling method:
readTraining(scanner);
} else if (preference == PREF_SHOW_CAMP) {
//LIKE YOU DID BEFORE OR calling mathod:
showCamp();
} else if (preference == PREF_QUIT) {
//Last loop
return false;
} else {
System.out.print(bundle.getString("ERROR_MESSAGE2"));
}
//Next loop
return true;
}
}

I'm trying to call a 2 dimensional array from another class

We are trying to use the array to store the locations and then call them in the if else statements in the first class. We want to be able to call the grid locations so we do not have to type the description of the room in the if else statements.
package ProjectTwo;
import java.util.Scanner;
public class ProjectTwo {
// ----------------------------------------
// Main method, calls location (loc) method, which controls navigation
// ----------------------------------------
public static void main(String[] args){
loc();
}
// This method allows the user to view a list of actions that are used throughout the game
public static void help() {
System.out.println("Enter the letter 'n' to move north, the letter 's' to move south, or type the word 'quit' to end the game. Also, you can enter the letter 'm' to see an image of the map.");
}
// -------------------------------------
// Loc method
// Prints on-load message (intro)
// Defines global variables
// -------------------------------------
public static void loc() {
location.locMove();
int location = 0;
System.out.println("The Search" + "\n" + "\n" + "You have awoken in a laboratory. There is a door to your north and a door to your south." + "/n+" + "Enter 'n' and 's' to navigate, or type 'quit' to end the game. Also, enter the letter 'h'.");
String userInput = new String();
boolean stillPlaying = true;
// ------------------------------------
// Moves player while user is still playing
// Tells user his/her location
// ------------------------------------
while (stillPlaying) {
Scanner scan = new Scanner(System.in);
userInput = scan.nextLine();
if (location == 0){
if (userInput.equals("n")) {
System.out.println("You entered the dungeon.");
location = 1; // Moves user from location 0 to 1
}
else if (userInput.equals("s")) {
System.out.println("You cannot move south.");
location = 0; // Keeps user at location 0
} else if (userInput.equals("quit")){
System.out.println("Thanks for playing");
stillPlaying = false;
}
else if (userInput.equals("h")) {
help(); // calls the help method
}
else if (userInput.equals("m")) {
map(); // calls the map method
}
else {
System.out.println("Command not understood.");
}
} else if (location == 1) {
if (userInput.equals("n")) {
System.out.println("You have escaped out the back door of the dungeon.");
location = 2; // Moves user from location 1 to location 2
}
else if(userInput.equals("s")) {
System.out.println("You're back in the laboratory.");
location = 0; // Moves user from location 1 to location 0
} else if (userInput.equals("quit")){
System.out.println("Thanks for playing");
stillPlaying = false;
}
else if (userInput.equals("h")) {
help(); // calls the help method
}
else if (userInput.equals("m")) {
map(); // calls the map method
}
else {
System.out.println("Command not understood");
}
}
else if (location == 2) {
if (userInput.equals("n")) {
System.out.println("You cannot go that way...yet!");
location = 2; // Lets the user know that they cannot go that way
}
else if (userInput.equals("s")) {
System.out.println("You're back in the dungeon");
location = 1; // Mover from location 2 to location 1
}
else if (userInput.equals("quit")){
System.out.println("Thanks for playing");
stillPlaying = false;
}
else if (userInput.equals("h")) {
help(); // calls help method
}
else if (userInput.equals("m")) {
map(); // calls map method
}
else {
System.out.println("Command not understood.");
}
}
}
}
}
//This is our main class
-------------------------------------------------------------------------
// This is our class with the 2d array
package ProjectTwo;
public class location {
public int location;
public String name;
public static String message;
public location(String name, int location, String message){
this.name = name;
this.location = location;
this.message = message;
System.out.println(message);
}
public static void locMove() {
location [][] grid = new location[4][4];
{
grid [1][0] = new location("LABORATORY", 0, "You're in the lab.");
grid [2][0] = new location("DUNGEON", 1, "You entered the dungeon.");
grid [3][0] = new location("COURTYARD ENTRANCE",2,"You have left the dungeon out the backdoor. Either head east and search the courtyard maze, or travel north back to the dungeon");
grid [3][1] = new location("FIRST PATH", 3,"You have now entered the courtyard, either continue east or move north.");
grid [3][2] = new location("DEADEND", 4,"You have reached a deadend that has a Magic Shop. Go inside and explore it.");
grid [3][3] = new location ("MAGIC SHOP", 5, "Search around the Magic Shop and see what there is. When you're done searching continue through the maze.");
grid [2][1] = new location("SECOND PATH",6,"Search the surroundings for items that will help you get into the locked room, then keep moving.");
grid [2][2] = new location("END MAZE", 7, "You've made it to the end of the courtyard. There seems to be a cave in the distance; go check it out.");
grid [1][2] = new location("CAVE",8,"Explore the cave to find the remaining items that will lead to your freedom.");
grid [0][0] = new location("EXIT",9,"This room will lead to your freedom, but you need the three essential items that will open this door.");
}
while (grid.equals(0)) {
System.out.println(message.toString());
}
}
}
There are many ways to do what you say but look your code, think this is really fits your code without changing much but just my opinion:
"try using, Location not location to name classes but not nesesario"
package ProjectTwo;
public class location {
In Your Class location:
//Your other code
public static location [][] locMove() { // <--- change void for location [][]
location [][] grid = new location[4][4];
{
grid [1][0] = new location("LABORATORY", 0, "You're in the lab.");
grid [2][0] = new location("DUNGEON", 1, "You entered the dungeon.");
grid [3][0] = new location("COURTYARD ENTRANCE",2,"You have left the dungeon out the backdoor. Either head east and search the courtyard maze, or travel north back to the dungeon");
grid [3][1] = new location("FIRST PATH", 3,"You have now entered the courtyard, either continue east or move north.");
grid [3][2] = new location("DEADEND", 4,"You have reached a deadend that has a Magic Shop. Go inside and explore it.");
grid [3][3] = new location ("MAGIC SHOP", 5, "Search around the Magic Shop and see what there is. When you're done searching continue through the maze.");
grid [2][1] = new location("SECOND PATH",6,"Search the surroundings for items that will help you get into the locked room, then keep moving.");
grid [2][2] = new location("END MAZE", 7, "You've made it to the end of the courtyard. There seems to be a cave in the distance; go check it out.");
grid [1][2] = new location("CAVE",8,"Explore the cave to find the remaining items that will lead to your freedom.");
grid [0][0] = new location("EXIT",9,"This room will lead to your freedom, but you need the three essential items that will open this door.");
}
while (grid.equals(0)) {
System.out.println(message.toString());
}
return grid;
}
//Your other code
In your other class:
package ProjectTwo;
public class ProjectTwo {
//your other code
location [][] testGrid = null; //<--- add variable
//your other code
public static void main(String[] args){
loc();
}
//your other code
public static void loc() {
testGrid = location.locMove();
//testGrid <-- this your array
//your other code
I have not test, but I think it can work, but not the way I usually do, I hope you can help.
P.S: You could look at this, if you want https://stackoverflow.com/tour
I definitely agree with the comments about code style and formatting. Anyway here are the suggestions how you can refactor your code.
Probably the simplest way to avoid writing lots of if-else construction is to use switches. You loc() code might look something like that (I would also move duplicated h/m/quit commands to a single place):
Solution 1:
...
while (stillPlaying) {
Scanner scan = new Scanner(System.in);
userInput = scan.nextLine();
switch (userInput) {
case "quit":
System.out.println("Thanks for playing");
stillPlaying = false;
break;
case "h":
help(); // calls the help method
break;
case "m":
map(); // calls the map method
break;
case "n":
case "s":
switch (location) {
case 0:
switch (userInput) {
case "n":
System.out.println("You entered the dungeon.");
location = 1; // Moves user from location 0 to 1
break;
case "s":
System.out.println("You cannot move south.");
location = 0; // Keeps user at location 0
break;
}
break;
case 1:
switch (userInput) {
case "n":
System.out.println("You have escaped out the back door of the dungeon.");
location = 2; // Moves user from location 1 to location 2
break;
case "s":
System.out.println("You're back in the laboratory.");
location = 0; // Moves user from location 1 to location 0
break;
}
break;
case 2:
switch (userInput) {
case "n":
System.out.println("You cannot go that way...yet!");
location = 2; // Lets the user know that they cannot go that way
break;
case "s":
System.out.println("You're back in the dungeon");
location = 1; // Mover from location 2 to location 1
break;
}
break;
default:
System.out.println("no such location");
}
break;
default:
System.out.println("Command not understood.");
}
}
...
However the better way is to try to encapsulate the locations-commands-actions stuff to a different classes. That how it might look:
Solution 2:
public static interface Action {
// return the next location or an error
int action();
}
public static class LocationsMap {
public Map<Integer, Map<String, Action>> locations = new HashMap<>();
public void registerAction(int location, String userInput, Action action) {
Map<String, Action> actionsMap = locations.get(location);
if (actionsMap == null) {
actionsMap = new HashMap<>();
locations.put(location, actionsMap);
}
actionsMap.put(userInput, action);
}
public int executeAction(int location, String userInput) {
Map<String, Action> currentLocation = locations.get(location);
if (currentLocation == null) {
return -1;
}
Action currentAction = currentLocation.get(userInput);
if (currentAction == null) {
return -2;
}
return currentAction.action(); // move to next location
}
}
then you can define your actions (per location and user input) like that:
...
public static LocationsMap locationsMap = new LocationsMap();
static {
// location 0
locationsMap.registerAction(0, "n", new Action() {
#Override
public int action() {
System.out.println("You entered the dungeon.");
return 1; // Moves user from location 0 to 1
}
});
locationsMap.registerAction(0, "s", new Action() {
#Override
public int action() {
System.out.println("You cannot move south.");
return 0; // Keeps user at location 0
}
});
// location 1
locationsMap.registerAction(1, "n", new Action() {
#Override
public int action() {
System.out.println("You have escaped out the back door of the dungeon.");
return 2; // Moves user from location 1 to location 2
}
});
locationsMap.registerAction(1, "s", new Action() {
#Override
public int action() {
System.out.println("You're back in the laboratory.");
return 0; // Moves user from location 1 to location 0
}
});
// location 2
locationsMap.registerAction(2, "n", new Action() {
#Override
public int action() {
System.out.println("You cannot go that way...yet!");
return 2; // Lets the user know that they cannot go that way
}
});
locationsMap.registerAction(2, "s", new Action() {
#Override
public int action() {
System.out.println("You're back in the dungeon");
return 1; // Mover from location 2 to location 1
}
});
}
...
and then the code in the loc() function will look like that:
...
while (stillPlaying) {
Scanner scan = new Scanner(System.in);
userInput = scan.nextLine();
switch (userInput) {
case "quit":
System.out.println("Thanks for playing");
stillPlaying = false;
break;
case "h":
help(); // calls the help method
break;
case "m":
map(); // calls the map method
break;
default:
int actionResult = locationsMap.executeAction(location, userInput);
if (actionResult == -1) {
System.out.println("no such location");
break;
}
if (actionResult == -2) {
System.out.println("Command not understood.");
break;
}
location = actionResult; // move to next location
}
}
...
That is not the best solution, but it is much better and readable.
I would also define an enum for locations instead of using ints.
Also you can think about storing this locations-inputs-actions information in some file, parse it and then use in the app/game, but that will be more complicated to implement.

Categories

Resources