F #

2011-02-22 17 views
5

में एक कंपाउंड इटरेटर बनाना I एक चेकर्स-जैसी गेम को कार्यान्वित कर रहा हूं, और मुझे एक अनुक्रम की आवश्यकता है जो किसी दिए गए कॉन्फ़िगरेशन के लिए सभी कानूनी चालों को दर्शाती है।F #

मैं निम्नलिखित समारोह, सीधे सी # से अनुवादित मिल गया है:

seq { 
    for y1 = 0 to BOARDSIZE-1 do 
     for x1 = 0 to BOARDSIZE-1 do 
      for dy = -2 to 2 do 
       for dx = -2 to 2 do 
        let x2 = x1 + dx; 
        let y2 = y1 + dy; 
        let currentMove = new MoveStruct(x1, y1, x2, y2); 
        if (currentMove.SomeCondition = true) then 
          yield currentMove; 
    } 

यह काम करता है, लेकिन यह अजीब है, और नहीं काफी "एफ # रास्ता", अकेले मेरे पास है एक चुपके से संदेह है कि क्या मैं मैं यहां कर रहा हूं प्रदर्शन अनुकूल नहीं है।

मुझे यह पसंद है कि "इस सेल से सभी वैध चालों पर" फिर से "सभी कोशिकाओं पर पुनरावृत्त" के संयोजन का उपयोग करने वाले किसी चीज़ में "इसे बाहर फ़्लैट करना" है। ,

let AllCells = 
    seq { 
     for y=0 to BOARDSIZE-1 do 
      for x=0 to BOARDSIZE-1 do 
       yield (x,y); 
    }; 

और

let LegalMovesAround(x1,y1) = 
    seq { 
     if board.[x1, y1] = WHITE then 
     for dy = -2 to 2 do 
      for dx = -2 to 2 do 
       let x2 = x1 + dx; 
       let y2 = y1 + dy; 
       let currentMove = new MoveStruct(x1, y1, x2, y2); 
       if (currentMove.DetermineMoveType <> MoveType.ILLEGAL 
        && board.[x2, y2] = NONE) then 
         yield currentMove; 
    } 

मैं इसे काम करने के लिए आप मेरे विभिन्न प्रयासों की जानकारी के लिए छोड़ जा रहा हूँ क्योंकि:

और यहाँ कार्यों मैं गठबंधन करने के आशा करती हूं कि कर रहे हैं उनमें से कोई भी सफल नहीं था। लेकिन लंबी कहानी को कम करने के लिए, सबसे अच्छा मैं साथ आ सकता हूं एक इटरेटर जो प्रत्येक उपज के साथ एक सीक देता है, जो कि मैं चाहता हूं कि चतुर संस्करण की बजाय, जो एक सरल मूवस्ट्रक्चर लौटाएगा।

किसी के पास ऑलकेल्स, और LegalMovesAround (x, y) को गठबंधन करने का अच्छा विचार है?

सादर, Aleks

उत्तर

1

आप उन्हें इस तरह जिस तरह से वे कर रहे हैं कुछ गठबंधन और फिर समतल, सक्षम होना चाहिए:

let validMoves = 
    AllCells 
    |> Seq.collect LegalMovesAround 
    |> Seq.distinct 

हालांकि यह सबसे अच्छा समाधान प्रदर्शन के लिहाज से हो सकता है।

संपादित करें: टॉमस टिप्पणी

+0

आलसी दृश्यों और दुष्प्रभावों मिश्रण से सावधान! यदि बोर्ड को उत्परिवर्तित किया जाता है, तो यह समझना महत्वपूर्ण है कि पूरे अनुक्रम का मूल्यांकन कब किया जाए। Seq.distinct को कॉल करना खतरनाक लग रहा है। – Joh

+0

ऊपर मेरी टिप्पणी को कभी भी ध्यान न दें, चाल वृक्ष नीचे जाने से पहले Seq.distinct को बुलाया जाएगा। – Joh

+1

यह चेक टाइप नहीं करता है। मुझे लगता है कि 'legalMovesAround'' Seq.collect' का तर्क होना चाहिए। –

3

के अनुसार निश्चित नमूना कोड आप उपज का उपयोग कर सकते हैं! एक नई अनुक्रम अभिव्यक्ति में:

let allLegalMoves = seq { 
    for cell in AllCells do 
    yield! LegalMovesAround cell 
} 
3

क्या आप yield! से अवगत हैं?

कुछ

तरह
seq { 
    for x,y in Allcells do 
     yield! LMA(x,y) 
} 
+0

यह समाधान भी काम करता है, सिवाय इसके कि यह प्रत्येक उपज के साथ एक अनुक्रम देता है, जबकि मैं इसे मूवस्ट्रक्चर वापस करने के लिए पसंद करता हूं। कॉलर को कार्यान्वयन के विवरण के बारे में जानने की आवश्यकता नहीं है। – user627943

+0

नहीं, यह एक मूवस्ट्रक्चर उत्पन्न करता है। कोशिश करो। – Brian

+0

सच है, यह करता है। जादू की तरह काम करता है। – user627943

संबंधित मुद्दे