Reputation: 35
I have to create a java class where I can read some commands from standard console. It's like to simulate a movement into a grid. I have some difficult to create exactly what I want. Let's say that I have this commands:
"X" and "Y" are coordinates of a matrix 6x6. "DIRECTION" can be "UP","DOWN","LEFT","RIGHT". If I write "STEP" I'll do one step.
The program should discard STEP command until a valid START command has been executed. After that, I can use STEP or another valid START command that it will put "1" using the new coordinates removing the first one.
Examples:
a)START 1,4,UP ---> OK! ANOTHER START OR STEP COMMAND
STEP ---> OK MOVE!
b)START 3,5,UP ---> OK! ANOTHER START OR STEP COMMAND
START 5,2,LEFT ---> DONE! OK NEW POSITION!
STEP ---> OK MOVE!
c)STEP ---> NO! I NEED START
OWINEVEIVNEW ---> NO! I NEED START
START 3,2,RIGHT ---> OK! ANOTHER START OR STEP COMMAND
I have to catch also coordinates (X,Y) and DIRECTION if I have a START command.
My idea is:
public static void main(String[] args) {
Movement grid = new Movement(6); --> call constructor. 6 is dimension square grid
System.out.println("**********INSERT COMMANDS**********");
while(true){ --> loop to continue to insert commands
if (grid.startCommand()) {
System.out.println("OK START RECEIVED! I CAN USE STEP");
grid.stepForward();
} else {
System.out.println("I can't go ahead without valid START command. Try again!");
};
}
}
public boolean stepForward() {
if (start.equals("STEP") {
System.out.println("OK LET'S DO A STEP!!");
}
return true;
}
public boolean startCommand() {
Scanner sc = new Scanner(System.in);
String start = sc.next();
sc.useDelimiter("\\s+");
String[] coordinates = sc.next().split(",");
X = Integer.parseInt(coordinates[0]);
Y = Integer.parseInt(coordinates[1]);
direction = coordinates[2];
while(start.equals("START")) {
if ((0<=X && X<dim) && (0<=Y && Y<dim)){
if (direction.equals("UP")||direction.equals("DOWN")||direction.equals("LEFT")||direction.equals("RIGHT")){
cleanGrid(); --> this is just a method that put everything at 0
matrix[X][Y] = 1;
return true;
} else {
System.out.println("Your direction doesn't exist. Use \"UP\",\"DOWN\",\"LEFT\",\"RIGHT\".Try again!");
return false;
}
} else {
System.out.println("Check range of X and Y. Try again!");
return false;
}
}
System.out.println("Insert command like ex. \"START 1,2,UP\". Try again!");
return false;
}
Yes, I'm lost between IF,WHILE, etc... I tried different solutions but or I lose the possibility to insert another START or I can't recognize STEP command or other kind of problems. Can someone help me to figure out with this please?? Thanks in advance.
Upvotes: 1
Views: 553
Reputation: 347314
Think about your problem differently...
This would suggest you need to identify the command the user input before you can execute the logic behind the command, for example...
Scanner scanner = new Scanner(System.in);
boolean exit = false;
do {
System.out.print("CMD> ");
String input = scanner.nextLine();
if ("exit".equalsIgnoreCase(input)) {
exit = true;
} else if (input.toLowerCase().startsWith("start")) {
doStart(input);
} else if (input.toLowerCase().startsWith("step")) {
doStep(input);
}
} while (!exit);
Once you know the command the user has entered, you know which method to execute to perform the command.
Then, based on the command, you may need to parse the parameters and process it...
protected void doStart(String input) {
Scanner scanner = new Scanner(input);
scanner.next(); // Command
String parameters[] = scanner.next().split(",");
int x = Integer.parseInt(parameters[0]);
int y = Integer.parseInt(parameters[1]);
String dir = parameters[2];
System.out.println(" > start @ " + x + "x" + y + " in " + dir + " direction");
}
Like your code say I can write "start 2,3,up" and go ahead with a "step" but I can write also "step" like first command
You need to something that can maintain the current state, as an example...
public class BotPos {
private int x;
private int y;
private String direction;
public BotPos(int x, int y, String direction) {
this.x = x;
this.y = y;
this.direction = direction;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
@Override
public String toString() {
return " > Bot is @ " + x + "x" + y + " in " + direction + " direction";
}
}
Assuming that botPos
is a class instance field, then do start would set this state...
protected void doStart(String input) {
Scanner scanner = new Scanner(input);
scanner.next(); // Command
String parameters[] = scanner.next().split(",");
int x = Integer.parseInt(parameters[0]);
int y = Integer.parseInt(parameters[1]);
String dir = parameters[2];
botPos = new BotPos(x, y, dir);
System.out.println(botPos);
}
And doStep
would update it if it can...
protected void doStep(String input) {
if (botPos != null) {
switch (botPos.getDirection().toLowerCase()) {
case "up":
botPos.setY(botPos.getY() - 1);
break;
case "down":
botPos.setY(botPos.getY() + 1);
break;
case "left":
botPos.setX(botPos.getX() - 1);
break;
case "right":
botPos.setX(botPos.getX() + 1);
break;
}
System.out.println(botPos);
} else {
System.out.println(" > Invalid state, you have no start position");
}
}
Now, you could also pass the botPos
to the methods, but the idea is the same.
If required, you would simply set botPos
to null
to invalidate it
Upvotes: 1