2010-12-11 3 views
1

Ich bin auf einem Tic Tac Toe-Spiel zu arbeiten und bin zu wollen, eine Undo-Methode zu implementieren. Was ich denke, ist der beste Weg, dies zu tun, indem man einfach einen anderen (mehrere?) Stapel einrichtet und eine Kopie der gerade stattgefundenen Bewegungen macht. Dann, wenn rückgängig gemacht wird, einfach den letzten Zug pop und das Spielfeld neu bevölkern.Java - Verwenden mehrere Stapel einer ‚Undo‘ Methode zu ermöglichen

Also ja, ich habe die Idee, kann aber nicht herausfinden, wie es zu implementieren.

Manches, was ich habe:

ein:

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; 
} 

Dann gibt es ein Brett Verfahren das Board, ein Anzeigeverfahren zu bauen, und natürlich eine für 3 in einer Reihe zu überprüfen .

Vielen Dank für jede Beratung

+0

Suche nach dem Memento Designmuster in GOF – pastjean

Antwort

4

Es gibt Entwurfsmuster zum Rückgängigmachen und Wiederherstellen. Das Befehlsdesignmuster. Es involes

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

die obige Schnittstelle implementieren Ihren Umzug durchzuführen, führen Sie Ihre Aktion einzukapseln.

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 
} 
} 

nun eine neue Klasse erstellen, die

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(); 
} 

}

diese Weise können Sie den Zustand Ihrer Anwendung erhalten und verhindern, dass sich aus immer Nullpointer Ausnahmen CommandDispatcher sein wird. Die Methode redo() ruft die Methode execute() auf. Ich habe es nur für die Klarheit hinzugefügt.

+0

Obwohl ich nicht an einem Tic Tac Toe Spiel arbeite, habe ich etwas sehr nützliches aus deiner Antwort gelernt! –

1

Ich würde vorschlagen, dass Sie ein Objekt, das eine „Move“ kapselt die eine (BoardState s) und ein ähnliches Unapply Verfahren auf sie anzuwenden hat. Dann können Sie einen Stapel/eine Liste von diesen behalten. Rückgängig wird zu einem Popup aus dem Stapel und wird auf den aktuellen Boardstatus nicht angewendet.

Da die Methoden zum Anwenden/Auflösen umkehrbar sind, ist dies wahrscheinlich eine der einfachsten und effizientesten Methoden zur Lösung (und funktioniert bei komplexeren Problemen, wenn die Methode apply einen überschriebenen Zustand merkt).

Wenn dies keine akzeptable Lösung ist, würde ich vorschlagen, dass Sie mehr erklären, wie Ihr Code funktioniert - für alle Zahlen, und wofür n steht, ist mir nicht klar.

2

Direkt zum Gang of Four Design Patterns Buch und den Abschnitt über die Befehlsmuster lesen. Das ist es, worauf Sie hinarbeiten - und machen Sie einen ziemlich guten Job - und es ist einfach, es in Java zu implementieren, sobald Sie die Idee haben.

Verwandte Themen