2010-12-11 3 views
1

Я работаю над игрой tic tac toe и хочу реализовать метод отмены. Я считаю, что это лучший способ сделать это, просто установить другие (несколько?) Стеки и сделать копию «ходов», которые только что состоялись. Затем, если вызывается undo, просто нажмите последний ход и заново установите игровое поле.Java - Использование нескольких стеков, позволяющих использовать метод 'undo'

Итак, у меня есть идея, но я не могу понять, как ее реализовать.

Некоторые из того, что у меня есть:

Установка:

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

Поиск шаблона дизайна Memento в GOF – pastjean

ответ

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

}

Таким образом, вы можете сохранить состояние приложения и предотвратить себя от получения исключения NullPointer. Метод redo() вызовет метод execute(). Я просто добавил его для ясности.

+0

Несмотря на то, что я не работаю над играми с tic tac toe, я узнал что-то очень полезное из вашего ответа! –

1

Я предположил бы, что у вас есть объект, который инкапсулирует «Move», который имеет применять (BoardState s) и подобный метод на изменениях внесенного этим. Затем вы можете сохранить стек/список из них. Undo становится популярным из стека и не применяется к текущему состоянию платы.

Поскольку методы apply/unapply обратимы, это, вероятно, один из самых простых и эффективных методов его решения (и работает для более сложных проблем, если метод apply запоминает любое состояние, которое он переопределяет).

Если это не приемлемое решение, я бы посоветовал вам объяснить, как работает ваш код - все номера, а что n означает, потому что это не так ясно для меня.

2

Перейдите непосредственно к Банду Четырех Design Patterns и прочитайте раздел о шаблоне Command. Это то, над чем вы работаете, и делаете довольно неплохую работу, и сразу же, как только вы получите эту идею, прямо реализовать на Java.