如何实现撤消功能

时间:2011-10-27 05:09:09

标签: c# undo

我正在编写一个名为Flipper的程序,它有3x3个单元用于拼图。每个单元格(按钮)在初始时都具有绿色。单击某个单元格时,该单元格及其相邻单元格会翻转(更改颜色)。另一个要求是撤销功能,它回到了前一阶段。我不知道如何实现这一点。这些是游戏中发生的主要事情。

public Puzzle(Form1 form1)
{
    buttons = new Button[3, 3] { { form1.button1, form1.button2, form1.button3 }, 
                                 { form1.button4, form1.button5, form1.button6 }, 
                                 { form1.button7, form1.button8, form1.button9 } };
    //button reference from form1
}
public void reset()
{
   //reset all the colors of buttons in the puzzle to lime
}

public void FlipCells(int row, int col)
{        
   //when certain button is clicked(this event is done in the form1.cs), say for (0,0) change color of cell (0,0),///(0,1) and (1,0) by calling changeColor method
}

public void changeColor(int row, int col)
{
    //test current color of the cell, and change it
}

我要求在名为Undo的类中实现撤销功能。任何想法都很赞赏!!!

6 个答案:

答案 0 :(得分:5)

可以通过了解上次操作的更改来实现单个撤销。

事实证明,撤消翻转可以通过......再次翻转来完成。所以请记住你的最后一步,重复一遍!

如果您记得每次移动,您可以根据需要多次执行此操作的初始状态。您可以通过创建在移动时按下的一组移动来执行此操作,并在撤消时弹出。

更一般地说,要撤消,你需要做三件事:

  1. 对于用户可以进行的每个操作,请执行反向操作以撤消该操作。
  2. 每次用户进行操作时,请记住它,以便了解要采取的反向操作(如果需要)。
  3. 当用户表示他想要撤消时,将他做的最后一件事与其反向行动相匹配,然后执行。
  4. 有时,创建反向动作非常困难。在这些情况下,在执行操作之前更容易存储程序的状态,然后在用户想要撤消时重新加载它。

答案 1 :(得分:2)

实现撤消功能有很多选择。

由于这是家庭作业,我只想指出Stack数据结构。 Stack是后进先出。把它想象成一张桌子上的一叠文件。

当玩家翻转正方形时,您会记下它并将其添加到堆栈中(称为“推送”)。玩家翻转另一个方块:你再做一个音符,然后推到堆栈的顶部。

当请求“撤消”时,您要撤消哪个操作?最近的一个 - 所以你从堆栈顶部绘制(称为“pop”)。调用Stack.Pop()将从堆栈中返回最顶层(最新)项并从堆栈中删除该项。

这应该足以让你前进 - 找出你需要的东西,你已经快完成了。

进一步阅读:
Stackhttp://msdn.microsoft.com/en-us/library/system.collections.stack.aspx
Stack<T>http://msdn.microsoft.com/en-us/library/3278tedw.aspx

答案 2 :(得分:1)

或许想想当你'撤消'一招时会发生什么。假设您只有两种颜色

,那么您刚刚翻转的所有内容都会被翻转(或再次)

答案 3 :(得分:1)

实施命令模式。你实际上在某种字典或数组或堆栈中跟踪你的命令,然后撤消

访问此链接http://www.codeproject.com/KB/architecture/sharped.aspx

答案 4 :(得分:1)

Memento Design Pattern是实现撤消(和重做)功能的标准方法,但在你的情况下可能有些过分。

Memento将保存对象的当前状态,并具有恢复功能,该功能将反转与其链接的对象的更改。

因此,在您的情况下,Memento会保存电路板的状态(每个电池的每种颜色),当应用于电路板时,它将设置颜色。

答案 5 :(得分:0)

如果只有两种颜色,则撤消与您为其称之为的单元格的changeColor没有区别。 因此,您所要做的就是存储(在成员变量中)调用changeColor的最后一列和行,并在Undo函数中再次使用存储的值调用changeColor。