2011-09-28 82 views
12

救我從猛禽死亡 - 有沒有更好的方法來處理這種結構?即將使用goto語句

while(condition) { 
    $this->phase1(); 
    $this->phase2(); 
    $this->phase3(); 
    $this->phase4(); 
} 

縱觀這些方法中的任何一個,在條件能否得到滿足。 立即條件滿足後,迴路必須退出。例如,如果我可以在phase2();的內部調用break;例如,我不需要goto語句(但當然,這會引發錯誤)。

+7

猛禽死亡參考:http://xkcd.com/292/ – amosrivera

+0

Catchy標題。 :-) – Herbert

+0

如果條件變爲false,phase1是否也會停止運行? – corsiKa

回答

11

返回一個布爾值來執行每一個階段,直到成功爲止。

while (condition) { 
    if ($this->phase1() || $this->phase2() || $this->phase3() || $this->phase4()) { 
     // Success! 
    } 
} 
+0

如果在階段1中間滿足條件並且您不想等到函數退出,該怎麼辦? –

+3

該方法假定每個階段都是一次原子操作,並且只有一次成功/失敗測試。如果你在一個可能達到成功狀態的階段有多個案例,那麼整個代碼很可能只是結構不好。 –

+0

假裝它是一款遊戲。如果玩家有50分,遊戲應該立即說出「你贏了!」而不是等待玩家完成他們的轉身。玩家可以在shoot_player()階段或got_flag()事件或者assist_team()事件期間獲得積分,甚至可以在player_death()事件期間獲得積分。它應該如何結構呢? –

4

從不同的階段返回一個布爾值。如果它沒有成功,我會返回false,然後檢查那個和break

+0

如果我遵循了你的建議,我可能必須在代碼中添加〜50條語句鏈。條件可以通過許多不同的方式來實現,並且這個循環必須立即退出(閱讀:儘快滿足條件) –

+8

然後我說你有更大的設計問題。 –

+0

我不知道如何構建它。這是一個經典的遊戲循環問題,我會想象。玩家可以隨時獲勝,你不想等待輪到他們完成顯示「你贏了!」。您希望它立即顯示! –

7

或者您可以使用State pattern

總之,而不是具有goto語句,更改$this這樣的內部狀態的方法phase1phase2phase3phase4不會產生影響,是空的功能。既然它們是空的函數,你就可以直接通過它們並退出循環!

您可能還需要一小撮事件或Observer模式,才能知道何時更改狀態。

+0

我覺得像觀察者模式是我在這裏尋找的。每次條件變量改變時,它都會通知一個game_won?()函數,該函數檢查遊戲是否獲勝。那麼我將如何擺脫遊戲循環? –

2

拋出一個異常......聽起來很特殊......

try { 
    while(condition) { 
     $this->phase1(); 
     $this->phase2(); 
     $this->phase3(); 
     $this->phase4(); 
    } 
} catch (Exception $e) { } 
+0

這取決於。 @chris - 問問自己「這值得開銷嗎?」。 –

+1

這可以工作,但它遇到的條件不是嚴格的錯誤。這只是一個滿足的條件。錯誤處理仍然是一個好方法嗎? –

+2

正如我的朋友Dan juuust所說:「你不用控制流量的例外!」,但是,嘿,我不知道爲什麼你需要跳出這個執行。也許不是,當我讀它時,聽起來更加可怕...... – Steve

0

如何包裝每個階段在if

while(condition) 
{ 
    if(condition) 
    { 
    $this->phase1(); 
    } 

    if(condition) 
    { 
    $this->phase2(); 
    } 

    if(condition) 
    { 
    $this->phase3(); 
    } 

    if(condition) 
    { 
    $this->phase4(); 
    } 
} 

當然,這也許可以做得更緊湊有一些規劃和循環。

+0

當然,我可以做到這一點。我也可以在if語句中包裝所有其他條件會議事件。這很多如果陳述,喲。 –

0

一種方法可能是使用if()語句檢查每個phase*()的返回值並打破while循環。

事情是這樣的:

while (condition) { 
    if ($this->phase1()) { break; } 
} 
0

請不要使用goto語句,認爲誰將會輻照誘導你的代碼庫

如果您條件這不是太大的開銷的編碼器,你可以

while(*condition*){ 
    $this->phase1(); 
    if (*condition*){ 
     $this->phase2(); 
    } 

    ... 

} 
0
$phases=array('phase1','phase2','phase3','phase4'); 
foreach($phases as $phase){ 
    $this->$phase(); 
    if(condition)break; 
} 

另外,如果您想從函數內部突破,則可以使用異常。