2011-10-27 43 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會保存電路板的狀態(每個單元格的顏色),當應用到電路板上時,它將設置顏色。