2012-01-25 85 views
0

(也想不出更好的標題,隨意編輯它來描述這個問題好標題)我有以下方法停止迭代後返回true?

bool CalculateNewState(int adjacent, bool currentState) 
    { 
     if (currentState == true) 
     { 
      foreach (int n in liveRule) 
      { 
       if (adjacent == n) 
       { 
        return true; 
       }    
      } 
      return false; 
     } 
     else 
     { 
      foreach (int n in becomeAliveRule) 
      { 
       if (adjacent == n) 
       { 
        return true; 
       }    
      } 
      return false; 
     } 
    } 

這是一個game of life克隆。我想要實現的是用戶可以制定他自己的規則。

bool currentState告訴方法該單元格是否存在。 int adjacent告訴該方法該單元有多少活着的鄰居。

我想用這個實現的是,當用戶說: 2,3 and 5 neighbors keep the cell alive。它將遍歷一個包含2,3 and 5的數組(liveRule)。當發生任何匹配時,應返回true,否則返回false

這裏發生的事情是,在返回true之後,它會繼續迭代並最終返回liveRule中最後一個元素是否匹配。

我需要做什麼,在匹配發生後停止迭代?

這當然可能我採取了錯誤的方法來解決這個問題。我從建議here開始。

(試圖把它形容盡我的能力,但它似乎仍然還不是很清楚)

這是C#在Unity3D。

+1

「這裏發生的事情是,返回true後,它會一直迭代」 - 你確定*這就是發生了什麼? – AakashM

+0

我會做一次複查,但我很確定那就是發生了什麼。 –

+1

一旦你到達'return'語句,你將離開方法的範圍,並且'foreach'將不會繼續迭代。如果這是你認爲你正在經歷的事情,我懷疑這個錯誤是在別的地方比在這個方法中... – madd0

回答

6

您實現的代碼是「如果相鄰不等於2,3或5,然後返回」。顯然相鄰不能等於全部其中!

重新開始。重命名你的方法,使它們更清晰。布爾應該回答一個真/假的問題,因此,選擇問一個問題名稱:

bool IsCellAlive(int adjacentCount, bool isAlive) 
{ 
    if (isAlive) 
     return liveRule.Contains(adjacentCount); 
    else 
     return deadRule.Contains(adjacentCount); 
} 

「包含」比foreach循環更慢,所以這可能會導致性能問題。現在不要擔心;你甚至還沒有得到正確的。編寫代碼,使其明顯正確,然後使用分析器查找緩慢點,如果速度不夠快。

記住:使它正確,然後說清楚,然後使其快速。

+0

謝謝你解釋命名! (這是我們還沒有在學校學習的東西)。我試過你的解決方案,並且它看起來沒有'Contains'方法存在。 –

+1

@SimonVerbeke:在程序的頂部放置'using System.Linq;'。並使用C#3或更好。 –

+0

這是公認的:)它沒有幫助,所以我繼續調試,並注意到我將返回值分配給錯誤的數組(網格,而不是newGrid)。再次,一個愚蠢的錯誤......謝謝! –

1

您的return語句將立即退出CalculateNewState方法。如果您發現迭代正在繼續,您要麼未達到return語句(adjacent == n從不爲真),要麼從代碼中的其他地方反覆調用CalculateNewState

你或許可以更加簡單地把它改寫成類似:

if (currentState) 
    return liveRule.Contains(adjacent); 
return becomeAliveRule.Contains(adjacent); 
1

考慮你描述了你的方法是好的,看起來問題調用代碼,你可以分享嗎?

使用LINQ的方法可以重構只是單行:

usign System.Linq; 
bool CalculateNewState(int adjacent, bool currentState) 
{ 
    return (currentState ? liveRule : becomeAliveRule).Any(i => i == n); 
} 
+0

我試過你的解決方案,但它似乎也沒有認出'Any'方法。 (編輯:剛剛意識到我可能需要首先導入LINQ :)) –

+0

對不起,忘了提及,只需添加'using System.Linq' – sll

0

它看起來像你的等價測試的罪魁禍首......你不應該被測試adjacent == n代替adjacent != n?這樣它就會返回true,只有在沒有匹配的情況下才返回false。

迭代器在返回退出循環後不會繼續。

+0

這是我在複製時意外遺留的錯誤。現在已經修復了。 –

0

你可以使用for循環而不是foreach和其他變量嗎?

bool CalculateNewState(int adjacent, bool currentState) 
{ 
    if (currentState == true) 
    { 
     bool match = false; 
     for(int n = 0; n < liveRule.length && !match; n++) 
     { 
      if (adjacent != n) 
      { 
       match = true; 
      }    
     } 
     return match; 
    } 
    else 
    { 
     bool match = false; 
     for(int n = 0; n < becomeAliveRule.length && !match; n++) 
     { 
      if (adjacent != n) 
      { 
       match = true; 
      }    
     } 
     return match; 
    } 
} 
1

那麼你總是可以使用「break」語句來終止循環。做類似的事情:

bool CalculateNewState(int adjacent, bool currentState) 
{ 
    if(currentState) 
    { 
     return IsStateMatch(adjacent, liveRule); 
    } 
    else 
    { 
     return IsStateMatch(adjacent, becomeAliveRule); 
    } 
} 

bool IsStateMatch(int adjacent, int[] rules) 
{ 
    bool finalState = false; 

    if(rules != null) 
    { 
     for(int i = 0; i < rules.length; i++) 
     { 
      if(adjacent == rules[i]) 
      { 
       finalState = true; 
       break; 
      } 
     } 
    } 

    return finalState; 
} 

爲了便於閱讀,我分解了一些方法,但我認爲這是基本思想。現在,我確實同意其他海報有關可能發生的事情。如果你的循環在break/return語句之後繼續,那麼你很可能在其他地方錯誤地調用了方法。