2013-09-29 107 views
0

我在java中進行連接4遊戲,並且對於如何爲其創建撤消方法有點困惑。我知道這可以使用ArrayList或Stack來完成,但我不太確定如何實現它。我的遊戲和GUI代碼可以在下面看到,任何幫助將不勝感激!連接4 Java遊戲撤消按鈕

import javax.swing.JOptionPane; 


public class ConnectFourGame { 

    private int[][] board; 
    //private GameStatus status;; 
    private int player, bSize; 


    public ConnectFourGame() { 
     //status = GameStatus.InProgress; 

     Object[] possibilities = {"4", "5", "6", "7", "8", "9", "10", 
       "11", "12", "13", "14", "15", "16", "17", "18", "19"}; 

     String s = (String)JOptionPane.showInputDialog(null, 
       "Choose Board Size:", "Sizes", JOptionPane.PLAIN_MESSAGE, 
       null, possibilities, "10"); 

     if(s == null || (s != null && ("".equals(s)))){ 
      s = "10"; 
     } 

     bSize = Integer.parseInt(s); 

     Object[] playerSelect = {"1", "2"}; 
     String s2 = (String)JOptionPane.showInputDialog(null, 
       "Choose Player to Start", "Start", JOptionPane.PLAIN_MESSAGE, 
       null, playerSelect, "1"); 

     if(s2 == null || (s2 != null && ("".equals(s)))){ 
      s2 = "1"; 
     } 

     player = Integer.parseInt(s2); 

     board = new int[bSize][bSize]; 
     reset(); 
    } 

    public int getSize(){ 
     return bSize; 
    } 

    public void reset(){ 
     for (int r = 0; r < bSize; r++) 
      for (int c = 0; c < bSize; c++) 
       board[r][c] = -1; 
    } 
    public int selectCol (int pCol) { 

     for (int r = bSize - 1; r >= 0; r--) 
      if (board[r][pCol] == -1){ 
       board[r][pCol] = player; 
       return r; 
      } 

     return -1; 
    } 

    public int nextPlayer() { 

     if (player == 1) 
      player = 2; 
     else 
      player = 1; 

     return player; 
    } 

    public int getCurrentPlayer() { 
     return player; 
    } 

    public GameStatus isWinner() { 
     int count = 0; 
     for (int r = 0; r < bSize; r++) 
      for (int c = 0; c < bSize - 3; c++) 
       if ((board[r][c] == 1) && (board[r][c + 1] == 1) && 
        (board[r][c + 2] == 1) && (board[r][c + 3] == 1)){ 
         return GameStatus.Player1WON; 
       } 

     for (int r = 0; r < bSize; r++) 
      for (int c = 0; c < bSize - 3; c++) 
       if ((board[r][c] == 2) && (board[r][c + 1] == 2) && 
        (board[r][c + 2] == 2) && (board[r][c + 3] == 2)){ 
         return GameStatus.Player2WON; 
    } 

     for (int c = 0; c < bSize; c++) 
      for (int r = 0; r < (bSize - 3); r++) 
       if ((board[r][c] == 1) && (board[r + 1][c] == 1) && 
        (board[r + 2][c] == 1) && (board[r + 3][c] == 1)){ 
         return GameStatus.Player1WON; 
    } 
     for (int c = 0; c < bSize; c++) 
      for (int r = 0; r < (bSize - 3); r++) 
       if ((board[r][c] == 2) && (board[r + 1][c] == 2) && 
        (board[r + 2][c] == 2) && (board[r + 3][c] == 2)){ 
         return GameStatus.Player2WON; 
       } 

     for (int r = 0; r < bSize - 3; r++) 
      for (int c = 0; c < bSize - 3; c++) 
       if ((board[r][c] == 1) && (board[r+1][c + 1] == 1) && 
        (board[r+2][c + 2] == 1) && (board[r+3][c + 3] == 1)){ 
         return GameStatus.Player1WON; 
    }  

     for (int r = bSize - 1; r >= 3; r--) 
      for (int c = 0; c < bSize - 3; c++) 
       if ((board[r][c] == 1) && (board[r-1][c + 1] == 1) && 
        (board[r-2][c + 2] == 1) && (board[r-3][c + 3] == 1)){ 
         return GameStatus.Player1WON; 
       } 

     for (int r = 0; r < bSize - 3; r++) 
      for (int c = 0; c < bSize - 3; c++) 
       if ((board[r][c] == 2) && (board[r+1][c + 1] == 2) && 
        (board[r+2][c + 2] == 2) && (board[r+3][c + 3] == 2)){ 
         return GameStatus.Player2WON; 
       } 

     for (int r = bSize - 1; r >= 3; r--) 
      for (int c = 0; c < bSize - 3; c++) 
       if ((board[r][c] == 2) && (board[r-1][c + 1] == 2) && 
        (board[r-2][c + 2] == 2) && (board[r-3][c + 3] == 2)){ 
         return GameStatus.Player2WON; 
       } 

     for (int r = 0; r < bSize; r++) 
      for (int c = 0; c < bSize; c++) 
       if(board[r][c] != -1) 
        count ++; 
       if(count == (bSize)*(bSize)) 
        return GameStatus.Cats; 



     return GameStatus.InProgress; 
    } 

