1
\$\begingroup\$

The following function uses a cartesian system and has an agent who moves on the table like: F - forward, L - turn left, R - turn right.

The code works fine but I would like to make it more efficient:

import java.util.Scanner; public class HelloWorld { public static void main (String[] args) { int x = 0, y = 0; //initial coordinates int direction = 0; //initial direction Scanner scanner = new Scanner(System.in); System.out.print("Introduce the command: "); String inputString = scanner.nextLine(); //get the command for (int i = 0; i < inputString.length(); i++){ char c = inputString.charAt(i); //breaking the string into chars if(c == 'l') { //determining the direction direction++; } else if (c == 'r') { direction--; } else if (c == 'f') { if(direction < 0) { direction +=4; } if(direction % 4 ==0) { //moving forward in the wanted direction y++; } else if (direction % 4 ==1) { x--; } else if (direction % 4 == 2) { y--; } else if(direction % 4 == 3) { x++; } } } System.out.println("Result: ["+x+","+y+"]"); } } 
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Consider using two variables — an x and a y component — to store the direction. The left and right turns are based on cross product principles.

Then, each forward move can be done using unconditional additions with no modulo operations. An additional advantage is that the meaning of the direction is self-evident. (It's not immediately obvious what direction = 1 would mean in your code.)

import java.util.Scanner; public class CartesianAgent { public static void main(String[] args) { int x = 0, y = 0; int dx = 0, dy = 1; Scanner scanner = new Scanner(System.in); System.out.print("Introduce the command: "); String command = scanner.nextLine(); for (int i = 0; i < command.length(); i++) { switch (command.charAt(i)) { case 'l': int old_dx = dx; dx = -dy; dy = old_dx; break; case 'r': old_dx = dx; dx = dy; dy = -old_dx; break; case 'f': x += dx; y += dy; break; } } System.out.printf("Result: [%d,%d]%n", x, y); } } 

Alternatively, store the direction as a single integer, and use lookup tables to decode it.

According to the convention you chose, direction = 0 points up (in the +y direction), and turns left as direction increases (assuming a standard Cartesian grid that follows the right-hand rule). I consider that to be weird. You should either use

  • direction = 0 points up, then turns clockwise as direction increases (like navigation headings), or
  • direction = 0 points to the right (in the +x direction), then turns counterclockwise as direction increases (like polar coordinates).

The modulo operation should be done when turning, rather than when advancing.

import java.util.Scanner; public class CartesianAgent { private static final int[] DX = { 0, +1, 0, -1 }, DY = { +1, 0, -1, 0 }; public static void main(String[] args) { int x = 0, y = 0, direction = 0; Scanner scanner = new Scanner(System.in); System.out.print("Introduce the command: "); String command = scanner.nextLine(); for (int i = 0; i < command.length(); i++) { switch (command.charAt(i)) { case 'l': direction = (direction + 3) % 4; break; case 'r': direction = (direction + 1) % 4; break; case 'f': x += DX[direction]; y += DY[direction]; break; } } System.out.printf("Result: [%s,%s]%n", x, y); } } 

Printing the result using System.out.printf() is a bit more readable than concatenating the string using +.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ To store the direction I would recommend a Direction enum (that can be extended with things like rotateLeft and rotateRight) \$\endgroup\$ Commented Sep 26, 2018 at 9:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.