Sea battle. I am writing a method for turning the ship.

tt is the current position of the ship:

0 - vertically (by default)

1 - horizontally (0 + 90 °)

2 - vertically (0 upside down)

3 - horizontally (0 - 90 °)

ckw is the turn flag:

true - clockwise

false - counterclockwise

Rotation method code:

 public void turn (boolean ckw) { if ((tt == 0 && !ckw) || (tt == 1 && ckw)) { //b -> c } else if ((tt == 1 && !ckw) || (tt == 2 && ckw)) { //c -> d } else if ((tt == 2 && !ckw) || (tt == 3 && ckw)) { //d -> a } else if ((tt == 3 && !ckw) || (tt == 0 && ckw)) { //a -> b } if (ckw) tt++; else tt--; } 

The comments indicate 4 for-each with a reversal logic. I’d like to cut this ladder of ifs. Is it possible

Rotation logic

The ship is an ArrayList positions in the grid. For example, 4-deck, located in the middle of the field: 35, 45, 55, 65 . To turn it clockwise, you must add to each position its index multiplied by 11 .

b -> c (90 ° -> 180 °) or (0 ° -> 270 °)

 for (int i = 0; i < col.size(); i++) { int num = col.get(i); int new_num = num + 11 * i; col.set(i, new_num); } 

Etc.

  • one
    who are b -> c , c -> d and other animals? and what is the вертикально (0 вверх ногами) ? What are the legs of the ships? - Alexey Shimansky
  • Comments? Do not pay attention to them, it's not about them. Ship upside down? And how can this be explained? Twice clockwise to turn 45 ° here to you and upside down - Flippy
  • And what does the code of the turn look like? It is possible that these four turns ( a -> b and others) can be combined into a single code and there will be no need for an if-else (or switch-case ) at all. - Regent
  • It is also not clear why for tt == 0 && !ckw and tt == 1 && ckw same turn code, if in the first case it is a turn from 0 to 270 degrees, and in the second case - from 90 to 180. - Regent
  • @Regent Вполне возможно, что эти четыре поворота (a -> b и другие) можно объединить в единый код - yes, thank you for expressing it for me)) And I wanted to cut the clues in the comments in the comment ...) - Alexey Shimansky

3 answers 3

We store only the base coordinates, the length and the current state of the turn.
Everything else is calculated from this data.

Demo on the knee:

 public class Main { public static void main(String[] args) { Ship ship = new Ship(4, 1, 3, 5); // 35, ship.print(); System.out.println("Clockwise"); ship.turn(true).print(); ship.turn(true).print(); ship.turn(true).print(); ship.turn(true).print(); System.out.println("Counter-clockwise"); ship.turn(false).print(); ship.turn(false).print(); ship.turn(false).print(); ship.turn(false).print(); } } public class Ship { private int state; private int x; private int y; private int length; public Ship(int length, int initialState, int x, int y) { state = initialState; this.x = x; this.y = y; this.length = length; } public Ship turn(boolean clockwise) { if (clockwise) { state = (state + 1) % 4; } else { state = (state + 3) % 4; } return this; } public Ship print() { for (int i = 0; i < length; i++) { switch (state) { case 0: System.out.print("("+(10*x+yi)+")"); break; // N case 1: System.out.print("("+(10*(x+i)+y)+")"); break; // E case 2: System.out.print("("+(10*x+y+i)+")"); break; // S case 3: System.out.print("("+(10*(xi)+y)+")"); break; // W } } System.out.println(""); return this; } } 
  • Hmm .... what is most terrible: the very first inadequate answer of another participant hangs with 5 pluses ... - Alexey Shimansky

We perform this or that operation if tt == n and ckw == false or tt == n + 1 and ckw == true . Therefore, if for the case ckw == false we increase the compared value by 1, then later we will need to check only the case tt == n + 1 . Such a chain of checks is easy to organize using the switch operator.

Update as corrected me @vp_arth instead of switch (val) it is better to use switch (val % 4) . Then you can remove the case 4: check case 4:

 public void turn(boolean ckw) { int val = tt; if (!ckw) val++; switch (val % 4) { case 1: //b -> c break; case 2: //c -> d break; case 3: //d -> a break; case 0: //a -> b break; } if (ckw) tt++ else tt--; } 
  • Comments are not intended for extended discussion; conversation moved to chat . - Nick Volynkin

If you do not deviate from the fact that the coordinates of the ship are stored in the ArrayList , you can do so. In the turn method, a new tt value is calculated, after which the coordinates of the ship are calculated anew taking into account the new tt value and the fixed point of the ship (for example, the head).

 public void turn(boolean ckw) { tt += ckw ? 1 : -1; tt = (tt + 4) % 4; int sign = (tt == 1 || tt == 2) ? 1 : -1; int shift = (tt % 2 == 0) ? 10 : 1; int head = col.get(0); for (int i = 1; i < col.size(); i++) { int newNum = head + sign * shift * i; col.set(i, newNum); } } 

It is assumed that ships can only be in one line. It also does not take into account the fact that after turning the ship can "go" beyond the edge of the field.