2016-12-06 68 views
0

「撤消移動」功能,實現了二維數組棋盤遊戲「撤消移動」功能,實現了二維數組棋盤遊戲

大家好

使用一個ArrayList,我想實現的撤銷舉措功能由此,用戶可以選擇一個選項'Z',這使得可以實現多級'撤銷'。換句話說,如果用戶選擇'Z',那麼先前的移動被撤銷,如果他立即再次選擇'Z',那麼之前的移動被撤消,以此類推。

每次執行有效的移動「U」,「D」,「L」,「R」並刪除最後一個對象時,我已經能夠獲取代碼以添加新的移動對象, Z'被按下。我的問題是,如何讓播放器的運動(座標)和吃甜甜圈(布爾)依賴於ArrayList中的最後一個對象,以便當按下'Z'並且ArrayList中的最後一個對象被移除時,玩家動作和吃甜甜圈現​​在將依賴ArrayList中的新最後一個對象來創建「撤消」效果?希望我的問題有道理。

'Z'實現是move方法中switch語句的最後一種情況。

我的類是下面:

package secondproject; 

import java.util.ArrayList; 
import java.util.Random; 
import java.util.Scanner; 

public class Game { 

    private static final int BOARD_SIZE = 10; 
    private static final int INITIAL_PLAYER_COL = 0; 
    private static final int INITIAL_PLAYER_ROW = BOARD_SIZE - 1; 
    private static final int HOME_COL = BOARD_SIZE - 1; 
    private static final int HOME_ROW = 0; 
    private static final int WALL_LENGTH = 5; 
    private static final char PLAYER_CHAR = 'P'; 
    private static final char HOME_CHAR = 'H'; 
    private static final char WALL_CHAR = 'X'; 
    private static final char FREE_SQUARE_CHAR = '.'; 
    private static final char DOUGHNUT_CHAR = '@'; 
    private static final char UP_MOVE_CHAR = 'U'; 
    private static final char DOWN_MOVE_CHAR = 'D'; 
    private static final char LEFT_MOVE_CHAR = 'L'; 
    private static final char RIGHT_MOVE_CHAR = 'R'; 
    private static final char UNDO_MOVE_CHAR = 'Z'; 
    private static final char TRAIL_CHAR = 'M'; 

    private static char[][] board = new char[BOARD_SIZE][BOARD_SIZE]; 
    private static Scanner scan = new Scanner(System.in); 
    private static Scanner keyBoard = new Scanner(System.in); 

    private static int playerCol = INITIAL_PLAYER_COL; 
    private static int playerRow = INITIAL_PLAYER_ROW; 
    private static int nbrDoughnuts = 0; 
    private static int nbrMoves = 0; 
    private static Random random = new Random(); 

    private static int lives = 1; 
    private static int doughnutLives; 
    private static boolean doughnutCheck; 
    static ArrayList<Move> movement = new ArrayList<Move>(); 

    public static void main(String[] args) { 

     setUpBoard(); 
     showBoard(); 
     String opt; 
     do { 
      System.out.print("Next option ?"); 
      opt = scan.next(); 
      char opt1 = opt.charAt(0); 
      if (opt1 == UP_MOVE_CHAR || opt1 == DOWN_MOVE_CHAR || opt1 == LEFT_MOVE_CHAR || opt1 == RIGHT_MOVE_CHAR || opt1 == UNDO_MOVE_CHAR) { 
       move(opt1); 
      } else { 
       System.out.println("Allowed commands are: + " + UP_MOVE_CHAR + "," + DOWN_MOVE_CHAR + "," + LEFT_MOVE_CHAR + "," + RIGHT_MOVE_CHAR); 
      } 
      showBoard(); 
      System.out.println("Number of moves made = " + nbrMoves); 
      System.out.println("Number of doughnuts eaten = " + nbrDoughnuts); 
      System.out.println("Lives = " + lives); 
     } while (board[HOME_ROW][HOME_COL] == HOME_CHAR); 
     System.out.println("Thank you and goodbye"); 
    } 

