2011-10-27 40 views
1

我正在编写一个名为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 
} 

我要求在一个名为撤消的类中实现撤消功能。任何想法是赞赏!

回答

0

如果您只有两种颜色,而不是与您为其调用的单元格的changeColor不同, 所以你所要做的就是存储(在成员变量中)changeColor被调用的最后一列和最后一行,并且在Undo函数中使用存储的值再次调用changeColor。

1

也许想想当你'撤销'一个举动会发生什么。所有刚刚翻转的部分都会翻转(或重新翻转),假设您只有两种颜色,即

5

通过了解上次操作发生了哪些变化,可以实现单个撤消操作。

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

如果您还记得每移动移动,您都可以根据自己的喜好进行多次操作。您可以通过在移动时创建一系列移动来完成此操作,并在撤消时弹出。

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

  1. 对于每一个动作,用户可以进行,使逆动作将撤销它。
  2. 每次用户进行操作时,请记住它,以便知道采取了哪种逆向操作(如果需要)。
  3. 当用户表示他想要撤销时,将他所做的最后一件事情与其反向操作相匹配,并执行它。

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

2

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

由于这是作业,我只是指您到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

1

所有的辛苦也可能是您的情况矫枉过正备忘录设计模式是一种标准的方法实现撤销(和重做)功能。

一个Memento将保存一个对象的当前状态,并将具有恢复功能,该功能将对所链接对象的更改进行反转。

所以在你的情况下,一个Memento会保存电路板的状态(每个单元格的颜色),当应用到电路板上时,它将设置颜色。