Advertisement
CaptainSpaceCat

ElectricRunner - Board

Apr 14th, 2017
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.91 KB | None | 0 0
  1. import java.lang.Math;
  2. import java.util.ArrayList;
  3.  
  4. public class Board {
  5.   private Tile[][] board;
  6.   private int w, h;
  7.   private int[][] refTab = {
  8.     {-1, 0},
  9.     {0, 1},
  10.     {1, 0},
  11.     {0, -1}
  12.   };
  13.  
  14.   public Board() {
  15.     board = new Tile[4][4];
  16.     w = 4;
  17.     h = 4;
  18.     generateNewBoard(0);
  19.   }
  20.  
  21.   public Board(int x, int y, int t) {
  22.     board = new Tile[x][y];
  23.     w = x;
  24.     h = y;
  25.     generateNewBoard(t);
  26.   }
  27.  
  28.   public int[] getDimensions() {
  29.     return new int[] {w, h};
  30.   }
  31.  
  32.   public Tile getTile(int x, int y) {
  33.     return board[x][y];
  34.   }
  35.  
  36.   public int size() {
  37.     return board.length * board[0].length;
  38.   }
  39.  
  40.   public void rotateTile(int x, int y) {
  41.     board[x][y].rotate();
  42.   }
  43.  
  44.   public void slideTile(int x, int y, int a, int b) {
  45.     board[a][b].copyProperties(board[x][y]);
  46.     board[x][y].setPresent(false);
  47.   }
  48.  
  49.   public void generateNewBoard(int t) { //0-slideboard 1-rotateboard
  50.     initializeBoard();
  51.     if (t==0) {
  52.       generateSlideBoard();
  53.     } else if (t==1) {
  54.       generateRotateBoard();
  55.     }
  56.   }
  57.  
  58.   private void initializeBoard() {
  59.     for (int x = 0; x < w; x++) {
  60.       for (int y = 0; y < h; y++) {
  61.         board[x][y] = new Tile();
  62.       }
  63.     }
  64.   }
  65.  
  66.   private void generateRotateBoard() {
  67.    
  68.   }
  69.  
  70.   private void generateSlideBoard() {
  71.     int[] startTile = chooseEndpoint();
  72.     //System.out.println(startTile[0] + ":" + startTile[1] + "--" + startTile[2]);
  73.     board[startTile[0]][startTile[1]].setProperties(3, startTile[2]);
  74.     board[startTile[0]][startTile[1]].setPresent(false);
  75.     board[startTile[0]][startTile[1]].setBolted(true);
  76.     ArrayList<int[]> stack = new ArrayList<int[]>();
  77.     stack.add(startTile);
  78.     int[] currentTile = new int[] {startTile[0]+refTab[startTile[2]][0], startTile[1]+refTab[startTile[2]][1]};
  79.     board[currentTile[0]][currentTile[1]].setPresent(false);
  80.     int solsize = (int)(size()*.5) + random(-1, 2);
  81.     while (stack.size() < solsize) {
  82.      
  83.       int[] choice = choosePathTile(currentTile);
  84.       if (choice != null) {
  85.         //System.out.println("> " + currentTile[0] + ":" + currentTile[1]);
  86.         stack.add(currentTile);
  87.         board[choice[0]][choice[1]].setPresent(false);
  88.         currentTile = choice;
  89.         if (stack.size() == solsize-1) {
  90.           stack.add(currentTile);
  91.           break;
  92.         }
  93.       } else {
  94.         currentTile = stack.remove(stack.size()-1);
  95.         //System.out.println("< " + currentTile[0] + ":" + currentTile[1]);
  96.       }
  97.     }
  98.     board[startTile[0]][startTile[1]].setPresent(true);
  99.     for (int i = 0; i < 4; i++) {
  100.       if (stack.get(stack.size()-1)[0] + refTab[i][0] == stack.get(stack.size()-2)[0] && stack.get(stack.size()-1)[1] + refTab[i][1] == stack.get(stack.size()-2)[1]) {
  101.         board[stack.get(stack.size()-1)[0]][stack.get(stack.size()-1)[1]].setProperties(4, i);
  102.       }
  103.     }
  104.     board[stack.get(stack.size()-1)[0]][stack.get(stack.size()-1)[1]].setBolted(true);
  105.     for (int i = 1; i < stack.size()-1; i++) {
  106.       board[stack.get(i)[0]][stack.get(i)[1]].setProperties(getProperties(stack.get(i-1), stack.get(i), stack.get(i+1)));
  107.     }
  108.     for (int x = 0; x < w; x++) {
  109.       for (int y = 0; y < h; y++) {
  110.         board[x][y].setPresent(true);
  111.       }
  112.     }
  113.    
  114.     int remainder = size() - solsize - 1;
  115.    
  116.     removeRandomTiles((int)Math.ceil(remainder*(random(6, 7)/10.0)));
  117.     wireRandomTiles((int)Math.ceil(remainder*(random(0, 2)/10.0)));
  118.     boltRandomTiles((int)Math.ceil(remainder*(random(1, 4)/20.0)));
  119.   }
  120.  
  121.   private void removeRandomTiles(int total) {
  122.     int num = 0;
  123.     while (num < total) {
  124.       int[] pos = {random(0, w-1), random(0, h-1)};
  125.       if (board[pos[0]][pos[1]].getType() == 0 && board[pos[0]][pos[1]].isPresent()) {
  126.         board[pos[0]][pos[1]].setPresent(false);
  127.         num++;
  128.       }
  129.     }
  130.   }
  131.  
  132.   private void wireRandomTiles(int total) {
  133.     int num = 0;
  134.     while (num < total) {
  135.       int[] pos = {random(0, w-1), random(0, h-1)};
  136.       if (board[pos[0]][pos[1]].getType() == 0 && board[pos[0]][pos[1]].isPresent()) {
  137.         board[pos[0]][pos[1]].setType(random(1, 2));
  138.         board[pos[0]][pos[1]].setOrientation(random(0, 3));
  139.         num++;
  140.       }
  141.     }
  142.   }
  143.  
  144.   private void boltRandomTiles(int total) {
  145.     int num = 0;
  146.     while (num <= total) {
  147.       int[] pos = {random(0, w-1), random(0, h-1)};
  148.       if (!(board[pos[0]][pos[1]].isBolted()) && board[pos[0]][pos[1]].isPresent()) {
  149.         board[pos[0]][pos[1]].setBolted(true);
  150.         if (!boltFill()) {
  151.           board[pos[0]][pos[1]].setBolted(false);
  152.           num--;
  153.         }
  154.         num++;
  155.       }
  156.     }
  157.   }
  158.  
  159.   public boolean boltFill() {
  160.     clearFlags();
  161.     boolean filling = true;
  162.     int total = 1;
  163.     int bolted = 0;
  164.     int[] startPos = new int[] {0, 0};
  165.     for (int a = 0; a < 5; a++) {
  166.       for (int b = 0; b < 5; b++) {
  167.         if (board[a][b].isBolted()) {
  168.           bolted++;
  169.         } else {
  170.           startPos = new int[] {a, b};
  171.         }
  172.       }
  173.     }
  174.     board[startPos[0]][startPos[1]].setFlagged(true);
  175.     while (filling) {
  176.       filling = false;
  177.       for (int a = 0; a < 5; a++) {
  178.         for (int b = 0; b < 5; b++) {
  179.           if (board[a][b].isFlagged()) {
  180.             for (int i = 0; i < 4; i++) {
  181.               if (a+refTab[i][0] >= 0 && a+refTab[i][0] < w && b+refTab[i][1] >= 0 && b+refTab[i][1] < h) {
  182.                 if (!board[a+refTab[i][0]][b+refTab[i][1]].isBolted() && !board[a+refTab[i][0]][b+refTab[i][1]].isFlagged()) {
  183.                   board[a+refTab[i][0]][b+refTab[i][1]].setFlagged(true);
  184.                   filling = true;
  185.                   total++;
  186.                 }
  187.               }
  188.             }
  189.           }
  190.         }
  191.       }
  192.     }
  193.     for (int a = 0; a < 5; a++) {
  194.       for (int b = 0; b < 5; b++) {
  195.         board[a][b].setFlagged(false);
  196.       }
  197.     }
  198.     //System.out.println((total+bolted) + "");
  199.     clearFlags();
  200.     return (total+bolted) == 25;
  201.   }
  202.  
  203.   public boolean checkWin() {
  204.     int[] startPos = {0, 0};
  205.     for (int x = 0; x < w; x++) {
  206.       for (int y = 0; y < h; y++) {
  207.         if (board[x][y].getType() == 3) {
  208.           startPos[0] = x;
  209.           startPos[1] = y;
  210.         }
  211.       }
  212.     }
  213.     int[] currentTile = {startPos[0], startPos[1]};
  214.     int prevOrientation = -1;
  215.     while (true) {
  216.       int type = board[currentTile[0]][currentTile[1]].getType();
  217.       int orientation = board[currentTile[0]][currentTile[1]].getOrientation();
  218.       if (!board[currentTile[0]][currentTile[1]].isPresent()) {
  219.         break;
  220.       }
  221.       if (type == 3) {
  222.         if (prevOrientation == -1) {
  223.           prevOrientation = (orientation+2)%4;
  224.           currentTile = new int[] {currentTile[0]+refTab[orientation][0], currentTile[1]+refTab[orientation][1]};
  225.         } else {
  226.           break;
  227.         }
  228.       } else if (type == 1) {
  229.         int onward;
  230.         if (prevOrientation == orientation) {
  231.           onward = (orientation+2)%4;
  232.         } else if (prevOrientation == (orientation+2)%4) {
  233.           onward = orientation;
  234.         } else {
  235.           break;
  236.         }
  237.         if (currentTile[0]+refTab[onward][0] < 0 || currentTile[0]+refTab[onward][0] >= w || currentTile[1]+refTab[onward][1] < 0 || currentTile[1]+refTab[onward][1] >= h) {
  238.           break;
  239.         }
  240.         prevOrientation = (onward+2)%4;
  241.         currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
  242.       } else if (type == 2) {
  243.         int onward;
  244.         if (prevOrientation == orientation) {
  245.           onward = (orientation+1)%4;
  246.         } else if (prevOrientation == (orientation+1)%4) {
  247.           onward = orientation;
  248.         } else {
  249.           break;
  250.         }
  251.         if (currentTile[0]+refTab[onward][0] < 0 || currentTile[0]+refTab[onward][0] >= w || currentTile[1]+refTab[onward][1] < 0 || currentTile[1]+refTab[onward][1] >= h) {
  252.           break;
  253.         }
  254.         prevOrientation = (onward+2)%4;
  255.         currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
  256.       } else if (type == 4) {
  257.         if (orientation == prevOrientation) {
  258.           //System.out.println("Win condition - true");
  259.           return true;
  260.         }
  261.         break;
  262.       } else {
  263.         break;
  264.       }
  265.     }
  266.     //System.out.println("Win condition - false");
  267.     return false;
  268.   }
  269.  
  270.   public int getExcessTiles() {
  271.     int totalTiles = 0;
  272.     int[] startPos = {0, 0};
  273.     for (int x = 0; x < w; x++) {
  274.       for (int y = 0; y < h; y++) {
  275.         if (board[x][y].getType() == 3) {
  276.           startPos[0] = x;
  277.           startPos[1] = y;
  278.         }
  279.         if ((board[x][y].getType() == 1 || board[x][y].getType() == 2) && board[x][y].isPresent()) {
  280.           totalTiles++;
  281.         }
  282.       }
  283.     }
  284.     //System.out.println(totalTiles);
  285.     int[] currentTile = {startPos[0], startPos[1]};
  286.     int prevOrientation = 0;
  287.     int solutionTiles = 0;
  288.     while (true) {
  289.       solutionTiles++;
  290.       int type = board[currentTile[0]][currentTile[1]].getType();
  291.       int orientation = board[currentTile[0]][currentTile[1]].getOrientation();
  292.       if (!board[currentTile[0]][currentTile[1]].isPresent()) {
  293.         break;
  294.       }
  295.       if (type == 3) {
  296.         prevOrientation = (orientation+2)%4;
  297.         currentTile = new int[] {currentTile[0]+refTab[orientation][0], currentTile[1]+refTab[orientation][1]};
  298.       } else if (type == 1) {
  299.         int onward;
  300.         if (prevOrientation == orientation) {
  301.           onward = (orientation+2)%4;
  302.         } else if (prevOrientation == (orientation+2)%4) {
  303.           onward = orientation;
  304.         } else {
  305.           break;
  306.         }
  307.         if (currentTile[0]+refTab[onward][0] < 0 || currentTile[0]+refTab[onward][0] >= w || currentTile[1]+refTab[onward][1] < 0 || currentTile[1]+refTab[onward][1] >= h) {
  308.           break;
  309.         }
  310.         prevOrientation = (onward+2)%4;
  311.         currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
  312.       } else if (type == 2) {
  313.         int onward;
  314.         if (prevOrientation == orientation) {
  315.           onward = (orientation+1)%4;
  316.         } else if (prevOrientation == (orientation+1)%4) {
  317.           onward = orientation;
  318.         } else {
  319.           break;
  320.         }
  321.         if (currentTile[0]+refTab[onward][0] < 0 || currentTile[0]+refTab[onward][0] >= w || currentTile[1]+refTab[onward][1] < 0 || currentTile[1]+refTab[onward][1] >= h) {
  322.           break;
  323.         }
  324.         prevOrientation = (onward+2)%4;
  325.         currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
  326.       } else if (type == 4) {
  327.         if (orientation == prevOrientation) {
  328.           break;
  329.         }
  330.         break;
  331.       } else {
  332.         break;
  333.       }
  334.     }
  335.     //System.out.println(solutionTiles);
  336.     return totalTiles - (solutionTiles - 2);
  337.   }
  338.  
  339.   private int[] getProperties(int[] a, int[] x, int[] b) {
  340.     int relA = -1;
  341.     int relB = -1;
  342.     for (int i = 0; i < 4; i++) {
  343.       if (x[0] + refTab[i][0] == a[0] && x[1] + refTab[i][1] == a[1]) {
  344.         relA = i;
  345.       }
  346.       if (x[0] + refTab[i][0] == b[0] && x[1] + refTab[i][1] == b[1]) {
  347.         relB = i;
  348.       }
  349.     }
  350.     if (relA%2 == relB%2) {
  351.       return new int[] {1, relA%2};
  352.     } else {
  353.       if (Math.abs(relA-relB) == 3) {
  354.         return new int[] {2, 3};
  355.       }
  356.       return new int[] {2, Math.min(relA, relB)};
  357.     }
  358.   }
  359.  
  360.   private int[] choosePathTile(int[] pos) {
  361.     boolean[] flag = {true, true, true, true};
  362.     for (int i = 0; i < 4; i++) {
  363.       if (pos[0] + refTab[i][0] < 0 || pos[0] + refTab[i][0] == w || pos[1] + refTab[i][1] < 0 || pos[1] + refTab[i][1] == h || !(board[pos[0]+refTab[i][0]][pos[1]+refTab[i][1]].isPresent())) {
  364.         flag[i] = false;
  365.       }
  366.     }
  367.     int c = 0;
  368.     for (int i = 0; i < 4; i++) {
  369.       if (flag[i]) {
  370.         c++;
  371.       }
  372.     }
  373.     if (c == 0) {
  374.       return null;
  375.     }
  376.     int[] options = new int[c];
  377.     c = 0;
  378.     for (int i = 0; i < 4; i++) {
  379.       if (flag[i]) {
  380.         options[c] = i;
  381.         c++;
  382.       }
  383.     }
  384.     int choice = options[random(0, options.length-1)];
  385.     return new int[] {pos[0]+refTab[choice][0], pos[1]+refTab[choice][1]};
  386.   }
  387.  
  388.   public void shuffle(int num) {
  389.     int c = 0;
  390.     while (c < num) {
  391.       ArrayList<int[]> options = new ArrayList<int[]>();
  392.       for (int x = 0; x < w; x++) {
  393.         for (int y = 0; y < h; y++) {
  394.           for (int i = 0; i < 4; i++) {
  395.             if (!(board[x][y].isBolted()) && board[x][y].isPresent()) {
  396.               if (x+refTab[i][0] >= 0 && x+refTab[i][0] < w && y+refTab[i][1] >= 0 && y+refTab[i][1] < h) {
  397.                 if (!(board[x+refTab[i][0]][y+refTab[i][1]].isPresent())) {
  398.                   options.add(new int[] {x, y, i});
  399.                 }
  400.               }
  401.             }
  402.           }
  403.         }
  404.       }
  405.       int[] choice = options.get(random(0, options.size()-1));
  406.       slideTile(choice[0], choice[1], choice[0]+refTab[choice[2]][0], choice[1]+refTab[choice[2]][1]);
  407.       c++;
  408.     }
  409.   }
  410.  
  411.   public int floodFill(int x, int y) {
  412.     boolean filling = true;
  413.     int total = 0;
  414.     clearFlags();
  415.     board[y][x].setFlagged(true);
  416.     while (filling) {
  417.       filling = false;
  418.       for (int a = 0; a < 5; a++) {
  419.         for (int b = 0; b < 5; b++) {
  420.           if (board[a][b].isFlagged()) {
  421.             for (int i = 0; i < 4; i++) {
  422.               if (a+refTab[i][0] >= 0 && a+refTab[i][0] < w && b+refTab[i][1] >= 0 && b+refTab[i][1] < h) {
  423.                 if (!board[a+refTab[i][0]][b+refTab[i][1]].isPresent() && !board[a+refTab[i][0]][b+refTab[i][1]].isFlagged()) {
  424.                   board[a+refTab[i][0]][b+refTab[i][1]].setFlagged(true);
  425.                   filling = true;
  426.                   total++;
  427.                 }
  428.               }
  429.             }
  430.           }
  431.         }
  432.       }
  433.     }
  434.     board[y][x].setFlagged(false);
  435.     return total;
  436.   }
  437.  
  438.   public void clearFlags() {
  439.     for (int a = 0; a < w; a++) {
  440.       for (int b = 0; b < h; b++) {
  441.         board[a][b].setFlagged(false);
  442.       }
  443.     }
  444.   }
  445.  
  446.  
  447.  
  448.   private int[] chooseEndpoint() {
  449.     int[] pos = {random(0, w-1), random(0, h-1)};
  450.     boolean[] flag = {true, true, true, true};
  451.     if (pos[0] == 0) {
  452.       flag[0] = false;
  453.     }
  454.     if (pos[0] == w-1) {
  455.       flag[2] = false;
  456.     }
  457.     if (pos[1] == 0) {
  458.       flag[3] = false;
  459.     }
  460.     if (pos[1] == h-1) {
  461.       flag[1] = false;
  462.     }
  463.     int c = 0;
  464.     for (int i = 0; i < 4; i++) {
  465.       if (flag[i]) {
  466.         c++;
  467.       }
  468.     }
  469.     int[] options = new int[c];
  470.     c = 0;
  471.     for (int i = 0; i < 4; i++) {
  472.       if (flag[i]) {
  473.         options[c] = i;
  474.         c++;
  475.       }
  476.     }
  477.     int orientation = options[random(0, options.length-1)];
  478.     return new int[] {pos[0], pos[1], orientation};
  479.   }
  480.  
  481.   private int random(int a, int b) {
  482.     return (int)(Math.random()*(b-a+1))+a;
  483.   }
  484.  
  485.   public String toString() {
  486.     String output = "";
  487.     for (int x = 0; x < w; x++) {
  488.       for (int y = 0; y < h; y++) {
  489.         if (board[x][y].isBolted()) {
  490.           output += "{";
  491.         } else {
  492.           output += "[";
  493.         }
  494.         if (!(board[x][y].isPresent())) {
  495.           output += ".";
  496.         } else {
  497.           if (board[x][y].getType() == 0) {
  498.             output += " ";
  499.           } else if (board[x][y].getType() == 1) {
  500.             if (board[x][y].getOrientation()%2 == 0) {
  501.               output += "|";
  502.             } else {
  503.               output += "-";
  504.             }
  505.           } else if (board[x][y].getType() == 2) {
  506.             if (board[x][y].getOrientation() == 0) {
  507.               output += "L";
  508.             } else if (board[x][y].getOrientation() == 1) {
  509.               output += "F";
  510.             } else if (board[x][y].getOrientation() == 2) {
  511.               output += "7";
  512.             } else if (board[x][y].getOrientation() == 3) {
  513.               output += "J";
  514.             }
  515.           } else if (board[x][y].getType() == 3) {
  516.             if (board[x][y].getOrientation() == 0) {
  517.               output += "^";
  518.             } else if (board[x][y].getOrientation() == 1) {
  519.               output += ">";
  520.             } else if (board[x][y].getOrientation() == 2) {
  521.               output += "V";
  522.             } else if (board[x][y].getOrientation() == 3) {
  523.               output += "<";
  524.             }
  525.           }  else if (board[x][y].getType() == 4) {
  526.             if (board[x][y].getOrientation() == 0) {
  527.               output += "U";
  528.             } else if (board[x][y].getOrientation() == 1) {
  529.               output += "C";
  530.             } else if (board[x][y].getOrientation() == 2) {
  531.               output += "A";
  532.             } else if (board[x][y].getOrientation() == 3) {
  533.               output += ")";
  534.             }
  535.           }
  536.         }
  537.         if (board[x][y].isBolted()) {
  538.           output += "}";
  539.         } else {
  540.           output += "]";
  541.         }
  542.       }
  543.       output += "\n";
  544.     }
  545.     return output;
  546.   }
  547.  
  548. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement