Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.lang.Math;
- import java.util.ArrayList;
- public class Board {
- private Tile[][] board;
- private int w, h;
- private int[][] refTab = {
- {-1, 0},
- {0, 1},
- {1, 0},
- {0, -1}
- };
- public Board() {
- board = new Tile[4][4];
- w = 4;
- h = 4;
- generateNewBoard(0);
- }
- public Board(int x, int y, int t) {
- board = new Tile[x][y];
- w = x;
- h = y;
- generateNewBoard(t);
- }
- public int[] getDimensions() {
- return new int[] {w, h};
- }
- public Tile getTile(int x, int y) {
- return board[x][y];
- }
- public int size() {
- return board.length * board[0].length;
- }
- public void rotateTile(int x, int y) {
- board[x][y].rotate();
- }
- public void slideTile(int x, int y, int a, int b) {
- board[a][b].copyProperties(board[x][y]);
- board[x][y].setPresent(false);
- }
- public void generateNewBoard(int t) { //0-slideboard 1-rotateboard
- initializeBoard();
- if (t==0) {
- generateSlideBoard();
- } else if (t==1) {
- generateRotateBoard();
- }
- }
- private void initializeBoard() {
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- board[x][y] = new Tile();
- }
- }
- }
- private void generateRotateBoard() {
- }
- private void generateSlideBoard() {
- int[] startTile = chooseEndpoint();
- //System.out.println(startTile[0] + ":" + startTile[1] + "--" + startTile[2]);
- board[startTile[0]][startTile[1]].setProperties(3, startTile[2]);
- board[startTile[0]][startTile[1]].setPresent(false);
- board[startTile[0]][startTile[1]].setBolted(true);
- ArrayList<int[]> stack = new ArrayList<int[]>();
- stack.add(startTile);
- int[] currentTile = new int[] {startTile[0]+refTab[startTile[2]][0], startTile[1]+refTab[startTile[2]][1]};
- board[currentTile[0]][currentTile[1]].setPresent(false);
- int solsize = (int)(size()*.5) + random(-1, 2);
- while (stack.size() < solsize) {
- int[] choice = choosePathTile(currentTile);
- if (choice != null) {
- //System.out.println("> " + currentTile[0] + ":" + currentTile[1]);
- stack.add(currentTile);
- board[choice[0]][choice[1]].setPresent(false);
- currentTile = choice;
- if (stack.size() == solsize-1) {
- stack.add(currentTile);
- break;
- }
- } else {
- currentTile = stack.remove(stack.size()-1);
- //System.out.println("< " + currentTile[0] + ":" + currentTile[1]);
- }
- }
- board[startTile[0]][startTile[1]].setPresent(true);
- for (int i = 0; i < 4; i++) {
- 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]) {
- board[stack.get(stack.size()-1)[0]][stack.get(stack.size()-1)[1]].setProperties(4, i);
- }
- }
- board[stack.get(stack.size()-1)[0]][stack.get(stack.size()-1)[1]].setBolted(true);
- for (int i = 1; i < stack.size()-1; i++) {
- board[stack.get(i)[0]][stack.get(i)[1]].setProperties(getProperties(stack.get(i-1), stack.get(i), stack.get(i+1)));
- }
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- board[x][y].setPresent(true);
- }
- }
- int remainder = size() - solsize - 1;
- removeRandomTiles((int)Math.ceil(remainder*(random(6, 7)/10.0)));
- wireRandomTiles((int)Math.ceil(remainder*(random(0, 2)/10.0)));
- boltRandomTiles((int)Math.ceil(remainder*(random(1, 4)/20.0)));
- }
- private void removeRandomTiles(int total) {
- int num = 0;
- while (num < total) {
- int[] pos = {random(0, w-1), random(0, h-1)};
- if (board[pos[0]][pos[1]].getType() == 0 && board[pos[0]][pos[1]].isPresent()) {
- board[pos[0]][pos[1]].setPresent(false);
- num++;
- }
- }
- }
- private void wireRandomTiles(int total) {
- int num = 0;
- while (num < total) {
- int[] pos = {random(0, w-1), random(0, h-1)};
- if (board[pos[0]][pos[1]].getType() == 0 && board[pos[0]][pos[1]].isPresent()) {
- board[pos[0]][pos[1]].setType(random(1, 2));
- board[pos[0]][pos[1]].setOrientation(random(0, 3));
- num++;
- }
- }
- }
- private void boltRandomTiles(int total) {
- int num = 0;
- while (num <= total) {
- int[] pos = {random(0, w-1), random(0, h-1)};
- if (!(board[pos[0]][pos[1]].isBolted()) && board[pos[0]][pos[1]].isPresent()) {
- board[pos[0]][pos[1]].setBolted(true);
- if (!boltFill()) {
- board[pos[0]][pos[1]].setBolted(false);
- num--;
- }
- num++;
- }
- }
- }
- public boolean boltFill() {
- clearFlags();
- boolean filling = true;
- int total = 1;
- int bolted = 0;
- int[] startPos = new int[] {0, 0};
- for (int a = 0; a < 5; a++) {
- for (int b = 0; b < 5; b++) {
- if (board[a][b].isBolted()) {
- bolted++;
- } else {
- startPos = new int[] {a, b};
- }
- }
- }
- board[startPos[0]][startPos[1]].setFlagged(true);
- while (filling) {
- filling = false;
- for (int a = 0; a < 5; a++) {
- for (int b = 0; b < 5; b++) {
- if (board[a][b].isFlagged()) {
- for (int i = 0; i < 4; i++) {
- if (a+refTab[i][0] >= 0 && a+refTab[i][0] < w && b+refTab[i][1] >= 0 && b+refTab[i][1] < h) {
- if (!board[a+refTab[i][0]][b+refTab[i][1]].isBolted() && !board[a+refTab[i][0]][b+refTab[i][1]].isFlagged()) {
- board[a+refTab[i][0]][b+refTab[i][1]].setFlagged(true);
- filling = true;
- total++;
- }
- }
- }
- }
- }
- }
- }
- for (int a = 0; a < 5; a++) {
- for (int b = 0; b < 5; b++) {
- board[a][b].setFlagged(false);
- }
- }
- //System.out.println((total+bolted) + "");
- clearFlags();
- return (total+bolted) == 25;
- }
- public boolean checkWin() {
- int[] startPos = {0, 0};
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- if (board[x][y].getType() == 3) {
- startPos[0] = x;
- startPos[1] = y;
- }
- }
- }
- int[] currentTile = {startPos[0], startPos[1]};
- int prevOrientation = -1;
- while (true) {
- int type = board[currentTile[0]][currentTile[1]].getType();
- int orientation = board[currentTile[0]][currentTile[1]].getOrientation();
- if (!board[currentTile[0]][currentTile[1]].isPresent()) {
- break;
- }
- if (type == 3) {
- if (prevOrientation == -1) {
- prevOrientation = (orientation+2)%4;
- currentTile = new int[] {currentTile[0]+refTab[orientation][0], currentTile[1]+refTab[orientation][1]};
- } else {
- break;
- }
- } else if (type == 1) {
- int onward;
- if (prevOrientation == orientation) {
- onward = (orientation+2)%4;
- } else if (prevOrientation == (orientation+2)%4) {
- onward = orientation;
- } else {
- break;
- }
- 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) {
- break;
- }
- prevOrientation = (onward+2)%4;
- currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
- } else if (type == 2) {
- int onward;
- if (prevOrientation == orientation) {
- onward = (orientation+1)%4;
- } else if (prevOrientation == (orientation+1)%4) {
- onward = orientation;
- } else {
- break;
- }
- 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) {
- break;
- }
- prevOrientation = (onward+2)%4;
- currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
- } else if (type == 4) {
- if (orientation == prevOrientation) {
- //System.out.println("Win condition - true");
- return true;
- }
- break;
- } else {
- break;
- }
- }
- //System.out.println("Win condition - false");
- return false;
- }
- public int getExcessTiles() {
- int totalTiles = 0;
- int[] startPos = {0, 0};
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- if (board[x][y].getType() == 3) {
- startPos[0] = x;
- startPos[1] = y;
- }
- if ((board[x][y].getType() == 1 || board[x][y].getType() == 2) && board[x][y].isPresent()) {
- totalTiles++;
- }
- }
- }
- //System.out.println(totalTiles);
- int[] currentTile = {startPos[0], startPos[1]};
- int prevOrientation = 0;
- int solutionTiles = 0;
- while (true) {
- solutionTiles++;
- int type = board[currentTile[0]][currentTile[1]].getType();
- int orientation = board[currentTile[0]][currentTile[1]].getOrientation();
- if (!board[currentTile[0]][currentTile[1]].isPresent()) {
- break;
- }
- if (type == 3) {
- prevOrientation = (orientation+2)%4;
- currentTile = new int[] {currentTile[0]+refTab[orientation][0], currentTile[1]+refTab[orientation][1]};
- } else if (type == 1) {
- int onward;
- if (prevOrientation == orientation) {
- onward = (orientation+2)%4;
- } else if (prevOrientation == (orientation+2)%4) {
- onward = orientation;
- } else {
- break;
- }
- 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) {
- break;
- }
- prevOrientation = (onward+2)%4;
- currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
- } else if (type == 2) {
- int onward;
- if (prevOrientation == orientation) {
- onward = (orientation+1)%4;
- } else if (prevOrientation == (orientation+1)%4) {
- onward = orientation;
- } else {
- break;
- }
- 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) {
- break;
- }
- prevOrientation = (onward+2)%4;
- currentTile = new int[] {currentTile[0]+refTab[onward][0], currentTile[1]+refTab[onward][1]};
- } else if (type == 4) {
- if (orientation == prevOrientation) {
- break;
- }
- break;
- } else {
- break;
- }
- }
- //System.out.println(solutionTiles);
- return totalTiles - (solutionTiles - 2);
- }
- private int[] getProperties(int[] a, int[] x, int[] b) {
- int relA = -1;
- int relB = -1;
- for (int i = 0; i < 4; i++) {
- if (x[0] + refTab[i][0] == a[0] && x[1] + refTab[i][1] == a[1]) {
- relA = i;
- }
- if (x[0] + refTab[i][0] == b[0] && x[1] + refTab[i][1] == b[1]) {
- relB = i;
- }
- }
- if (relA%2 == relB%2) {
- return new int[] {1, relA%2};
- } else {
- if (Math.abs(relA-relB) == 3) {
- return new int[] {2, 3};
- }
- return new int[] {2, Math.min(relA, relB)};
- }
- }
- private int[] choosePathTile(int[] pos) {
- boolean[] flag = {true, true, true, true};
- for (int i = 0; i < 4; i++) {
- 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())) {
- flag[i] = false;
- }
- }
- int c = 0;
- for (int i = 0; i < 4; i++) {
- if (flag[i]) {
- c++;
- }
- }
- if (c == 0) {
- return null;
- }
- int[] options = new int[c];
- c = 0;
- for (int i = 0; i < 4; i++) {
- if (flag[i]) {
- options[c] = i;
- c++;
- }
- }
- int choice = options[random(0, options.length-1)];
- return new int[] {pos[0]+refTab[choice][0], pos[1]+refTab[choice][1]};
- }
- public void shuffle(int num) {
- int c = 0;
- while (c < num) {
- ArrayList<int[]> options = new ArrayList<int[]>();
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- for (int i = 0; i < 4; i++) {
- if (!(board[x][y].isBolted()) && board[x][y].isPresent()) {
- if (x+refTab[i][0] >= 0 && x+refTab[i][0] < w && y+refTab[i][1] >= 0 && y+refTab[i][1] < h) {
- if (!(board[x+refTab[i][0]][y+refTab[i][1]].isPresent())) {
- options.add(new int[] {x, y, i});
- }
- }
- }
- }
- }
- }
- int[] choice = options.get(random(0, options.size()-1));
- slideTile(choice[0], choice[1], choice[0]+refTab[choice[2]][0], choice[1]+refTab[choice[2]][1]);
- c++;
- }
- }
- public int floodFill(int x, int y) {
- boolean filling = true;
- int total = 0;
- clearFlags();
- board[y][x].setFlagged(true);
- while (filling) {
- filling = false;
- for (int a = 0; a < 5; a++) {
- for (int b = 0; b < 5; b++) {
- if (board[a][b].isFlagged()) {
- for (int i = 0; i < 4; i++) {
- if (a+refTab[i][0] >= 0 && a+refTab[i][0] < w && b+refTab[i][1] >= 0 && b+refTab[i][1] < h) {
- if (!board[a+refTab[i][0]][b+refTab[i][1]].isPresent() && !board[a+refTab[i][0]][b+refTab[i][1]].isFlagged()) {
- board[a+refTab[i][0]][b+refTab[i][1]].setFlagged(true);
- filling = true;
- total++;
- }
- }
- }
- }
- }
- }
- }
- board[y][x].setFlagged(false);
- return total;
- }
- public void clearFlags() {
- for (int a = 0; a < w; a++) {
- for (int b = 0; b < h; b++) {
- board[a][b].setFlagged(false);
- }
- }
- }
- private int[] chooseEndpoint() {
- int[] pos = {random(0, w-1), random(0, h-1)};
- boolean[] flag = {true, true, true, true};
- if (pos[0] == 0) {
- flag[0] = false;
- }
- if (pos[0] == w-1) {
- flag[2] = false;
- }
- if (pos[1] == 0) {
- flag[3] = false;
- }
- if (pos[1] == h-1) {
- flag[1] = false;
- }
- int c = 0;
- for (int i = 0; i < 4; i++) {
- if (flag[i]) {
- c++;
- }
- }
- int[] options = new int[c];
- c = 0;
- for (int i = 0; i < 4; i++) {
- if (flag[i]) {
- options[c] = i;
- c++;
- }
- }
- int orientation = options[random(0, options.length-1)];
- return new int[] {pos[0], pos[1], orientation};
- }
- private int random(int a, int b) {
- return (int)(Math.random()*(b-a+1))+a;
- }
- public String toString() {
- String output = "";
- for (int x = 0; x < w; x++) {
- for (int y = 0; y < h; y++) {
- if (board[x][y].isBolted()) {
- output += "{";
- } else {
- output += "[";
- }
- if (!(board[x][y].isPresent())) {
- output += ".";
- } else {
- if (board[x][y].getType() == 0) {
- output += " ";
- } else if (board[x][y].getType() == 1) {
- if (board[x][y].getOrientation()%2 == 0) {
- output += "|";
- } else {
- output += "-";
- }
- } else if (board[x][y].getType() == 2) {
- if (board[x][y].getOrientation() == 0) {
- output += "L";
- } else if (board[x][y].getOrientation() == 1) {
- output += "F";
- } else if (board[x][y].getOrientation() == 2) {
- output += "7";
- } else if (board[x][y].getOrientation() == 3) {
- output += "J";
- }
- } else if (board[x][y].getType() == 3) {
- if (board[x][y].getOrientation() == 0) {
- output += "^";
- } else if (board[x][y].getOrientation() == 1) {
- output += ">";
- } else if (board[x][y].getOrientation() == 2) {
- output += "V";
- } else if (board[x][y].getOrientation() == 3) {
- output += "<";
- }
- } else if (board[x][y].getType() == 4) {
- if (board[x][y].getOrientation() == 0) {
- output += "U";
- } else if (board[x][y].getOrientation() == 1) {
- output += "C";
- } else if (board[x][y].getOrientation() == 2) {
- output += "A";
- } else if (board[x][y].getOrientation() == 3) {
- output += ")";
- }
- }
- }
- if (board[x][y].isBolted()) {
- output += "}";
- } else {
- output += "]";
- }
- }
- output += "\n";
- }
- return output;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement