कार्यात्मक प्रोग्रामिंग और पाठ रोमांच


14

यह ज्यादातर एफपी के बारे में एक सैद्धांतिक सवाल है, लेकिन मैं अपनी बात को स्पष्ट करने के लिए टेक्स्ट एडवेंचर (जैसे पुराने-स्कूल ज़ोर्क) लूंगा। मैं आपकी राय जानना चाहता हूं कि आप एफपी के साथ एक अनुकरणीय अनुकरण कैसे करेंगे।

पाठ रोमांच वास्तव में OOP के लिए कहते हैं। उदाहरण के लिए, सभी "कमरे" एक Roomवर्ग के उदाहरण हैं , आपके पास एक बुनियादी Itemवर्ग और इंटरफेस Item<Pickable>हो सकते हैं जैसे कि आप ले जा सकते हैं और इसी तरह की चीजें।

एफपी में विश्व मॉडलिंग अलग काम करती है, खासकर यदि आप एक ऐसी दुनिया है कि में अचल स्थिति लागू करना चाहते हैं चाहिए खेल की प्रगति के रूप में उत्परिवर्तित (वस्तुओं ले जाया जाता है, दुश्मन हार जाते हैं, स्कोरिंग बढ़ता है, खिलाड़ी अपने स्थान बदलता है)। मैं एक बड़ी वस्तु की कल्पना करता हूं Worldजिसमें यह सब है: आप कौन से कमरे का पता लगा सकते हैं, वे कैसे जुड़े हुए हैं, खिलाड़ी क्या कर रहे हैं, लीवर को क्या ट्रिगर किया गया है।

मुझे लगता है कि एक शुद्ध दृष्टिकोण मूल रूप से किसी भी कार्य के लिए इस बड़ी वस्तु को पारित करना होगा और क्या यह उनके द्वारा (संभवतः संशोधित) वापस आ गया है। उदाहरण के लिए, मेरे पास एक moveToRoomफ़ंक्शन है जो Worldइसे World.player.locationबदलकर नए कमरे में देता है, World.rooms[new_room].visited = Trueऔर इसी तरह।

यहां तक ​​कि अगर यह अधिक "सही" तरीका है, तो इसके लिए पवित्रता लागू करना प्रतीत होता है। प्रोग्रामिंग भाषा के आधार पर, इस संभावित बहुत बड़ी Worldवस्तु को आगे-पीछे करना महंगा हो सकता है। साथ ही, प्रत्येक फ़ंक्शन को किसी भी Worldऑब्जेक्ट तक पहुंच की आवश्यकता हो सकती है । उदाहरण के लिए, एक कमरा सुलभ हो सकता है या किसी अन्य कमरे में ट्रिगर किए गए लीवर के आधार पर नहीं हो सकता है क्योंकि यह बाढ़ हो सकता है, लेकिन अगर खिलाड़ी एक जीवन जैकेट ले जाता है, तो यह वैसे भी इसमें प्रवेश कर सकता है। एक राक्षस आक्रामक हो सकता है या नहीं इस पर निर्भर करता है कि खिलाड़ी ने अपने चचेरे भाई को दूसरे कमरे में मार दिया है। इसका मतलब है कि roomCanBeEnteredफ़ंक्शन को एक्सेस करने की आवश्यकता है World.player.invetoryऔर World.rooms, describeMonsterएक्सेस करने की आवश्यकता है World.monstersऔर इसी तरह (मूल रूप से, आपको चाहिएपूरे भार को पास करें)। यह वास्तव में मुझे एक वैश्विक वैरिएबल के लिए कॉल करने के लिए लगता है, भले ही यह विशेष रूप से एफपी में अच्छी प्रोग्रामिंग शैली है।

आप इस समस्या को कैसे हल करेंगे?


4
"प्रोग्रामिंग भाषा पर निर्भर करते हुए, इस संभावित बहुत बड़े विश्व ऑब्जेक्ट को आगे और पीछे पारित करना महंगा हो सकता है।" यह शायद संदर्भ द्वारा पारित किया जाएगा। "इसके अलावा, प्रत्येक फ़ंक्शन को किसी भी विश्व ऑब्जेक्ट तक पहुंचने की आवश्यकता हो सकती है।" मुझे यह विश्वास करना मुश्किल है कि हर फ़ंक्शन को खेल के पूरे राज्य तक पहुंच की आवश्यकता है ।
डोभाल

2
मुझे लगता है कि क्रिस मार्टन का शोध दिलचस्प होगा, इसका उद्देश्य यह दिखाना है कि कैसे घोषणात्मक भाषाओं में इंटरैक्टिव फिक्शन को अच्छा बनाया जाए। github.com/chrisamaphone/interactive-lp
डैनियल ग्रैज़र 15

2
आप इस ब्लॉग पर एक नज़र डाल सकते हैं कि इस तरह के खेल को एक कार्यात्मक तरीके से प्रोग्रामिंग करने के लिए लेखक के दृष्टिकोण का वर्णन किया गया है। खासतौर पर यह पोस्ट काफी प्वाइंट पर है।
गैलिस

3
मुझे आश्चर्य है कि क्या यह प्रश्न @ एरिकलिपर्ट के बाद के निर्णय को प्रभावित करने के बारे में लेखों की एक श्रृंखला को लिखने के लिए (ओम्स्कल में एक जेड मशीन के कुछ हिस्सों को लागू करने के लिए है ...)?
जूल्स

1
@Jules उस श्रृंखला की शुरुआत के लिए एक लिंक, उन लोगों के लिए: ericlippert.com/2016/02/01/west-of-house
KChaloux

जवाबों:


4

यह ध्यान रखें कि कार्यात्मक भाषाएं वस्तुओं के बजाय डेटा संरचनाओं और अलग-अलग कार्यों का उपयोग करती हैं। उदाहरण के लिए, आपके पास दुनिया के बजाय कमरों का एक सेट और इन्वेंट्री आइटम की एक सूची होगी।

आदर्श रूप से आप उन डेटा की मात्रा को सीमित कर देंगे जो आप कार्यों को देते हैं कि पूरी दुनिया को पारित करने के बजाय उन्हें वास्तव में जितना संभव हो सके उतना कहें (आप अपनी दुनिया से एक ही प्रासंगिक कमरा निकालें; बेशक पूरी तरह से अन्योन्याश्रित दुनिया के लिए कठिन हो सकता है; अलग)। परिणाम एक नया राज्य बनाते हुए, विश्व डेटा संरचना में फिर से शामिल हो जाएगा। आप राज्य का उपयोग किए बिना राज्य को मॉडल नहीं कर सकते हैं; जैसा कि आप कहते हैं कि कुछ चीजों को स्वाभाविक रूप से उत्परिवर्तन की आवश्यकता होती है।

अधिकांश व्यावहारिक कार्यात्मक भाषाएं म्यूटेशन को प्रत्यक्ष रूप से महसूस करने का एक तरीका प्रदान करती हैं (जैसे कि हस्केल में एसटी मोनड या क्लीजुरे में संक्रमण), या इसे कुशलता से अनुकरण करें (अक्सर डेटा संरचना के अपरिवर्तित भागों का पुन: उपयोग करके (क्लोजर की डिफ़ॉल्ट संरचनाएं यहां एक अच्छा उदाहरण हैं) )। किसी भी तरह से शुद्धता बनाए रखी जाती है।

चूंकि राज्य की मात्रा जिसे उत्परिवर्तित करने की आवश्यकता है, सीमित लगता है, मैं प्रदर्शन के मुद्दों के बारे में बहुत अधिक चिंता नहीं करेगा और भोले कार्यात्मक दृष्टिकोण (संभवतः पहले से अनुकूलित) के साथ जा सकता है।

एक अलग विकल्प जो मैंने देखा है वह आपके व्यक्तिगत कार्यों से दुनिया के कुछ हिस्से को बदलने के लिए केवल निर्देश लौटाएगा, और फिर इनके अनुसार अपनी दुनिया को अपडेट करेगा। यह वर्णन करने वाले ब्लॉग पोस्ट की एक श्रृंखला http://prog21.dadgum.com/23.html पर उपलब्ध है ।

ये दोनों उत्तर आपके कार्यों को पूरी दुनिया को पारित नहीं करने की तुलना में परिवर्तनों को व्यवस्थित करने के तरीके के साथ अधिक व्यवहार करते हैं, क्योंकि एक पूरी तरह से अन्योन्याश्रित परिभाषा द्वारा खंडित नहीं किया जा सकता है - लेकिन कोशिश करें और अपने मामले में जितना हो सके उतना अच्छा करें, जो न केवल है कार्यात्मक, लेकिन यह भी अच्छा अभ्यास।


0

स्वयं, मैं निश्चित रूप से डेटाबेस के कुछ रूप तक पहुंचने के लिए भाषा की क्षमता पर गौर करूंगा। दुनिया की स्थिति को समवर्ती रूप से बदलने के लिए होने वाली अधिकांश घटनाओं को बस डिस्क में रिकॉर्ड किया जाएगा, और वर्तमान कमरे के भीतर वर्तमान खिलाड़ी को प्रभावित नहीं करेगा (विशेष परिस्थितियों के बाहर जैसे विस्फोट, या एक पैराग्राफ में, जो खुले दरवाजे स्विच करता है) दूर से, अन्य खिलाड़ियों के चिल्लाने, आदि)।

जैसे, वर्तमान ग्राहक को वास्तव में केवल Roomवस्तु के बारे में पता होना चाहिए , और ऐसी चीजें जो इसे सीधे प्रभावित करती हैं। noticableEventsOutsideRoomतब Roomडेटाबेस में हाल के बदलावों से प्रभावित हो सकता है , और आपकी गेम ऑब्जेक्ट बहुत छोटी हो गई है।


मैं समझता हूं कि यह दृष्टिकोण स्थानीय घटनाओं (जैसे पास के भीड़ पर कृषि) को पथभ्रष्ट करने या ट्रिगर करने के लिए बहुत कुछ नहीं करता है, लेकिन मुझे अतीत में डेटाबेस का दुरुपयोग करने के लिए जाना जाता है ... मैं शायद सिर्फ एक कॉल भेजूंगा update mobs set agro=1 where distance<5और हो सकता हूं इसके साथ किया। शायद यह सबसे अच्छा अभ्यास नहीं है, लेकिन यह मेरे उद्देश्यों के अनुरूप है। डेटाबेस के माध्यम से
पाथफाइंग करने के

0

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

BAD:
   f :: (World, Int) -> World

Good:
   f :: (Int,Int,Int,Int) -> World

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.