निम्नलिखित लेख एक श्रृंखला का हिस्सा है। इस श्रृंखला के अधिक लेखों के लिए रूबी में गेम 2048 का क्लोनिंग देखें। पूर्ण और अंतिम कोड के लिए, जिस्ट देखें।
अब जब हम जानते हैं कि एल्गोरिथ्म कैसे काम करेगा, यह सोचने का समय है कि यह एल्गोरिदम किस डेटा पर काम करेगा। यहां दो मुख्य विकल्प हैं: एक फ्लैट सरणी किसी प्रकार का, या द्वि-आयामी सरणी। प्रत्येक के अपने फायदे हैं, लेकिन इससे पहले कि हम कोई निर्णय लें, हमें कुछ को ध्यान में रखना होगा।
DRY पहेलियाँ
ग्रिड-आधारित पहेलियों के साथ काम करने की एक सामान्य तकनीक जहां आपको इस तरह के पैटर्न को देखना होता है, एक लिखना है एल्गोरिथ्म का संस्करण जो पहेली पर बाईं से दाईं ओर काम करता है और फिर पूरी पहेली को चारों ओर घुमाता है बार। इस तरह, एल्गोरिथ्म को केवल एक बार लिखा जाना है और इसे केवल बाएं से दाएं काम करना है। इस नाटकीय रूप से जटिलता और आकार को कम करता है इस परियोजना का सबसे कठिन हिस्सा।
चूंकि हम पहेली को बाएं से दाएं पर काम कर रहे हैं, यह सरणियों द्वारा दर्शाई गई पंक्तियों का अर्थ है। दो आयामी सरणी बनाते समय माणिक (या, अधिक सटीक रूप से, आप इसे कैसे संबोधित करना चाहते हैं और डेटा का वास्तव में क्या मतलब है), आपको यह तय करना होगा कि आप क्या चाहते हैं पंक्तियों का एक ढेर (जहां ग्रिड की प्रत्येक पंक्ति को एक सरणी द्वारा दर्शाया गया है) या स्तंभों का एक समूह (जहां प्रत्येक स्तंभ एक सरणी है)। चूंकि हम पंक्तियों के साथ काम कर रहे हैं, हम पंक्तियों का चयन करेंगे।
इस 2D सरणी को कैसे घुमाया जाता है, हम वास्तव में इस तरह के एक सरणी का निर्माण करने के बाद प्राप्त करेंगे।
दो आयामी सरणियों का निर्माण
Array.new विधि आपके इच्छित सरणी के आकार को परिभाषित करने वाला एक तर्क ले सकती है। उदाहरण के लिए, Array.new (5) 5 शून्य वस्तुओं की एक सरणी बनाएगा। दूसरा तर्क आपको एक डिफ़ॉल्ट मान देता है, इसलिए Array.new (5, 0) आप सरणी दे देंगे [0,0,0,0,0]. तो आप दो आयामी सरणी कैसे बनाते हैं?
गलत तरीका, और जिस तरह से मैं लोगों को अक्सर कोशिश करते हुए देखता हूं वह कहना है Array.new (4, Array.new (4, 0)). दूसरे शब्दों में, 4 पंक्तियों की एक सरणी, प्रत्येक पंक्ति 4 शून्य की एक सरणी होती है। और यह पहली बार में काम करता है। हालाँकि, निम्न कोड चलाएँ:
यह सरल दिखता है। शून्य का 4x4 सरणी बनाएं, शीर्ष-बाएँ तत्व को 1 पर सेट करें। लेकिन इसे प्रिंट करें और हमें मिल जाएगा ...
यह पूरे पहले कॉलम को 1 पर सेट करता है, क्या देता है? जब हमने सरणियाँ बनाईं, तो Array.new को सबसे भीतर की कॉल सबसे पहले मिलती है, जो एक पंक्ति बनाती है। बाहरी पंक्ति को भरने के लिए इस पंक्ति का एक एकल संदर्भ 4 बार दोहराया गया है। प्रत्येक पंक्ति फिर उसी सरणी को संदर्भित कर रही है। एक को बदलें, उन सभी को बदलें।
इसके बजाय, हमें इसका उपयोग करने की आवश्यकता है तीसरा रूबी में एक सरणी बनाने का तरीका। मान को Array.new पद्धति से पारित करने के बजाय, हम एक ब्लॉक पास करते हैं। हर बार Array.new विधि को नए मान की आवश्यकता है, तो ब्लॉक निष्पादित किया जाता है। तो अगर आप कहते थे Array.new (5) {get.chomp}, रूबी रुक जाएगी और 5 बार इनपुट मांगेगी। इसलिए हमें बस इस ब्लॉक के अंदर एक नई व्यूह रचना करनी है। तो हम साथ समाप्त करते हैं Array.new (4) {Array.new (4,0)}. अब उस परीक्षण मामले को फिर से आज़माते हैं।
और यह वैसा ही होता है जैसा आप अपेक्षा करते हैं।
भले ही रूबी के पास द्वि-आयामी सरणियों के लिए समर्थन नहीं है, फिर भी हम वह कर सकते हैं जो हमें चाहिए। बस याद रखें कि शीर्ष-स्तरीय सरणी रखती है संदर्भ उप-सरणियों के लिए, और प्रत्येक उप-सरणी को विभिन्न प्रकार के मानों को संदर्भित करना चाहिए।
यह सरणी क्या दर्शाती है, यह आपके ऊपर है। हमारे मामले में, यह सरणी पंक्तियों के रूप में रखी गई है। पहला सूचकांक वह पंक्ति है जिसे हम अनुक्रमित कर रहे हैं, ऊपर से नीचे तक। पहेली की शीर्ष पंक्ति को अनुक्रमित करने के लिए, हम उपयोग करते हैं एक [0], अगली पंक्ति को नीचे सूचीबद्ध करने के लिए जिसका हम उपयोग करते हैं एक [1]. दूसरी पंक्ति में एक विशिष्ट टाइल को अनुक्रमित करने के लिए, हम उपयोग करते हैं एक [1] [एन]. हालाँकि, अगर हमने स्तम्भों पर निर्णय लिया था... तो यह एक ही बात होगी। रूबी को इस बात की कोई जानकारी नहीं है कि हम इस डेटा के साथ क्या कर रहे हैं, और चूंकि यह तकनीकी रूप से दो-आयामी सरणियों का समर्थन नहीं करता है, हम यहां क्या कर रहे हैं वह एक हैक है। इसे केवल कन्वेंशन द्वारा एक्सेस करें और सब कुछ एक साथ आयोजित होगा। भूल जाओ कि क्या किया जा रहा है और नीचे सब कुछ वास्तविक तेजी से गिर सकता है।