Advertisement
Guest User

Untitled

a guest
Mar 30th, 2015
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.01 KB | None | 0 0
  1. // Board.java
  2. package tetris;
  3.  
  4. /**
  5. * CS108 Tetris Board. Represents a Tetris board -- essentially a 2-d grid of
  6. * booleans. Supports tetris pieces and row clearing. Has an "undo" feature that
  7. * allows clients to add and remove pieces efficiently. Does not do any drawing
  8. * or have any idea of pixels. Instead, just represents the abstract 2-d board.
  9. */
  10. public class Board {
  11. // Some ivars are stubbed out for you:
  12. private int width;
  13. private int height;
  14. private boolean[][] grid;
  15. private boolean[][] saveGrid;
  16. private boolean DEBUG = true;
  17. boolean committed;
  18. private int[] w;
  19. private int[] h;
  20. protected int maxHeight;
  21.  
  22. // Here a few trivial methods are provided:
  23.  
  24. /**
  25. * Creates an empty board of the given width and height measured in blocks.
  26. */
  27. public Board(int width, int height) {
  28. this.width = width;
  29. this.height = height;
  30. grid = new boolean[width][height];
  31. committed = true;
  32. w = new int[height];
  33. h = new int[width];
  34. for (int i = 0; i < w.length; i++)
  35. w[i] = 0;
  36. for (int i = 0; i < h.length; i++)
  37. h[i] = 0;
  38. }
  39.  
  40. /**
  41. * Returns the width of the board in blocks.
  42. */
  43. public int getWidth() {
  44. return width;
  45. }
  46.  
  47. /**
  48. * Returns the height of the board in blocks.
  49. */
  50. public int getHeight() {
  51. return height;
  52. }
  53.  
  54. /**
  55. * Returns the max column height present in the board. For an empty board
  56. * this is 0.
  57. */
  58. public int getMaxHeight() {
  59. for (int i = 0; i < h.length; i++)
  60. if (h[i] > maxHeight)
  61. maxHeight = h[i];
  62. return maxHeight;
  63. }
  64.  
  65. /**
  66. * Checks the board for internal consistency -- used for debugging.
  67. */
  68. public void sanityCheck() {
  69. if (DEBUG) {
  70. int[] theights = new int[width];
  71. for (int r = 0; r < height; r++)
  72. for (int c = 0; c < width; c++)
  73. if (getGrid(c, r))
  74. theights[c] = r + 1;
  75.  
  76. for (int i = 0; i < theights.length; i++)
  77. if (theights[i] != h[i])
  78. throw new RuntimeException(
  79. "row heights is not correct. expected "
  80. + theights[i] + " but was " + h[i]
  81. + " for " + i + "th height.");
  82.  
  83. int[] twidths = new int[height];
  84. for (int c = 0; c < width; c++)
  85. for (int r = 0; r < height; r++)
  86. if (getGrid(c, r))
  87. twidths[r]++;
  88. for (int i = 0; i < twidths.length; i++)
  89. if (twidths[i] != w[i])
  90. throw new RuntimeException(
  91. "widths is not correct. expected " + twidths[i]
  92. + " but was " + w[i] + " for " + i
  93. + "th width.");
  94.  
  95. /*
  96. * int tMaxheight = 0; for (int height : h) tMaxheight =
  97. * Math.max(tMaxheight, height); if (tMaxheight != maxHeight) throw
  98. * new RuntimeException( "max height is not correct. expected " +
  99. * tMaxheight + " and was " + maxHeight);
  100. */
  101. }
  102. }
  103.  
  104. /**
  105. * Given a piece and an x, returns the y value where the piece would come to
  106. * rest if it were dropped straight down at that x.
  107. *
  108. * <p>
  109. * Implementation: use the skirt and the col heights to compute this fast --
  110. * O(skirt length).
  111. */
  112. public int dropHeight(Piece piece, int x) {
  113. int[] skirt = piece.getSkirt();
  114. int res = 0;
  115. for (int i = 0; i < skirt.length; i++) {
  116. int hits = 0;
  117. if (h[x + i] - skirt[i] > 0)
  118. hits = h[x + i] - skirt[i];
  119. if (hits > res)
  120. res = hits;
  121. }
  122. return res;
  123. }
  124.  
  125. /**
  126. * Returns the height of the given column -- i.e. the y value of the highest
  127. * block + 1. The height is 0 if the column contains no blocks.
  128. */
  129. public int getColumnHeight(int x) {
  130. return h[x];
  131. }
  132.  
  133. /**
  134. * Returns the number of filled blocks in the given row.
  135. */
  136. public int getRowWidth(int y) {
  137. return w[y];
  138. }
  139.  
  140. /**
  141. * Returns true if the given block is filled in the board. Blocks outside of
  142. * the valid width/height area always return true.
  143. */
  144. public boolean getGrid(int x, int y) {
  145. if (x >= getWidth() || y >= getHeight() || grid[x][y] == true)
  146. return true;
  147. return false;
  148. }
  149.  
  150. public static final int PLACE_OK = 0;
  151. public static final int PLACE_ROW_FILLED = 1;
  152. public static final int PLACE_OUT_BOUNDS = 2;
  153. public static final int PLACE_BAD = 3;
  154.  
  155. /**
  156. * Attempts to add the body of a piece to the board. Copies the piece blocks
  157. * into the board grid. Returns PLACE_OK for a regular placement, or
  158. * PLACE_ROW_FILLED for a regular placement that causes at least one row to
  159. * be filled.
  160. *
  161. * <p>
  162. * Error cases: A placement may fail in two ways. First, if part of the
  163. * piece may falls out of bounds of the board, PLACE_OUT_BOUNDS is returned.
  164. * Or the placement may collide with existing blocks in the grid in which
  165. * case PLACE_BAD is returned. In both error cases, the board may be left in
  166. * an invalid state. The client can use undo(), to recover the valid,
  167. * pre-place state.
  168. */
  169. public int place(Piece piece, int x, int y) {
  170. // flag !committed problem
  171. if (!committed)
  172. throw new RuntimeException("place commit problem");
  173. int res = 0;
  174. for (int i = 0; i < piece.getBody().length; i++) {
  175. if (piece.getBody()[i].x + x >= getWidth()
  176. || piece.getBody()[i].y + y >= getHeight())
  177. res = PLACE_OUT_BOUNDS;
  178. if (getGrid(piece.getBody()[i].x + x, piece.getBody()[i].y + y)) {
  179. if (res != PLACE_OUT_BOUNDS)
  180. res = PLACE_BAD;
  181.  
  182. }
  183. if (!getGrid(piece.getBody()[i].x + x, piece.getBody()[i].y + y)) {
  184. grid[piece.getBody()[i].x + x][piece.getBody()[i].y + y] = true;
  185. w[piece.getBody()[i].y + y]++;
  186. if (piece.getBody()[i].y + y + 1 > h[piece.getBody()[i].x + x])
  187. h[piece.getBody()[i].x + x] = piece.getBody()[i].y + y + 1;
  188. }
  189.  
  190. }
  191. for (int i = 0; i < w.length; i++) {
  192. if (w[i] == height)
  193. res = PLACE_ROW_FILLED;
  194. }
  195. if (res == 0)
  196. res = PLACE_OK;
  197. committed = false;
  198. return res;
  199.  
  200. }
  201.  
  202. /**
  203. * Deletes rows that are filled all the way across, moving things above
  204. * down. Returns the number of rows cleared.
  205. */
  206. public int clearRows() {
  207. System.out.println(this);
  208. int rowsCleared = 0;
  209. for (int i = 0; i < grid.length; i++) {
  210. int rowcnt = 0;
  211. for (int j = 0; j < grid[0].length; j++) {
  212. if (grid[i][j] == true)
  213. rowcnt++;
  214. }
  215. if (rowcnt == grid[0].length) {
  216. rowsCleared++;
  217. for (int s = 0; s < grid[0].length; s++) {
  218. grid[i][s] = false;
  219. }
  220. for (int n = i; n < grid.length-1; n++) {
  221. for (int m = 0; m < grid[0].length; m++) {
  222. boolean temp;
  223. temp = grid[n][m];
  224. grid[n][m] = grid[n+1][m ];
  225. grid[n+1][m] = temp;
  226.  
  227. }
  228. }
  229. for (int k = i; k <w.length - 1; k++) {
  230. w[k] = w[k + 1];
  231. }
  232.  
  233. w[w.length - 1] = 0;
  234. i--;
  235. }
  236. }
  237. for (int j = 0; j <h.length; j++) {
  238. h[j] = h[j] - rowsCleared ;
  239. }
  240. System.out.println(rowsCleared);
  241. committed = false;
  242. System.out.println(this);
  243. sanityCheck();
  244. return rowsCleared;
  245. }
  246.  
  247. /**
  248. * Reverts the board to its state before up to one place and one
  249. * clearRows(); If the conditions for undo() are not met, such as calling
  250. * undo() twice in a row, then the second undo() does nothing. See the
  251. * overview docs.
  252. */
  253. public void undo() {
  254. committed = true;
  255. for (int i = 0; i < saveGrid.length; i++) {
  256. for (int j = 0; j < saveGrid[0].length; j++) {
  257. grid[i][j] = saveGrid[i][j];
  258. }
  259. }
  260.  
  261. }
  262.  
  263. /**
  264. * Puts the board in the committed state.
  265. */
  266. public void commit() {
  267. committed = true;
  268. saveGrid = new boolean[width][height];
  269. for (int i = 0; i < grid.length; i++) {
  270. for (int j = 0; j < grid[0].length; j++) {
  271. saveGrid[i][j] = grid[i][j];
  272. }
  273. }
  274. }
  275.  
  276. /*
  277. * Renders the board state as a big String, suitable for printing. This is
  278. * the sort of print-obj-state utility that can help see complex state
  279. * change over time. (provided debugging utility)
  280. */
  281. public String toString() {
  282. StringBuilder buff = new StringBuilder();
  283. for (int y = height - 1; y >= 0; y--) {
  284. buff.append('|');
  285. for (int x = 0; x < width; x++) {
  286. if (getGrid(x, y))
  287. buff.append('+');
  288. else
  289. buff.append(' ');
  290. }
  291. buff.append("|\n");
  292. }
  293. for (int x = 0; x < width + 2; x++)
  294. buff.append('-');
  295. return (buff.toString());
  296. }
  297. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement