如何实现撤销功能

本文关键字:功能 实现 何实现 | 更新日期: 2023-09-27 18:12:26

我正在写一个名为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的类中实现undo函数。任何想法都很感激!!

如何实现撤销功能

通过知道上一次操作改变了什么,可以实现一次撤销。

事实证明,取消翻转可以通过……再翻一遍。所以只要记住你的最后一个动作,并重复它!

如果你记得每一个移动,那么你可以在游戏的初始状态中多次这样做。你可以通过创建一个移动堆栈来实现这一点,当你移动时,你可以推它,当你撤销时,它会弹出。

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

  1. 对于用户可以做的每一个动作,做一个反向动作来撤销它。
  2. 每次用户做出一个动作,记住它,这样你就知道要采取哪个反向动作(如果需要的话)。
  3. 当用户表示他想要撤销时,将他所做的最后一件事与其反向动作相匹配,并执行它。

有时候,创建一个反向动作是非常困难的。在这些情况下,在操作执行之前只存储程序的状态,然后在用户想要撤销时重新加载它会变得更容易。

有很多实现撤销功能的选项。

因为这是家庭作业,我只给你指出Stack数据结构。堆栈是后进先出的。把它想象成桌子上的一叠文件。

当玩家翻转一个方块时,你记录下它并将其添加到堆栈中(称为"push")。玩家翻转另一个方块:你做另一个笔记,然后推到堆栈的顶部。

当请求"撤销"时,您要撤销哪个操作?最近的一个——所以你从堆栈的顶部抽取(称为"pop")。调用stack. pop()将返回堆栈中最顶层(最近)的项,并从堆栈中删除该项。

这应该足以让你继续——找出你在堆栈中需要什么,你就差不多完成了。

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

不妨想想当你"撤销"一个动作时会发生什么。所有你刚刚翻转的颜色都被翻转回来(或者再次)假设你只有两种颜色

尽管在您的情况下这可能是多余的,但Memento设计模式是实现撤消(和重做)功能的标准方法。

Memento将保存对象的当前状态,并将具有还原功能,该功能将逆转其所链接对象的更改。

所以在你的例子中,Memento将保存板的状态(每个单元格的每种颜色),当应用到板上时,它将设置颜色。

执行命令模式。你可以在字典,数组或堆栈中记录你的命令然后撤销

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

如果您只有两种颜色,那么撤销与您在类中调用它的单元格的changeColor没有什么不同。因此,您所要做的就是存储(在成员变量中)调用changeColor的最后一列和行,并在Undo函数中使用存储的值再次调用changeColor。