    public int [][] getBoard() { 
     return board; 
    } 

    public void undo(){ 

    } 



} 
import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; 


public class ConnectFourPanel extends JPanel{ 

    static final long serialVersionUID = 1L; 
    private JLabel[][] board; 
    private JButton[] selection; 
    private JPanel top; 
    private JPanel bottom; 
    private JButton exit; 
    private JButton reset; 
    private JButton undo; 
    private ConnectFourGame game; 
    private int boardSize; 

    private JMenuItem quitItem; 
    private JMenuItem newGameItem; 

    public ConnectFourPanel(JMenuItem quitItem, JMenuItem gameItem){ 
     game = new ConnectFourGame(); 
     boardSize = game.getSize(); 
     this.quitItem = quitItem; 
     this.newGameItem = gameItem; 

     top = new JPanel(); 
     bottom = new JPanel(); 

     reset = new JButton ("Reset"); 
     top.add(reset); 
     undo = new JButton("Undo"); 
     top.add(undo); 
     exit = new JButton ("Exit"); 
     top.add(exit); 

     bottom.setLayout(new GridLayout(boardSize+1,boardSize,1,1)); // room for top row 

     ButtonListener listener = new ButtonListener(); 
     exit.addActionListener(listener); 
     reset.addActionListener(listener); 
     undo.addActionListener(listener); 
     quitItem.addActionListener(listener); 
     newGameItem.addActionListener(listener); 

     selection = new JButton[boardSize]; 

     for (int col = 0; col < boardSize; col++) { 
      selection[col] = new JButton ("Select"); 
      selection[col].addActionListener(listener); 
      bottom.add(selection[col]); 
     } 

     board = new JLabel[boardSize][boardSize]; 

     for (int row = 0; row < boardSize; row++) { 
      for (int col = 0; col < boardSize; col++) { 
       board[row][col] = new JLabel("X"); 
       board[row][col].setForeground(Color.RED); 
       bottom.add(board[row][col]);      
      } 
     } 

     setLayout(new BorderLayout()); 
     add (BorderLayout.NORTH,top); 
     add (BorderLayout.CENTER,bottom); 
    } 