    /** 
    * Set up the initial state of the board 
    */ 
    private static void setUpBoard() { 
     intialiseBoard(); // Fill the board with . characters 
     //Add the first vertical wall 
     int v1StartCol = 1 + random.nextInt(BOARD_SIZE - 2); 
     int v1StartRow = 1 + random.nextInt(BOARD_SIZE - WALL_LENGTH - 1); 
     addVerticalWall(v1StartCol, v1StartRow, WALL_LENGTH); 

     //Add the second vertical wall 
     int v2StartCol; 
     do { 
      v2StartCol = 1 + random.nextInt(BOARD_SIZE - 2); 
     } while (v2StartCol == v1StartCol); 
     int v2StartRow = 1 + random.nextInt(BOARD_SIZE - WALL_LENGTH - 1); 
     addVerticalWall(v2StartCol, v2StartRow, WALL_LENGTH); 

     //Add the horizontal wall 
     int h1StartRow = 1 + random.nextInt(BOARD_SIZE - 2); 
     int h1StartCol = 1 + random.nextInt(BOARD_SIZE - WALL_LENGTH - 1); 
     addHorizontalWall(h1StartCol, h1StartRow, WALL_LENGTH); 

     //Add the dougnuts 
     int nbrDoughnutsAdded = 0; 
     while (nbrDoughnutsAdded < 5) { 
      int dRow = 1 + random.nextInt(BOARD_SIZE - 2); 
      int dCol = 1 + random.nextInt(BOARD_SIZE - 2); 
      if (board[dRow][dCol] == FREE_SQUARE_CHAR) { 
       board[dRow][dCol] = DOUGHNUT_CHAR; 
       nbrDoughnutsAdded++; 
      } 
     } 

     //Add the player and the home square 
     board[playerRow][playerCol] = PLAYER_CHAR; 
     board[HOME_ROW][HOME_COL] = HOME_CHAR; 
    } 

    /** 
    * Add a vertical wall to the board 
    * 
    * @param startCol Column on which wall is situated 
    * @param startRow Row on which top of wall is situated 
    * @param length Number of squares occupied by wall 
    */ 
    private static void addVerticalWall(int startCol, int startRow, int length) { 
     for (int row = startRow; row < startRow + length; row++) { 
      board[row][startCol] = WALL_CHAR; 
     } 
    } 

    /** 
    * Add a horizontal wall to the board 
    * 
    * @param startCol Column on which leftmost end of wall is situated 
    * @param startRow Row on which wall is situated 
    * @param length Number of squares occupied by wall 
    */ 
    private static void addHorizontalWall(int startCol, int startRow, int length) { 
     for (int col = startCol; col < startCol + length; col++) { 
      board[startRow][col] = WALL_CHAR; 
     } 
    } 

    /** 
    * Display the board 
    */ 
    private static void showBoard() { 
     for (int row = 0; row < board.length; row++) { 
      for (int col = 0; col < board[row].length; col++) { 
       System.out.print(board[row][col]); 
      } 
      System.out.println(); 
     } 
    } 

    /** 
    * Fill the board with FREE_SQUARE_CHAR characters. 
    */ 
    private static void intialiseBoard() { 
     for (int row = 0; row < board.length; row++) { 
      for (int col = 0; col < board[row].length; col++) { 
       board[row][col] = FREE_SQUARE_CHAR; 
      } 
      System.out.println(); 
     } 
    } 

    /** 
    * Move the player 
    * 
    * @param moveChar Character indicating the move to be made 
    */ 
    private static void move(char moveChar) { 
     int newCol = playerCol; 
     int newRow = playerRow; 

     switch (moveChar) { 
      case UP_MOVE_CHAR: 
       if (lives == 1) { 
        newRow--; 
       } else if (lives > 1) { 
        int number = keyBoard.nextInt(); 
        if (number <= lives) { 
         newRow = newRow - number; 
        } else { 
         checkLives(); 
        } 
       } 
       break; 
      case DOWN_MOVE_CHAR: 
       if (lives == 1) { 
        newRow++; 
       } else if (lives > 1) { 
        squareNumberPrompt(); 
        int number = keyBoard.nextInt(); 
        if (number <= lives) { 
         newRow = newRow + number; 
        } else { 
         checkLives(); 
        } 
       } 
       break; 
      case LEFT_MOVE_CHAR: 
       if (lives == 1) { 
        newCol--; 
       } else if (lives > 1) { 
        squareNumberPrompt(); 
        int number = keyBoard.nextInt(); 
        if (number <= lives) { 
         newCol = newCol - number; 
        } else { 
         checkLives(); 
        } 
       } 
       break; 
      case RIGHT_MOVE_CHAR: 
       if (lives == 1) { 
        newCol++; 
       } else if (lives > 1) { 
        squareNumberPrompt(); 
        int number = keyBoard.nextInt(); 
        if (number <= lives) { 
         newCol = newCol + number; 
        } else { 
         checkLives(); 
        } 
       } 
       break; 
      case UNDO_MOVE_CHAR: 
       if (movement.size() >= 1) { 
        movement.remove(movement.size() - 1); 
        System.out.println("The decreasing size of the arraylist is now " + movement.size()); 
       } else if (movement.size() < 1) { 
        System.out.println("There is no move to be undone!"); 
       } 
       break; 
     } 
     if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) { 
      System.out.println("Sorry that move takes you off the board!"); 
     } else { 
      char dest = board[newRow][newCol]; 
      if (dest == WALL_CHAR) { 
       System.out.println("Sorry you landed on a wall!"); 
      } else { 
       nbrMoves++; 
       if (dest == DOUGHNUT_CHAR) { 
        doughnutCheck = true; 
        nbrDoughnuts++; 
        doughnutLives++; 
        lives = (doughnutLives + 1); 
       } 
       board[playerRow][playerCol] = FREE_SQUARE_CHAR; 
       playerCol = newCol; 
       playerRow = newRow; 
       board[playerRow][playerCol] = PLAYER_CHAR; 
      } 
     } 
     if (moveChar == UP_MOVE_CHAR || moveChar == DOWN_MOVE_CHAR || moveChar == LEFT_MOVE_CHAR || moveChar == RIGHT_MOVE_CHAR) { 
      movement.add(new Move(playerCol, playerRow, newCol, newRow, doughnutCheck)); 
      System.out.println("The increasing size of the arraylist is now " + movement.size()); 
     } 
    } 

    public static void squareNumberPrompt() { 
     System.out.println("Enter the number of squares to be moved"); 
    } 

    public static void checkLives() { 
     System.out.println("Invalid number! The number must be" 
       + " equal to or less than the number of lives you have"); 
    } 
} 





