2010-12-11 219 views
1

我正在開發一個tic tac toe遊戲,並且想要實現撤消方法。我覺得做這件事的最好方法就是設置另一個(多個)堆棧,並複製剛剛發生的「移動」。然後,如果撤消被調用,只需彈出最後一步並重新填充遊戲板。Java - 使用多個堆棧以允許「撤消」方法

所以是的,我有想法,但無法弄清楚如何實現它。

一些什麼,我有:

設置:

public void set(Position p, int v, int n) throws IOException { 
    if (board[p.x][p.y][p.z]!= 0) throw new IOException("Position taken"); 

    //Restrict 222 until all other's have been used 
    if (n != 26) { 
     if (p.x == 1 && p.y == 1 && p.z ==1) { 
      throw new IOException("[2,2,2] cannot be played until all other positions have been taken"); 
     } 
    } 

    //Enforce x=1 for first 9, x=3 for next 9 
    if (n < 9) { 
     if (p.x != 0) throw new IOException("Please play on x=1 for the first 9 moves"); 
    } 

    if (n >= 9 && n < 18) { 
     if (p.x != 2) throw new IOException("Please play on x=3 for the first 9 moves"); 
    } 

    board[p.x][p.y][p.z] = v; 
} 

然後有一個板的方法,建立董事會,顯示方法,當然一個的連續檢查3 。

感謝您的任何意見

+0

尋找GOF中的紀念品設計圖案 – pastjean 2010-12-11 02:32:52

回答

4

有撤銷和重做的設計模式。 命令設計模式。它被調用

public interface ICommand{ 
    void execute(); 
    void undo(); 
    void redo(); 
} 

執行上述接口來執行你的動作,執行會封裝你的動作。

class MoveCommand implements ICommand{//parameter to store current board state 
    public MoveCommand(){ 
    // new board state is validated 
    } 
    public void execute(){ 
    // change the board state 
    } 
public void undo(){ // restore 
} 
public void redo(){ // apply again if possible 
} 
} 

現在創建一個新的類,這將是CommandDispatcher

class CommandDispatcher{ 
private List<ICommand> commands = new ArrayList<ICommand>(); 
public CommandDispatcher(){ 
} 
private ICommand currentCommand = null; 
public void setCommand(ICommand cmd){ 
    currentCommand = cmd; 
    cmd.execute(); 
    commands.add(cmd); 
} 
public void undoAll(){ 
    for(ICommand cmd : commands){cmd.undo();} 
} 
public void undo(){ 
commands.remove(commands.size()-1); 
currentCommand = commands.get(commands.size()-1) 
} 
public void redo(){ 
if(null!=currentCommand) currentCommand.redo(); 
} 

}

這樣你可以保留你的應用程序的狀態,並防止自己從獲得空指針異常。 redo()方法將調用execute()方法。我只是爲了清晰起見而添加了它

+0

即使我不是在製作一個tic tac toe遊戲,我從你的答案中學到了一些非常有用的東西! – 2010-12-11 03:26:28

1

我會建議你把它封裝了其具有的應用「移動」(BoardState S)和它類似的方法不應用的對象。 然後你可以保留這些的堆棧/列表。 撤銷成爲從堆棧彈出,並不適用於當前板狀態。

由於你的apply/unapply方法是可逆的,所以這可能是解決它的最簡單和最有效的方法之一(如果apply方法記住它覆蓋的任何狀態,則適用於更復雜的問題)。

如果這不是一個可以接受的解決方案,那麼我建議你更詳細地解釋你的代碼是如何工作的 - 重新計算所有數字,以及n代表什麼,cos對我來說不是那麼清楚。

2

直接進入四人幫Design Patterns的書,並閱讀命令模式的部分。這就是你正在努力的方向 - 並且做得很好 - 一旦你明白了這個想法,用Java實現就會很簡單。