Advertisement
mixeila

Untitled

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