package secondproject; 

import java.util.ArrayList; 

public class Move { 

    private static int pColumn; 
    private static int pRow; 
    private static int nCol; 
    private static int nRow; 
    private static boolean dCheck; 

    public Move(int playerCol, int playerRow, int newCol, int newRow, boolean doughnutCheck) { 
     pColumn = playerCol; 
     pRow = playerRow; 
     nCol = newCol; 
     nRow = newRow; 
     dCheck = doughnutCheck; 
    } 

    public int getFromCol() { 
     return pColumn; 
    } 

    public int getFromRow() { 
     return pRow; 
    } 

    public int getToCol() { 
     return nCol; 
    } 

    public int getToRow() { 
     return nRow; 
    } 

    public boolean isDoughnutEaten() { 
     return dCheck; 
    } 
} 
+1

保留一堆座標。只要不是撤消移動,就將座標推入堆棧。在撤消移動時從堆棧彈出。 – rafid059

+0

要麼你保存在一次移動過程中吃過的每個甜甜圈的列表,要麼需要從頭開始重新創建遊戲,從移動1開始。還可以使用數據結構來記住玩家已經存在的位置,並且如果撤消移除了其中一個那些點再次放置甜甜圈。儘管如果玩家不止一次訪問一個區塊,那麼這可能會變得複雜,但是您可以只記得點數。 – Mark

+0

除非每塊瓷磚上都有甜甜圈,只能訪問一次,否則實際上你只需要知道你去哪裏,所以你可以在那裏替換甜甜圈......我懷疑這是怎麼回事。 – Mark

回答

0

看起來有點接近你的代碼後,你基本上已經擁有你需要的一切撤消到位。 甚至可能有點太多:D你實際上並不需要從位置到位置。只有這個舉動讓你進入的位置就足夠了。

所以,當你按下Z,你的代碼應該看起來有點像這樣:

Move lastMove = movement.remove(movement.size() - 1); 
playerCol = movement.get(movement.size() - 1).getToCol(); 
playerRow = movement.get(movement.size() - 1).getToRow(); 
board[playerRow][playerCol] = PLAYER_CHAR; 
if (lastMove.isDoughnutEaten()) { 
    int dCol = lastMove.getToCol(); 
    int dRow = lastMove.getToRow(); 
    board[dRow][dCol] = DOUGHNUT_CHAR; 
    nbrDoughnutsAdded--; 
} 

現在,你可以讀取lastMove的pColumn和船頭值的新的球員的位置,但正如我所說,這是無論如何,你可以從列表的新最後一個元素中讀取它,這是一種過度殺傷。

請記住,您仍然需要捕捉特殊情況(例如,當您撤消第一次移動時,在這種情況下,您需要從定義起點的靜態變量中讀取前一位玩家的位置,而不是列表的最後一個元素(不再存在))

+0

是的,我相信我已經實施了這個機制。我的困惑在於如何編碼恢復到最後位置和甜甜圈狀態。我無法理解它。 –

+0

我編輯了一段代碼示例,希望我不會錯過任何內容,但基本上是如何對代碼進行恢復。 – Mark