    //***************************************************************** 
    // Represents a listener for button push (action) events. 
    //***************************************************************** 
    private class ButtonListener implements ActionListener 
    { 
     //-------------------------------------------------------------- 
     // Updates the counter and label when the button is pushed. 
     //-------------------------------------------------------------- 
     public void actionPerformed (ActionEvent event) 
     { 

      JComponent comp = (JComponent) event.getSource(); 
      boardSize = game.getSize(); 

      if ((comp == exit) || (quitItem == comp)) 
       System.exit(1); 

      if(comp == reset || newGameItem == comp){ 
       bottom.removeAll(); 
       game = new ConnectFourGame(); 
       boardSize = game.getSize(); 
       bottom.setLayout(new GridLayout(boardSize + 1,boardSize,1,1)); 


       ButtonListener listener = new ButtonListener(); 
       selection = new JButton[boardSize]; 
       for (int col = 0; col < boardSize; col++) { 
        selection[col] = new JButton ("Select"); 
        selection[col].addActionListener(listener); 
        bottom.add(selection[col]); 
       } 

       board = new JLabel[boardSize][boardSize]; 

       for (int row = 0; row < boardSize; row++) { 
        for (int col = 0; col < boardSize; col++) { 
         board[row][col] = new JLabel("X"); 
         board[row][col].setForeground(Color.RED); 
         bottom.add(board[row][col]);      
        } 
       } 

       revalidate(); 
       repaint(); 

      } 

      for(int col = 0; col < boardSize; col++) 
       if(comp == selection[col]){ 
        int row = game.selectCol(col); 
        if(row != -1){ 
         board[row][col].setText("" + game.getCurrentPlayer()); 
         game.nextPlayer(); 
        }else 
         JOptionPane.showMessageDialog(null, "Column is full!"); 

       } 

      if (game.isWinner() == GameStatus.Player1WON){ 
       JOptionPane.showMessageDialog(null,"Player1 won!"); 
      } 

      if (game.isWinner() == GameStatus.Player2WON){ 
       JOptionPane.showMessageDialog(null,"Player2 won!"); 
      } 

      if (game.isWinner() == GameStatus.Cats){ 
       JOptionPane.showMessageDialog(null,"Cats Game!"); 
      } 




     } 

    } 


} 
+1

你能解釋一下你試過的嗎?你如何想象一個ArrayList或Stack可能被使用? – pburka

+0

對不起,讓你失望,但刪除完整的代碼,並要求添加一些功能並不是在這裏獲得幫助的最佳方式。簡短描述你的代碼如何工作和(甚至失敗)試圖解決你的問題會更好。 – Pshemo

+0

我在想我是否使用了堆棧,我可以將每一步移動到堆棧中,然後當撤銷按鈕被擊中時它會彈出。與ArrayList相同的東西將每一個移動添加到ArrayList,然後當撤消命中從ArrayList中刪除最後一個條目,我只是不知道如何實現這與二維數組和所有。 –

回答

1

簡單看你的代碼,你可以在每次移動後保持板狀態的堆棧/列表。

要initalise容易使用:Stack<int[][]> aStack = new Stack<int[][]>();

創建一個方法,然後將您板陣列getBoardCopy()

每個移動

aStack.push(getBoardCopy()); 

對於撤銷按鈕創建一組板的方法setBoard(int[][] aBoard())然後就撤銷時調用此功能

setBoard(aStack.pop()) 
+0

爲什麼你不能有一個堆棧? int [] []是一個對象。無論如何,除非您在推動電路板時還製作了深層副本,否則這將無法工作。 – pburka

+0

@pburka不夠公平,被原語陣列誤認爲已更新。深度複製可以在getBoardCopy方法中實現。意味着它將是非常低效的。 –

+0

由於每回合只有一行發生變化,因此您可以聰明地複製棋盤。您可以在副本之間共享未更改的行,但我認爲這會顯着增加難度級別。 – pburka

0

您使用Stack的直覺是正確的。您可以使用Stack來記錄每個玩家選擇的列。您不需要記錄行或玩家,因爲您可以從當前遊戲狀態推斷出這兩件事。播放時,推動堆疊上的列。撤銷時,從堆棧中彈出列,並將該列中最頂端的塊更改回-1。

編輯:不要忘記每次撤銷時都要切換用戶。