I'm a beginner when it comes to Java and I'm trying to find a way to see if an object is located on certain coordinates. I've tried to search for similar questions, but I still haven't found an answer.
The program I'm working on is a map (image file) and the user should be able to create places and place them on the map (which will be displayed as triangles on the map). There is also this function where the user should be able to type in coordinates to see if there already is a place on those coordinates.
The object is an object of the class "Place" and consists a name, an x-coordinate and an y-coordinate.
Here is my code:
class CoordinatesListener implements ActionListener {
public void actionPerformed(ActionEvent ave) {
try {
CoordinatesForm c = new CoordinatesForm();
int answer = c.getAnswer();
if (answer != JOptionPane.OK_OPTION) {
return;
}
if (c.getPosition() == null) {
JOptionPane.showMessageDialog(null, "Invalid Input kkk", "Invalid Input", JOptionPane.ERROR_MESSAGE);
} else {
Position p = c.getPosition();
boolean flag = false;
for (Position key : positionList.keySet()) {
if (key.getXCoordinate() == p.getXCoordinate() && key.getYCoordinate() == p.getYCoordinate()) {
flag = true;
this.setAllMarkedPlacesUnMarked();
Place place = positionList.get(key);
if (place != null) {
System.out.println("the place " + place + "against position " + key);
place.setMarked(true);
if (!place.isVisible()) {
place.setVisible(true);
}
markedPlacesHashMap.put(place.getName(), place);
if (markedPlacesHashMap.containsKey(place.getName())) {
markedPlacesHashMap.get(place.getName()).add(place);
} else {
// ArrayList<Place> newMarkedPlaces = new ArrayList<>();
// newMarkedPlaces.add(place);
markedPlacesHashMap.put(place.getName(), place);
}
}
}
}
Also, when a place is created, the user shouldn't be able to place another place on the same coordinates. There should be an error message saying that a place already exists on those coordinates.
Here is the code where a place is created:
private void createNamedPlace(int x, int y, String answer) {
Position pos = new Position(x, y);
display.add(n = new NamedPlace(selectedCategory, pos, answer));
p = n;
places = new ArrayList<>();
placeByCategory = new ArrayList<>();
positionList.put(pos, n);
if (categoryMap.containsKey(selectedCategory)) {
categoryMap.get(selectedCategory).add(n);
if (nameList.containsKey(answer)) {
nameList.get(answer).add(n);
} else {
places.add(n);
nameList.put(answer, places);
}
} else {
placeByCategory.add(n);
categoryMap.put(selectedCategory, placeByCategory);
if (nameList.containsKey(answer)) {
nameList.get(answer).add(n);
System.out.println("The new Place have been added in the Name
List, the place name is :" + answer);
this.displayMap(nameList, " PlACES LIST BY NAME");
} else {
places.add(n);
nameList.put(answer, places);
this.displayMap(nameList, "PLACES LIST BY NAME");
}
this.displayMap(categoryMap, " PlACES LIST BY CATEGORY");
}
n.addMouseListener(new TriangleListener());
display.validate();
display.repaint();
display.removeMouseListener(mouseListener);
display.setCursor(Cursor.getDefaultCursor());
newButton.setEnabled(true);
categoryList.clearSelection();
isSaved = false;
}
All Swing components are ultimately derived from the Component class, which has a method getBounds(), returning a rectangle. So you can simply write something like
if (myComponent.getBounds().contains(x,y)) {
// do something
where x and y are the co-ordinates of the point you're trying to check.
Related
As the title says, I'm having a problem with objects overlapping. I want them to be able to overlap because I need object X to be on top of object Y to get a point and if I remove object X from being on top of Y, I remove the said point. My problem then is, if object Y is created before object X, once I place object X on top of Y, I can no longer move it and it always outputs to the console, Object Y. I was wondering if there would be an easier way to fix this.
I try moving forward but the Box doesn't budge:
[
This is the code that I'm using to generate the level Data
private List<ImageTile> createLevel(){
ArrayList<Movable> aux1 = new ArrayList<>();
ArrayList<Immovable> aux2 = new ArrayList<>();
try {
Scanner sc = new Scanner(new File ("levels/level" + levelID + ".txt"));
String line = "";
while(sc.hasNextLine()) {
for (int y = 0; y < HEIGHT; y++) {
line = sc.nextLine();
for(int x = 0; x < WIDTH ; x++) {
levelObjects.add(new floor(new Point2D(x,y), "Floor", 0));//adding the floor before anything else
char letter = line.charAt(x); // checking the character in the X coordinate
if (letter == 'E') { // in case, there's a E, that's the starting position of the player
player = new Forklift(new Point2D(x,y), "Forklift_U", 2);
levelObjects.add(player);
objects.add(player);
} else if(letter != ' ') {
AbstractObject obj = ObjectCreation.readChar(letter, x, y); // going to look for the object in Factory to be put in the X and Y position
if(obj instanceof Immovable) {
aux2.add((Immovable) obj);
}else if(obj instanceof Movable) {
aux1.add((Movable) obj);
}
// comp.comprator(obj, obj);
objects.add(obj);
levelObjects.add(obj);//implementing said object into the Level
}
}
}
}
sc.close(); //Closing Scanner
} catch (FileNotFoundException e) {
System.out.println("No levels found!");
}
still = aux2;
moving = aux1;
return levelObjects;
}
Then I'm checking with the general move function if the box( or any object part of the instance Movable) can move to the next position
public void move(Direction direction) {
Vector2D pos = direction.asVector(); // Transforming the direction in a vector right off the bat.
Point2D currentPosition = getPosition(); // getting the current position of either player or object.
Point2D nextPosition = currentPosition.plus(pos); // the next position as to which the player or the object intend to go to.
if(isTransposable(nextPosition)) { // calls the function to see if the object is able to move to the next position, this prevents the boxes from pushing up into the walls and from into each other {
setPosition(nextPosition); //if it can, then the object will go to the next position
}
}
And this is to check whether or not the object can advance to the next position;
public boolean isTransposable(Point2D pos) { // is the object able to move to the next position
for(AbstractObject obj1 : Game.getInstance().getObjects()) { // for-each to get all the objects, with the exception of the floor, from the game.
if((obj1.isBlockable() && obj1.getPosition().equals(pos))){ // if the object is able to block and if it's position is the same as the nextPosition.
return false;
}
}
return true; // otherwise it's able to be walked on.
}
It was a simple case of having two lists and one having priority over the other.
In the picture, you can the box is on top of the target, but as soon as that happened, the engine would read the tile that came first, in this case being the Target one. Since that one is immovable it meant that it could not be pushed/moved by any means. Regardless if you had anything on top of it that could.
A way I used to fix it, was to simply check if the object was of class movable
public boolean isMovable(Point2D pos) {
for(AbstractObject obj1 : Game.getInstance().getObjects()) {
if((obj1.isMovable() && instanceof Movable)){
return true;
}
}
return false;
}
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.
I'm trying create a program that use dialog boxes and stores elements in Object Goals(string, int, int). This is just a home project I've decided to do during Uni holidays.
So far it's working how I planned but there is one bug I can't figure out.
//asks user to input goals and stores them in an array list
public static void setup(){
int n = 0;
int i = 0;
boolean setupFinished = false;
boolean success = false;
List<Goals> setupList = new ArrayList<Goals>();
JOptionPane setupBox = new JOptionPane();
while(!setupFinished){
Goals goal = new Goals();
String str1 = JOptionPane.showInputDialog("A goal you wish to work on?");
if(str1 == null){
System.exit(0);
}
goal.setGoal(str1);
String goalPrefInput = JOptionPane.showInputDialog("What is the initial preference of this goal compare to the others?");
if(goalPrefInput == null){
System.exit(0);
} else if (goalPrefInput.equalsIgnoreCase("")){
n = Integer.parseInt("1");
} else {
while(!success){
try {
n = (Integer.parseInt(goalPrefInput));
success = true;
}
catch (Exception NumberFormatException){
JOptionPane.showMessageDialog(null, "You must enter a valid number");
}
}
}
goal.setGoalPref(n);
System.out.println(goal.getGoalPref());
success = false;
String goalFreqInput = JOptionPane.showInputDialog("What is the frequency rate you wish this preference to increase?");
if(goalFreqInput == null){
System.exit(0);
} else if (goalFreqInput.equalsIgnoreCase("")){
n = Integer.parseInt("1");
} else {
while(!success){
try {
n = (Integer.parseInt(goalFreqInput));
success = true;
}
catch (Exception NumberFormatException){
JOptionPane.showMessageDialog(null, "You must enter a valid number");
}
}
}
goal.setGoalPrefIncrease(n);
System.out.println(goal.getGoalPrefIncrease());
setupList.add(i, goal);
i++;
int f = JOptionPane.showConfirmDialog(null, "Have you finished setup?", "Setup Finished?", YES_NO_OPTION);
if(f == JOptionPane.YES_OPTION){
setupFinished = true;
}
}
System.out.print(setupList.toString());
String s = removeBrackets(setupList.toString());
JOptionPane.showMessageDialog(setupBox, "Here are your goals \n" + s);
}
}
It's not finished but what is happening that I don't understand is that the user will enter the first instance of goal the user will put in -
goal: a, goalPref: 1, goalFreq: 1.
Then the second instance they will put in
goal: b, goalPref: 2, goalFreq: 2.
However for the second instance the goalPref that is suppose to 2 will return 1 whilst goalFreq will return a 2 correctly. If the next instance is
goal: c, goalPref: 3 goalFreq: 3.
Then it will return c, 2, 3 as the previous goalPref was 2.
The thing that confuses me is the code for entering goalPref and goalFreq is identical so why is one working and one isn't?
Here is the Goals class code:
public class Goals {
private String goal;
private int goalPref;
private int goalPrefIncrease;
public String getGoal() {
return goal;
}
public void setGoal(String goal) {
this.goal = goal;
}
public int getGoalPref() {
return goalPref;
}
public void setGoalPref(int goalPref) {
this.goalPref = goalPref;
}
public int getGoalPrefIncrease() {
return goalPrefIncrease;
}
public void setGoalPrefIncrease(int goalPrefIncrease) {
this.goalPrefIncrease = goalPrefIncrease;
}
#Override
public String toString() {
String s = "Goal: " + this.getGoal() + ", Goal Preference: " + this.getGoalPref() + ", Goal Frequency Rate: " + this.getGoalPrefIncrease();
//String s = goal + ", Goal Preference: " + goalPref + ", Goal Frequency Rate: " + goalPrefIncrease;
return s;
}
}
You should have used a debugger to see what is the mistake in your code. The problem here is your success variable which holds a key in determining value of n for your inputs.
Currently at the end of your loop it is true so in next cycle its value is still true and after entering goal pref it is not going in your while(!success) loop to determine value of n so last value of n(which is last value of goal frequency you entered) is assigned to new goal pref.
In order to correct it you need to reset value of success to false at the start of every iteration.
while(!setupFinished){
success = false;
Goals goal = new Goals();
Hope this helps.
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.
What is the best way to verify if a specific combination of two symbols is already selected in a several couples of jcomboboxes? This question is refered to a situation in which I have e. g. 10 options and for each of those I can assign a combination of two symbols where first one is from [ALT, CTRL, SHIFT] vector and second one is from [letters and numbers] vector. Both vectors are visualized in JComboBoxes (for each option are two combo boxes).
Put couples of jcomboboxes into different buckets. Those couples that have ALT selected in first combobox go to the 1st one, those who have CTRL selected - to the 2nd one, SHIFT - to the 3rd one. Then see whether the same option in the second combobox is selected within the buckets.
Thank you everyone for answers. Finally I manage this problem this way:
// Method For KeyGroup 1
public boolean isAlreadyKeyEvent(int index) {
int vector[] = {combo_1_group1.getSelectedIndex(), combo_2_group1.getSelectedIndex(), combo_n_group1.getSelectedIndex()};
int x = 0;
for (int i : vector) {
if (i == index) {
x++;
}
}
if (x > 1) {
return true;
} else {
return false;
}
}
// Method For KeyGroup 2
public boolean isAlreadyInputEvent(int index) {
int vector[] = {combo_1_group2.getSelectedIndex(), combo_2_group2.getSelectedIndex(), combo_n_group2.getSelectedIndex()};
int x = 0;
for (int i : vector) {
if (i == index) {
x++;
}
}
if (x > 1) {
return true;
} else {
return false;
}
}
combo_1_group2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean one = isAlreadyKeyEvent(combo_1_group2.getSelectedIndex());
boolean two = isAlreadyInputEvent(combo_1_group1.getSelectedIndex());
if (one) {
if (two) {
JOptionPane.showMessageDialog(null, "Such shortcut already exists! \n" +
"Choose something else.");
combo_1_group2.setSelectedIndex(Settings.combo_1_group2);
} else {
Settings.combo_1_group2 = combo_1_group2.getSelectedIndex();
}
} else {
Settings.combo_1_group2 = combo_1_group2.getSelectedIndex();
}
}
});
So basically I've wrote two quite similar methods and also I've created a new class with static fields for values store. All works great :)