1

三目並べゲームに取り組んでいて、undoメソッドを実装したいと思っています。これを行うための最良の方法は、別の(複数の?)スタックをセットアップし、実行されたばかりの「移動」のコピーを作成することです。次に、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つ続けてチェックする方法があります。

アドバイスありがとうございます

4

3 に答える 3

4

元に戻すとやり直すためのデザインパターンがあります。コマンドデザインパターン。それは関与します

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

上記のインターフェースを実装して移動を実行します。executeはアクションをカプセル化します。

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()メソッドを呼び出します。わかりやすくするために追加しました。

于 2010-12-11T03:04:19.697 に答える
2

Gang of Four Design Patternsの本に直接アクセスして、コマンドパターンのセクションを読んでください。それがあなたが目指していることであり、それをかなりうまくやっています。アイデアが浮かんだら、Javaで実装するのは簡単です。

于 2010-12-11T02:48:12.277 に答える
1

apply(BoardState s)と同様のunapplyメソッドを持つ「Move」をカプセル化するオブジェクトがあることをお勧めします。次に、これらのスタック/リストを保持できます。元に戻すはスタックからポップになり、現在のボード状態に適用を解除します。

apply / unapplyメソッドは元に戻すことができるため、これはおそらくそれを解決するための最も単純で最も効率的な方法の1つです(applyメソッドがオーバーライドする状態を記憶している場合は、より複雑な問題に対して機能します)。

これが許容できる解決策ではない場合は、コードがどのように機能するかを詳しく説明することをお勧めします。すべての数値と、nが何を表すかについては、cosは私にはそれほど明確ではありません。

于 2010-12-11T02:42:14.700 に答える