Advertisement
Guest User

Untitled

a guest
Dec 3rd, 2014
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.76 KB | None | 0 0
  1. public class Main {
  2. public static void main(String[] args){
  3.  
  4. int[][] numbers = {
  5. {1, 0, 3},
  6. {4, 2, 6},
  7. {7, 5, 8}
  8. };
  9.  
  10. Board board = new Board(numbers);
  11.  
  12.  
  13. Search search = new Search(board);
  14.  
  15. }
  16. }
  17.  
  18. import java.util.ArrayList;
  19.  
  20. /**
  21. * The board where the game is played.
  22. *
  23. * @author Paymon Sattarzadeh
  24. * @date 27/11/2014
  25. * @time 12:20
  26. */
  27. public class Board {
  28.  
  29. /**
  30. * Numbers in the board
  31. */
  32. private int[][] numbers = {};
  33.  
  34. private int rows = 3;
  35. private int columns = 3;
  36.  
  37. /**
  38. * The board
  39. */
  40. private ArrayList<Tile> board = new ArrayList();
  41.  
  42. /**
  43. * Constructs a <code>Board</code> instance and fills
  44. * it with <code>Tile</code> instances
  45. */
  46. public Board(int[][] numbers) {
  47.  
  48. this.numbers = numbers;
  49. int j = 0;
  50.  
  51. for(int[] row: numbers){
  52.  
  53. for (int i = 0; i < row.length; i++) {
  54. board.add(new Tile(row[i], i, j));
  55. }
  56.  
  57. j += 1;
  58. }
  59.  
  60. }
  61.  
  62. /**
  63. * @return
  64. * Numbers for board
  65. */
  66. public int[][] getNumbers(){
  67.  
  68. return numbers;
  69. }
  70.  
  71. /**
  72. * @return
  73. * Tiles in board
  74. */
  75. public ArrayList<Tile> getTiles(){
  76.  
  77. return board;
  78. }
  79.  
  80. /**
  81. * Moves the specified <code>Tile</code> to the specified position.
  82. * Swaps positions with <code>Tile</code> at that position.
  83. *
  84. * @param tile
  85. * <code>Tile</code> to be moved
  86. * @param x
  87. * The horizontal position you want <code>Tile</code> to move to.
  88. * @param y
  89. * The vertical position you want <code>Tile</code> to move to.
  90. */
  91. public void moveTile(Tile tile, int x, int y) {
  92.  
  93. int _x = tile.getXPosition();
  94. int _y = tile.getYPosition();
  95.  
  96. Tile tileToBeMoved = tile;
  97. Tile tileAtPosition;
  98.  
  99. if(findTile(x, y) != null) {
  100. tileAtPosition = findTile(x, y);
  101. } else {
  102. System.out.println("No tile exists at that position");
  103. return;
  104. }
  105.  
  106. /* Move tileToBeMoved to chosen position */
  107. tileToBeMoved.setPosition(x, y);
  108.  
  109. /* swap*/
  110. tileAtPosition.setPosition(_x, _y);
  111.  
  112.  
  113. }
  114.  
  115. /**
  116. * Checks if neighbouring <code>Tile</code>s exist, if so, it returns the <code>Tile</code>
  117. *
  118. * @param tile
  119. * Current <code>Tile</code>
  120. * @return
  121. * Set of <code>Tile</code>s
  122. */
  123. public ArrayList<Tile> checkNeighbouringTiles(Tile tile){
  124.  
  125. ArrayList<Tile> neighbouringTiles = new ArrayList<>();
  126.  
  127. int x = tile.getXPosition();
  128. int y = tile.getYPosition();
  129.  
  130. /* Neighbour to the right of tile */
  131. int rightNeighbourX = x + 1;
  132. int rightNeighbourY = y;
  133.  
  134. /* Neighbour to the left of tile */
  135. int leftNeighbourX = x - 1;
  136. int leftNeighbourY = y;
  137.  
  138. /* Neighbour to the top of tile */
  139. int topNeighbourX = x;
  140. int topNeighbourY = y - 1;
  141.  
  142. /* Neighbour to the bottom of tile */
  143. int bottomNeighbourX = x;
  144. int bottomNeighbourY = y + 1;
  145.  
  146.  
  147. for(Tile t: board) {
  148. if ((t.getXPosition() == rightNeighbourX) && (t.getYPosition() == rightNeighbourY)) {
  149. neighbouringTiles.add(t);
  150.  
  151. } else if((t.getXPosition() == leftNeighbourX) && (t.getYPosition() == leftNeighbourY)){
  152. neighbouringTiles.add(t);
  153.  
  154. } else if((t.getXPosition() == topNeighbourX) && (t.getYPosition() == topNeighbourY)){
  155. neighbouringTiles.add(t);
  156.  
  157. } else if((t.getXPosition() == bottomNeighbourX) && (t.getYPosition() == bottomNeighbourY)){
  158. neighbouringTiles.add(t);
  159. }
  160. }
  161.  
  162. return neighbouringTiles;
  163. }
  164.  
  165. /**
  166. * Finds a <code>Tile</code> with matching position
  167. *
  168. * @param x
  169. * The horizontal position
  170. * @param y
  171. * The vertical position
  172. * @return
  173. * matching <code>Tile</code>
  174. */
  175. public Tile findTile(int x, int y){
  176.  
  177. for(Tile t: board) {
  178. if(t.getXPosition() == x && t.getYPosition() == y)
  179. return t;
  180. }
  181.  
  182. return null;
  183. }
  184.  
  185. /**
  186. * Finds a <code>Tile</code> with matching number
  187. *
  188. * @param number
  189. * The number on the <code>Tile</code>
  190. * @return
  191. * matching <code>Tile</code>
  192. */
  193. public Tile findTile(int number){
  194.  
  195. for(Tile t: board) {
  196. if(t.getNumber() == number)
  197. return t;
  198. }
  199.  
  200. return null;
  201. }
  202.  
  203.  
  204. /**
  205. *Prints the board
  206. */
  207. public void print() {
  208.  
  209. System.out.println("*=====*");
  210.  
  211. for(int j = 0; j < rows; j++){
  212. System.out.print("||");
  213.  
  214. for(int i = 0; i < columns; i++){
  215. if(findTile(i, j) != null){
  216. System.out.print(findTile(i, j).getNumber());
  217. }
  218. }
  219. System.out.println("||");
  220. }
  221.  
  222. System.out.println("*=====*");
  223.  
  224. }
  225.  
  226. }
  227.  
  228. /**
  229. * Represents a single tile on a board
  230. *
  231. * @author Paymon Sattarzadeh
  232. * @date 27/11/2014
  233. * @time 02:27
  234. */
  235. public class Tile {
  236.  
  237. /**
  238. * Number on Tile
  239. */
  240. private int number;
  241.  
  242. /**
  243. * Horizontal position of tile
  244. */
  245. private int x;
  246.  
  247. /**
  248. * Vertical position of tile
  249. */
  250. private int y;
  251.  
  252. /**
  253. * Constructs a <code>Tile</code> instance with a number and position.
  254. *
  255. * @param number
  256. * The number for the <code>Tile</code>.
  257. * @param x
  258. * The Horizontal position for the <code>Tile</code>.
  259. */
  260. public Tile(int number, int x, int y){
  261. this.number = number;
  262. this.x = x;
  263. this.y = y;
  264. }
  265.  
  266. /**
  267. * @param x
  268. * Horizontal position for the <code>Tile</code>
  269. * @param y
  270. * Vertical position for the <code>Tile</code>
  271. */
  272. public void setPosition(int x, int y){
  273.  
  274. this.x = x;
  275. this.y = y;
  276. }
  277.  
  278. /**
  279. * @return
  280. * Current horizontal position of <code>Tile</code>
  281. */
  282. public int getXPosition(){
  283.  
  284. return x;
  285. }
  286.  
  287. /**
  288. * @return
  289. * Current vertical position of <code>Tile</code>
  290. */
  291. public int getYPosition(){
  292.  
  293. return y;
  294. }
  295.  
  296. /**
  297. * @param number
  298. * Number on Tile
  299. */
  300. public void setNumber(int number){
  301.  
  302. this.number = number;
  303. }
  304.  
  305. /**
  306. * @return
  307. * Current number on tile
  308. */
  309. public int getNumber(){
  310.  
  311. return number;
  312. }
  313.  
  314. }
  315.  
  316. import java.util.ArrayList;
  317. import java.util.Collections;
  318. import java.util.HashMap;
  319. import java.util.Map;
  320.  
  321. /**
  322. * Respresents the A* algorithm
  323. *
  324. * @author Paymon Sattarzadeh
  325. * @date 27/11/2014
  326. * @time 16:19
  327. */
  328. public class Search {
  329.  
  330. /**
  331. * Active instance of <code>Board</code>
  332. */
  333. private Board board;
  334.  
  335. /**
  336. * Set of fringes
  337. */
  338. private ArrayList<Integer> fringes = new ArrayList<>();
  339.  
  340. /**
  341. * Current nodes
  342. */
  343. private int node;
  344.  
  345. /**
  346. * Map linking tiles(by number) to the goal state
  347. */
  348. private static Map<Integer, int[]> goalStates = new HashMap<>();
  349.  
  350. /**
  351. * g value
  352. */
  353. private int g = 0;
  354.  
  355. /**
  356. * Is the search complete
  357. */
  358. private boolean searchComplete = false;
  359.  
  360. /**
  361. * The last move
  362. */
  363. private int lastMove = 0;
  364.  
  365. /**
  366. * Fills goalStates Map
  367. */
  368. static {
  369. goalStates.put(1, new int[]{0, 0});
  370. goalStates.put(2, new int[]{1, 0});
  371. goalStates.put(3, new int[]{2, 0});
  372. goalStates.put(4, new int[]{0, 1});
  373. goalStates.put(5, new int[]{1, 1});
  374. goalStates.put(6, new int[]{2, 1});
  375. goalStates.put(7, new int[]{0, 2});
  376. goalStates.put(8, new int[]{1, 2});
  377. };
  378.  
  379. /**
  380. * Construct the <code>Search</code> instance
  381. *
  382. * @param board
  383. * The board
  384. */
  385. public Search(Board board){
  386. this.board = board;
  387.  
  388. searchAlgo();
  389. }
  390.  
  391. /**
  392. * Main search algorithm
  393. */
  394. private void searchAlgo() {
  395.  
  396. ArrayList<Integer> nodeFValues = new ArrayList();
  397. ArrayList<Tile> nodeTiles = new ArrayList<>();
  398.  
  399. System.out.println("Step: " + g);
  400.  
  401. board.print();
  402.  
  403. /* Stores all the f values for the nodes in the fringe */
  404. for(Tile tile: board.checkNeighbouringTiles(board.findTile(0))){
  405.  
  406. if(lastMove != tile.getNumber()) {
  407. nodeFValues.add(node(tile));
  408. nodeTiles.add(tile);
  409. }
  410.  
  411. }
  412.  
  413. /* Gets the minimum fringe */
  414. int minFValueIndex = nodeFValues.indexOf(Collections.min(nodeFValues));
  415.  
  416. if (tilesOutOfPlaceHeuristic(board) == 0){
  417. System.out.println("Complete");
  418. searchComplete = true;
  419.  
  420. return;
  421. }
  422.  
  423. /* Goes to the node with the lowest f value. */
  424. board.moveTile(board.findTile(0),
  425. nodeTiles.get(minFValueIndex).getXPosition(),
  426. nodeTiles.get(minFValueIndex).getYPosition());
  427.  
  428. lastMove = nodeTiles.get(minFValueIndex).getNumber();
  429.  
  430. g += 1;
  431.  
  432. /* If search is incomplete, it recursively calls itself */
  433. if(!searchComplete)
  434. searchAlgo();
  435.  
  436.  
  437. }
  438.  
  439. /**
  440. * Represents each node
  441. *
  442. * @param tile
  443. * The tile to be moved in the node
  444. * @return
  445. * f value
  446. */
  447. private int node(Tile tile){
  448.  
  449. /** Initialises new board object */
  450. Board nodeBoard = new Board(board.getNumbers());
  451.  
  452. nodeBoard.moveTile(nodeBoard.findTile(0), tile.getXPosition(), tile.getYPosition());//moves 1 to 0, so 4 out of place now
  453.  
  454. int h1 = tilesOutOfPlaceHeuristic(nodeBoard);
  455. int h2 = manhattanHeuristic(nodeBoard);
  456.  
  457. int f = g + h2;
  458.  
  459. return f;
  460. }
  461.  
  462. /**
  463. * Calculates horizontal and vertical distances of tiles from their proper places.
  464. * Admissible Heuristic.
  465. *
  466. * @return
  467. * Sum of horizontal and vertical distances of tiles from their proper places.
  468. */
  469. private int manhattanHeuristic(Board board) {
  470.  
  471. int sum = 0;
  472. ArrayList<Tile> tiles = board.getTiles();
  473. int[] goalState;
  474. int goalX;
  475. int goalY;
  476. int differenceX;
  477. int differenceY;
  478.  
  479. for(Tile tile: tiles){
  480.  
  481. if(tile.getNumber() != 0) {
  482. goalState = goalStates.get(tile.getNumber());
  483. goalX = goalState[0];
  484. goalY = goalState[1];
  485.  
  486. differenceX = goalX - tile.getXPosition();
  487. differenceY = goalY - tile.getYPosition();
  488.  
  489. sum += Math.abs(differenceX) + Math.abs(differenceY);
  490. }
  491.  
  492. }
  493.  
  494. return sum;
  495. }
  496.  
  497. /**
  498. * Calculates number of tiles out of place. Admissible Heuristic.
  499. *
  500. * @return
  501. * Number of tiles out of place
  502. */
  503. private int tilesOutOfPlaceHeuristic(Board board) {
  504.  
  505. int tilesInWrongPlace = 0;
  506. ArrayList<Tile> tiles = board.getTiles();
  507.  
  508. for(Tile tile: tiles){
  509.  
  510. if(tile.getNumber() != 0) {
  511. if ((tile.getXPosition() != goalStates.get(tile.getNumber())[0])
  512. || (tile.getYPosition() != goalStates.get(tile.getNumber())[1])){
  513. tilesInWrongPlace += 1;
  514. }
  515. }
  516.  
  517. }
  518.  
  519. return tilesInWrongPlace;
  520. }
  521.  
  522. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement