Advertisement
ernstMach

4 Knights

Nov 18th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.97 KB | None | 0 0
  1. import java.text.NumberFormat;
  2. import java.util.*;
  3. import static java.lang.System.out;
  4.  
  5. /**
  6. Let each chess-player two knights jump along, without beating each other, and without ever repeating any position,
  7. until one player stucks. The task is to evaluate the longest move period possible.
  8.  
  9. positionList grows, as long each position have up to 16 jumps left.
  10. It shrinks, as soon the positions expire their possible jumps and stuck.
  11.  */
  12. public class Jumping {
  13.     private static final Stack<Position> positionList = new Stack<>();
  14.     private static Position position;
  15.     private static long counter = 0;
  16.     private static final int BOARD = 7;
  17.  
  18.     public static void main(String args[]) {
  19.         final Player p1 = new Player(new Knight[]{new Knight(0, 1), new Knight(0, 6)});
  20.         final Player p2 = new Player(new Knight[]{new Knight(BOARD, 1), new Knight(BOARD, 6)});
  21.         position = new Position(new Player[]{p1, p2}, false);
  22.         position.generatePositionId();
  23.         out.println(run());
  24.     }
  25.  
  26.     private static List<Position> run() {
  27.         final List<Position> bestMoveList = new ArrayList<>();
  28.         boolean white, hasNext = true, firstLoop = true;
  29.         int min = 0;
  30.         while (positionList.size() > 2 || firstLoop) {
  31.             while (hasNext) {
  32.                 counter++;
  33.                 positionList.push(position);
  34.                 white = positionList.size() % 2 != 0;
  35.                 position = new Position(position.getPlayers(), white);
  36.                 hasNext = nextJump();
  37.             }
  38.             if (positionList.size() > bestMoveList.size()) {
  39.                 bestMoveList.clear();
  40.                 bestMoveList.addAll(positionList);
  41.                 min = positionList.size();
  42.                 out.print("\t ****   total valid jumps: "
  43.                         +  NumberFormat.getInstance().format(counter) +  "\n Max ... Min:  "
  44.                         + NumberFormat.getInstance().format(min));
  45.             }
  46.             while (!hasNext) {
  47.                 position = positionList.pop();
  48.                 hasNext = nextJump();
  49.             }
  50.             if (min > positionList.size()) {
  51.                 min = positionList.size();
  52.                 out.print("\t" + NumberFormat.getInstance().format(min));
  53.             }
  54.             firstLoop = false;
  55.         }
  56.         return bestMoveList;
  57.     }
  58.  
  59.     private static boolean nextJump() {
  60.         while (position.nextJump()) {
  61.             position.generatePositionId();
  62.             if (!positionList.contains(position))
  63.                 return true;
  64.             jumpBack();
  65.         }
  66.         return false;
  67.     }
  68.  
  69.     private static void jumpBack() {
  70.         position.jumpBack();
  71.     }
  72. }
  73.  
  74. class Position {
  75.  
  76.     private Player[] players = new Player[2];
  77.     private Player waitingPlayer, movingPlayer;
  78.     private boolean white;
  79.     private int positionId;
  80.  
  81.  
  82.     Position(Player[] players, boolean white) {
  83.         for (int i = 0; i < 2; i++)
  84.             this.players[i] = new Player(players[i].knights);
  85.         movingPlayer = this.players[white ? 0 : 1];
  86.         waitingPlayer = this.players[white ? 1 : 0];
  87.         this.white = white;
  88.     }
  89.  
  90.     Player[] getPlayers() {
  91.         return players;
  92.     }
  93.  
  94.     private int getPositionId() {
  95.         return positionId;
  96.     }
  97.  
  98.     boolean nextJump() {
  99.         while (movingPlayer.nextJump()) {
  100.             if (isValidPosition())
  101.                 return true;
  102.             jumpBack();
  103.         }
  104.         return false;
  105.     }
  106.  
  107.     void jumpBack() {
  108.         movingPlayer.jumpBack();
  109.     }
  110.  
  111.     void generatePositionId() {
  112.         positionId = Integer.valueOf((players[0].generatePositionId()
  113.                 + players[1].generatePositionId()).replaceAll("(\\W|\\s)", ""));
  114.     }
  115.  
  116.     private boolean isValidPosition() {
  117.         for (Knight knight : waitingPlayer.knights)
  118.             if (movingPlayer.getMovingKnight().equals(knight))
  119.                 return false;
  120.         return true;
  121.     }
  122.  
  123.     @Override
  124.     public boolean equals(Object o) {
  125.         if (this == o) return true;
  126.         if (!(o instanceof Position)) return false;
  127.  
  128.         Position position = (Position) o;
  129.  
  130.         return getPositionId() == position.getPositionId();
  131.     }
  132.  
  133.     @Override
  134.     public int hashCode() {
  135.         return getPositionId();
  136.     }
  137.  
  138.     @Override
  139.     public String toString() {
  140.         return (white ? "white" : "black") + movingPlayer.toString();
  141.     }
  142. }
  143.  
  144. /**
  145.  * White or Black
  146.  */
  147. class Player {
  148.     final Knight[] knights = new Knight[2];
  149.     private Knight movingKnight;
  150.  
  151.     Player(Knight[] knights) {
  152.         for (int i = 0; i < 2; i++)
  153.             this.knights[i] = new Knight(knights[i].getX(), knights[i].getY());
  154.     }
  155.  
  156.     Knight getMovingKnight() {
  157.         return movingKnight;
  158.     }
  159.  
  160.     final String generatePositionId() {
  161.         final Set<String> positionPlayer = new TreeSet<>();
  162.         for (Knight knight : knights)
  163.             positionPlayer.add(knight.toString());
  164.         return positionPlayer.toString();
  165.     }
  166.  
  167.     boolean nextJump() {
  168.         for (int i = 0; i < 2; i++) {
  169.             movingKnight = knights[i];
  170.             while (knights[i].nextJump()) {
  171.                 if (!movingKnight.equals(knights[1 - i]))
  172.                     return true;
  173.                 jumpBack();
  174.             }
  175.         }
  176.         return false;
  177.     }
  178.  
  179.     void jumpBack() {
  180.         movingKnight.jumpBack();
  181.     }
  182.  
  183.     @Override
  184.     public String toString() {
  185.         return " Right: " + knights[0] + " Left: " + knights[1];
  186.     }
  187. }
  188.  
  189. class Knight {
  190.     private int x, y;
  191.     private int nextJump = -1;
  192.     private final int[][] moves = {{1, 2}, {2, 1}, {-1, -2}, {-2, -1}, {-1, 2}, {-2, 1}, {1, -2}, {2, -1}};
  193.  
  194.     Knight(int x, int y) {
  195.         this.x = x;
  196.         this.y = y;
  197.     }
  198.  
  199.     final int getX() {
  200.         return x;
  201.     }
  202.  
  203.     final int getY() {
  204.         return y;
  205.     }
  206.  
  207.     private void jump() {
  208.         this.x += moves[nextJump][0];
  209.         this.y += moves[nextJump][1];
  210.     }
  211.  
  212.     void jumpBack() {
  213.         this.x -= moves[nextJump][0];
  214.         this.y -= moves[nextJump][1];
  215.     }
  216.  
  217.     boolean nextJump() {
  218.         if (nextJump > 6)
  219.             return false;
  220.         nextJump++;
  221.         jump();
  222.         if (isOutside()) {
  223.             jumpBack();
  224.             return nextJump();
  225.         }
  226.         return true;
  227.     }
  228.  
  229.     private boolean isOutside() {
  230.         return x > 7 || x < 0
  231.                 || y > 7 || y < 0;
  232.     }
  233.  
  234.     @Override
  235.     public boolean equals(Object o) {
  236.         if (this == o) return true;
  237.         if (!(o instanceof Knight)) return false;
  238.         Knight knight = (Knight) o;
  239.         return getX() == knight.getX() && getY() == knight.getY();
  240.     }
  241.  
  242.     @Override
  243.     public int hashCode() {
  244.         int result = getX();
  245.         result = 31 * result + getY();
  246.         return result;
  247.     }
  248.  
  249.     @Override
  250.     public String toString() {
  251.         return "" + (x+1) + (y+1);
  252.         //return ((char) (y + (int) 'A')) + "-" + (x + 1);
  253.     }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement