2014-02-20 92 views
1

所以我有一個象棋遊戲。我試圖實現一種方法,用戶可以撤消他們的最後一步。遊戲循環中的「撤消移動」

enter image description here

我創建的菜單選項相應的操作監聽器。動作偵聽器將遊戲的撤消布爾值設置爲true。

僞碼,我的遊戲循環:

while (!game end) 
{ 
    if (undo) 
    { 
     undo the last move 
     continue; 
    } 

    prompt user to input next move 

    user inputs move into console 

    model, view are updated 

} 

這種邏輯是行不通的。遊戲循環處理撤消的唯一時間是用戶輸入下一步棋之後。所以......基本上它只是撤銷了他們剛纔的舉動。我需要這樣做,只要用戶單擊GUI上的撤消動作,遊戲循環就會在if語句中執行這些動作。

我有一種感覺,有一個更聰明的方法來處理這個問題。

+1

1)爲了更好地提供幫助,請發佈[MCTaRE](http://stackoverflow.com/help/mcve)(最小完整測試和可讀示例)。 2)獲取圖像的一種方法是通過熱鏈接到[本答案](http://stackoverflow.com/a/19209651/418556)中看到的圖像。 3)實際上,您可能將MCTaRE基於[健壯,可調整大小的國際象棋GUI](http://stackoverflow.com/q/21142686/418556)。它使用在「熱門鏈接圖像」問答中看到的國際象棋圖像。 –

回答

2

我認爲,最簡單的辦法是將撤銷代碼退出遊戲循環。只要你將遊戲狀態存儲在遊戲循環本身之外,這應該是可能的。 (遊戲循環將負責更新遊戲狀態)。通過將撤銷代碼移出遊戲循環,遊戲循環可以被阻塞(等待下一步移動),但當菜單動作處理程序調用它時,撤消仍然會起作用。

您的代碼可能是這個樣子:

class RunGame 
{ 
    GameState state; 

    void undoButtonPressed() 
    { 
    undo the last move in state 
    } 

    void main() 
    { 
    while(!game end) 
    { 
     prompt user to input next move 

     user inputs move into console 

     model(state), view are updated 
    } 
    } 
} 
+0

其他答案很好,但我選擇這個,因爲它是簡單的Duh類型的答案 – user2079802

3

這聽起來像這個階段阻止你while循環執行

prompt user to input next move 

user inputs move into console 

我認爲你需要尋找到threading,特別是創造了移動輸入單獨的線程,繪製和撤消。或者找到一種方式讓用戶輸入他們的輸入,而不會阻止while循環的執行。

這裏有併發 http://docs.oracle.com/javase/tutorial/essential/concurrency/

+0

我想在主線程中運行遊戲循環。然後產生另一個線程,不斷阻止'如果(撤消)'... – user2079802

2

一個很好的教程沒有太多的去,我會建議撤銷上次搬家後,你應該更新模型和視圖,但你提示下一個輸入之前...

while (!game end) 
{ 
    if (undo) 
    { 
     undo the last move 
     // Update the mode, view and update to the screen before moving on 
     model, view are updated 
     continue; 
    } 

    prompt user to input next move 

    user inputs move into console 

    model, view are updated 

} 

說了這麼多,我jeff_kile同意,這聽起來像您阻止事件調度線程,以便在那裏......

2
while (!game end) 

我認爲整個問題與該行的僞代碼開始。遊戲應該在模型中舉行,該模型的狀態決定了無論是在模式:

  • USER_PLAY - 使所有移動部件,當一個被選中,可能「轉會」的地方被啓用。
  • UNDO - 所有地方都是禁用的,遊戲在程序控制下反轉動畫。
  • OPPONENT_MOVE - 所有地方都禁用,遊戲由電腦或遠程用戶控制。

USER_PLAY的GUI會等待用戶的作品之一的事件,並在模型中設置一個MOVE_FROM_CHOSEN,它會接着觸發GUI刷新,將突出的一塊可能的行動。在第二個事件中,在可能移動到被選中的一個位置上時,它將移動該部分,可能移除被取出的部分,並將狀態設置爲OPPONENT_PLAY

在任何時候都可以選擇一個複選框(或其他)來生成確定要撤消多少遊戲的控件。一旦確定了這些參數,模型狀態將被設置爲UNDO,並使用Swing Timer作爲動畫參數(展開的移動次數)。

OPPONENT_MOVE可能會產生對對手JProgressBar「思考..」然後翻轉以同樣的方式動畫移動作爲UNDO狀態。

1

基本上什麼是你的待辦事項列表:

  1. 轉換遊戲是在這樣的狀態下,你可以把遊戲的 當前快照的快照,必須改變 的狀態的能力遊戲到快照
  2. 創建一個堆棧,您可以將當前遊戲狀態的快照轉移到每次轉動時。此快照是 是當前時間遊戲的確切狀態。
  3. 撤銷一個轉彎,將最後一個快照從堆棧中移出,然後將遊戲當前狀態更新爲 堆棧中的第一個快照(這是上一回合的狀態)。

如果你想要你可以不轉移到另一個棧上,那麼你可以添加重做。