【问题标题】:How to implement Undo function如何实现撤销功能
【发布时间】:2011-12-16 05:59:34
【问题描述】:

我正在编写一个名为 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 的类中实现撤销功能。任何想法表示赞赏!!!

【问题讨论】:

    标签: c# undo


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      也许想想当你“撤消”一个动作时会发生什么。假设您只有两种颜色,那么您刚刚翻转的所有颜色都会被翻转(或再次)

      【讨论】:

        【解决方案3】:

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

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

        如果你能记住每一个动作,你可以在游戏的初始状态下多次执行此操作。您可以通过创建一个移动堆栈来实现这一点,移动时推送,撤消时弹出。

        更一般地说,要撤消,您需要做 3 件事:

        1. 对于用户可以执行的每个操作,执行一个反向操作来撤消它。
        2. 每次用户执行操作时,请记住它,以便您知道要执行哪个反向操作(如果需要)。
        3. 当用户表示他想要撤消时,将他所做的最后一件事与其相反的操作相匹配,然后执行它。

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

        【讨论】:

          【解决方案4】:

          有很多选项可以实现撤消功能。

          因为这是家庭作业,所以我只是将您指向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

          【讨论】:

            【解决方案5】:

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

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

            【讨论】:

              【解决方案6】:

              在您的情况下,这可能有点矫枉过正,Memento 设计模式是实现撤消(和重做)功能的标准方式。

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

              因此,在您的情况下,Memento 会保存棋盘的状态(每个单元格的每种颜色),当应用于棋盘时,它将设置颜色。

              【讨论】:

                猜你喜欢
                • 2011-05-24
                • 2011-05-27
                • 2021-11-25
                • 2020-06-20
                • 2012-12-16
                • 2013-01-30
                • 1970-01-01
                • 2014-02-07
                • 2011-05-09
                相关资源
                最近更新 更多