पहले चरण के रूप में, आप लूप के अंदर while
पाश को सरल बनाने के तरीके को देख सकते हैं। एक विकल्प है कि अनुक्रम उत्पन्न करने के लिए Seq.initInfinite
का उपयोग करना है जो आपको यादृच्छिक एक्स, वाई निर्देशांक की संख्या प्रदान करेगा। फिर आप रिक्त बोर्ड फ़ील्ड को संदर्भित करने वाले पहले व्यक्ति को खोजने के लिए Seq.find
का उपयोग कर सकते हैं।
मैं भी isEmpty
बदल एक टपल लेने के लिए (ताकि आप आंशिक समारोह अनुप्रयोग का उपयोग Seq.find
को तर्क के रूप में पारित कर सकते हैं) और मैं कुछ नाम बदल अधिक मानक एफ # शैली (आप आमतौर हंगेरी नामकरण संकेतन का उपयोग नहीं होता) का पालन करने के लिए:
let isEmpty (x, y) = board.[x,y] = -1
let rnd = new System.Random()
for i = 0 to obstacleCount do
let x, y =
// Generate infinite sequence of random X Y coordinates
Seq.initInfinite (fun _ -> rnd.Next(width), rnd.Next(height))
// Find first coordinate that refers to empty field
|> Seq.find isEmpty
// We still have mutation here
board.[x,y] <- Obstacle
मुझे लगता है कि यह काफी सुरुचिपूर्ण कार्यात्मक समाधान है। यह अनिवार्य समाधान की तुलना में थोड़ा धीमा हो सकता है, लेकिन बिंदु यह है कि कार्यात्मक शैली & लिखना आसान बनाता है जब आप इसे सीखने के बाद कार्यान्वयन को बदलते हैं (आप हमेशा अनिवार्य शैली को अनुकूलन के रूप में उपयोग कर सकते हैं)।
सभी परिवर्तनीय स्थिति से बचने के लिए, आपको पहले बाधाओं के लिए स्थान जेनरेट करना होगा और फिर सरणी को प्रारंभ करना होगा। उदाहरण के लिए, आप एक सेट में नए निर्देशांक जोड़ सकते हैं जब तक कि इसकी आवश्यक लंबाई न हो। तो फिर तुम Array2D.init
का उपयोग कर देता है उत्पन्न कर सकते हैं:
let rec generateObstacles obstacles =
if Set.count obstacles = obstacleCount then obstacles
else
// Try generating new coordinate and add it to the set
// (if it is already included, this doesn't do anything)
obstacles
|> Set.add (rnd.Next(width), rnd.Next(height))
|> generateObstacles
let obstacles = generateObstacles Set.empty
Array2D.init width height (fun x y ->
if obstacles.Contains(x, y) then Obstacle else Empty)
यह वास्तव में कम नहीं है और यह थोड़ा धीमा हो जाएगा, तो मैं पहले समाधान के लिए छड़ी होगी।
Seq.initInfinite (fun _ -> rnd.Next(width), rnd.Next(height))
|> Seq.filter (fun (x, y) -> IsEmptyAt x y)
|> Seq.distinct
|> Seq.take nObstacles
|> Seq.iter (fun (x, y) -> board.[x,y] <- Obstacle)
आप Seq.filter निकाल सकते हैं बोर्ड शुरुआत में खाली है: हालांकि, यह एक अच्छा प्रत्यावर्तन और सेट दिखा व्यायाम ...
मुझे लगता है कि आपका पहला समाधान दिलचस्प है। मुझे लगता है कि "बॉक्स से बाहर" यहां शायद 100% अपरिवर्तनीयता की कोई ज़रूरत नहीं है, क्योंकि बोर्ड की तरह वैसे भी उत्परिवर्तनीय हो सकता है, मैं बस (x, y) की व्यवहार्यता से बचने की उम्मीद कर रहा था। – user627943