diff --git a/lab2/IntList/IntListExercises.java b/lab2/IntList/IntListExercises.java index f7f995e..71a3d9c 100644 --- a/lab2/IntList/IntListExercises.java +++ b/lab2/IntList/IntListExercises.java @@ -3,10 +3,10 @@ public class IntListExercises { /** - * Part A: (Buggy) mutative method that adds a constant C to each - * element of an IntList + * PART A: (BUGGY) MUTATIVE METHOD THAT ADDS A CONSTANT C TO EACH + * ELEMENT OF AN INTLIST * - * @param lst IntList from Lecture + * @PARAM LST INTLIST FROM LECTURE */ public static void addConstant(IntList lst, int c) { IntList head = lst; diff --git a/proj0/game2048/Model.java b/proj0/game2048/Model.java index 2ecebeb..93e39ab 100644 --- a/proj0/game2048/Model.java +++ b/proj0/game2048/Model.java @@ -4,17 +4,27 @@ import java.util.Observable; -/** The state of a game of 2048. - * @author TODO: YOUR NAME HERE +/** + * The state of a game of 2048. + * + * @author */ public class Model extends Observable { - /** Current contents of the board. */ + /** + * Current contents of the board. + */ private Board board; - /** Current score. */ + /** + * Current score. + */ private int score; - /** Maximum score so far. Updated when game ends. */ + /** + * Maximum score so far. Updated when game ends. + */ private int maxScore; - /** True iff game is ended. */ + /** + * True iff game is ended. + */ private boolean gameOver; /* Coordinate System: column C, row R of the board (where row 0, @@ -22,20 +32,26 @@ public class Model extends Observable { * to board.tile(c, r). Be careful! It works like (x, y) coordinates. */ - /** Largest piece value. */ + /** + * Largest piece value. + */ public static final int MAX_PIECE = 2048; - /** A new 2048 game on a board of size SIZE with no pieces - * and score 0. */ + /** + * A new 2048 game on a board of size SIZE with no pieces + * and score 0. + */ public Model(int size) { board = new Board(size); score = maxScore = 0; gameOver = false; } - /** A new 2048 game where RAWVALUES contain the values of the tiles + /** + * A new 2048 game where RAWVALUES contain the values of the tiles * (0 if null). VALUES is indexed by (row, col) with (0, 0) corresponding - * to the bottom-left corner. Used for testing purposes. */ + * to the bottom-left corner. Used for testing purposes. + */ public Model(int[][] rawValues, int score, int maxScore, boolean gameOver) { int size = rawValues.length; board = new Board(rawValues, score); @@ -44,22 +60,27 @@ public Model(int[][] rawValues, int score, int maxScore, boolean gameOver) { this.gameOver = gameOver; } - /** Return the current Tile at (COL, ROW), where 0 <= ROW < size(), - * 0 <= COL < size(). Returns null if there is no tile there. - * Used for testing. Should be deprecated and removed. - * */ + /** + * Return the current Tile at (COL, ROW), where 0 <= ROW < size(), + * 0 <= COL < size(). Returns null if there is no tile there. + * Used for testing. Should be deprecated and removed. + */ public Tile tile(int col, int row) { return board.tile(col, row); } - /** Return the number of squares on one side of the board. - * Used for testing. Should be deprecated and removed. */ + /** + * Return the number of squares on one side of the board. + * Used for testing. Should be deprecated and removed. + */ public int size() { return board.size(); } - /** Return true iff the game is over (there are no moves, or - * there is a tile with value 2048 on the board). */ + /** + * Return true iff the game is over (there are no moves, or + * there is a tile with value 2048 on the board). + */ public boolean gameOver() { checkGameOver(); if (gameOver) { @@ -68,17 +89,23 @@ public boolean gameOver() { return gameOver; } - /** Return the current score. */ + /** + * Return the current score. + */ public int score() { return score; } - /** Return the current maximum game score (updated at end of game). */ + /** + * Return the current maximum game score (updated at end of game). + */ public int maxScore() { return maxScore; } - /** Clear the board to empty and reset the score. */ + /** + * Clear the board to empty and reset the score. + */ public void clear() { score = 0; gameOver = false; @@ -86,34 +113,68 @@ public void clear() { setChanged(); } - /** Add TILE to the board. There must be no Tile currently at the - * same position. */ + /** + * Add TILE to the board. There must be no Tile currently at the + * same position. + */ public void addTile(Tile tile) { board.addTile(tile); checkGameOver(); setChanged(); } - /** Tilt the board toward SIDE. Return true iff this changes the board. - * + /** + * Tilt the board toward SIDE. Return true iff this changes the board. + *

* 1. If two Tile objects are adjacent in the direction of motion and have - * the same value, they are merged into one Tile of twice the original - * value and that new value is added to the score instance variable + * the same value, they are merged into one Tile of twice the original + * value and that new value is added to the score instance variable * 2. A tile that is the result of a merge will not merge again on that - * tilt. So each move, every tile will only ever be part of at most one - * merge (perhaps zero). + * tilt. So each move, every tile will only ever be part of at most one + * merge (perhaps zero). * 3. When three adjacent tiles in the direction of motion have the same - * value, then the leading two tiles in the direction of motion merge, - * and the trailing tile does not. - * */ + * value, then the leading two tiles in the direction of motion merge, + * and the trailing tile does not. + */ public boolean tilt(Side side) { - boolean changed; - changed = false; + boolean changed = false; + + if (side == Side.SOUTH) { + board.setViewingPerspective(Side.SOUTH); + } else if (side == Side.WEST) { + board.setViewingPerspective(Side.WEST); + } else if (side == Side.EAST) { + board.setViewingPerspective(Side.EAST); + } + + int[][] merage = new int[board.size()][board.size()]; + for (int i = 0; i < board.size(); i++) { + for (int j = 2; j >= 0; j--) { + // 从第二列开始,因为第三列没有可以合并的对象 + Tile t = board.tile(i, j); + if (t != null) { + for (int k = 3; k > j; k--) { + if (board.tile(i, k) == null) { + // 找到空位,移动 + board.move(i, k, t); + changed = true; + break; + } else if (board.tile(i, k).value() == t.value() && merage[i][k] == 0) { + // 找到相同值,合并 + int mergedValue = t.value() * 2; + board.move(i, k, t); + score += mergedValue; + merage[i][k] = 1; + changed = true; + break; + } + } + } + } + } - // TODO: Modify this.board (and perhaps this.score) to account - // for the tilt to the Side SIDE. If the board changed, set the - // changed local variable to true. + board.setViewingPerspective(Side.NORTH); checkGameOver(); if (changed) { setChanged(); @@ -121,23 +182,33 @@ public boolean tilt(Side side) { return changed; } - /** Checks if the game is over and sets the gameOver variable - * appropriately. + /** + * Checks if the game is over and sets the gameOver variable + * appropriately. */ private void checkGameOver() { gameOver = checkGameOver(board); } - /** Determine whether game is over. */ + /** + * Determine whether game is over. + */ private static boolean checkGameOver(Board b) { return maxTileExists(b) || !atLeastOneMoveExists(b); } - /** Returns true if at least one space on the Board is empty. - * Empty spaces are stored as null. - * */ + /** + * Returns true if at least one space on the Board is empty. + * Empty spaces are stored as null. + */ public static boolean emptySpaceExists(Board b) { - // TODO: Fill in this function. + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (b.tile(i, j) == null) { + return true; + } + } + } return false; } @@ -148,6 +219,16 @@ public static boolean emptySpaceExists(Board b) { */ public static boolean maxTileExists(Board b) { // TODO: Fill in this function. + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (b.tile(i, j) != null) { + int x = b.tile(i, j).value(); + if (x == MAX_PIECE) { + return true; + } + } + } + } return false; } @@ -159,12 +240,36 @@ public static boolean maxTileExists(Board b) { */ public static boolean atLeastOneMoveExists(Board b) { // TODO: Fill in this function. + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + //判断是否有空位 + if (b.tile(i, j) == null) { + return true; + } + } + } + // 检查是否有相邻的两个相同的数 + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + Tile current = b.tile(i, j); + if (current != null) { + // 检查右侧 + if (j < 3 && b.tile(i, j + 1) != null && b.tile(i, j).value() == b.tile(i, j + 1).value()) { + return true; + } + // 检查下方 + if (i < 3 && b.tile(i + 1, j) != null && b.tile(i, j).value() == b.tile(i + 1, j).value()) { + return true; + } + } + } + } return false; } @Override - /** Returns the model as a string, used for debugging. */ + /** Returns the model as a string, used for debugging. */ public String toString() { Formatter out = new Formatter(); out.format("%n[%n");