मुझे टेक्स्ट एडवेंचर गेम में उपयोगकर्ता इनपुट को पार्स कैसे करना चाहिए?


17

एक पाठ साहसिक कार्य में उपयोगकर्ता आदेशों पार्स से एक स्पेक्ट्रम है साहसिक में कुछ मन bogglingly चालाक लोगों को "उत्तर जाओ" के सरल hhgttg

मुझे अच्छा लगता है कि 80 के दशक में कंप्यूटर पत्रिकाओं में अच्छा-खासा पढ़ना याद था, लेकिन अब मुझे ' विकिपीडिया रेफरी ' को छोड़कर नेट पर लगभग कुछ भी नहीं मिला ।

आप इसे कैसे करेंगे ?


अपडेट : मैं अपनी लुडम डेयर प्रविष्टि में सबसे सरल दृष्टिकोण के साथ गया ।


3
क्या कोई विशेष समस्या है जिसे आप हल करने का प्रयास कर रहे हैं?
ट्रेवर पॉवेल

@TrevorPowell मस्ती के लिए एक छोटा सा पाठ साहसिक बनाने पर विचार कर रहा है, और सिर्फ अपने आप को 'डाइविंग ऑफ द आर्ट' से परिचित करना चाहता हूं, बजाय इसके कि मैं इसमें गोता लगाऊं और इसे हल करूं, यह सब है
विल

1
सूचना का उपयोग करें ; यह सबसे अच्छी रणनीति है जिसका आप कभी भी उपयोग कर सकते हैं। इन दिनों टेक्स्ट एडवेंचर को हैंड-कोड करने का कोई कारण नहीं है।
निकोल बोल्स

@ निचलोलस जब तक लड्डू डेरे के पास नहीं आता? ;)
विल

1
यह उतना व्यावहारिक नहीं है जितना व्यावहारिक है। सभी तकनीकों में जाना उन्नत पाठ पार्सिंग (स्पष्ट सामान के साथ कोई भी ऊपर आ सकता है) शायद यहां एक एकल उत्तर के दायरे से बाहर है।
तेतराद

जवाबों:


10

क्या आपने इंटरेक्टिव फिक्शन समुदाय में खोज की? वे अभी भी पार्सर लिखते हैं और कुछ प्राकृतिक भाषा प्रसंस्करण जैसी नई तकनीकों को लागू करके लिफाफे को आगे बढ़ाने की कोशिश करते हैं।

उदाहरण के लिए देखें इस लिंक का उपयोग किया गया वर्णन करने वाले लेखों के लिए:

http://ifwiki.org/index.php/Past_raif_topics:_Development:_part_2#Parsing


4
अहा, "टेक्स्ट एडवेंचर" "इंटरेक्टिव फिक्शन" बन जाता है और अचानक इसके बहुत अधिक गूगलेबल! जो मैंने सोचा था कि मैंने इसे खेलने के बाद से नाम भी बदल दिया होगा। :) फिर भी, उन लीडों को देखते हुए, और वास्तव में बहुत दुखी नहीं समझा जाता है
विल

9

आप जो शब्द चाहते हैं, वह 'प्राकृतिक भाषा प्रसंस्करण', या एनएलपी है। हालाँकि, इस बात को ध्यान में रखते हुए कि औपचारिक तरीके वास्तविक विश्व ग्रंथों को आज़माने और समझने के लिए डिज़ाइन किए गए हैं, जबकि आपको केवल कुछ ऐसी चीज़ों की ज़रूरत होती है जो आपकी प्राकृतिक भाषा के सीमित उपसमुच्चय के लिए काम करती हैं।

आमतौर पर आप एक सरल व्याकरण और शब्दावली के साथ शुरुआत कर सकते हैं, फिर इसके लिए एक पार्सर लिख सकते हैं। एक व्याकरण कुछ इस तरह सरल हो सकता है:

sentence = verb [preposition] object
verb = "get" | "go" | "look" | "examine"
preposition = "above" | "below"
object = ["the"] [adjective] noun
adjective = "big" | "green"
noun = "north" | "south" | "east" | "west" | "house" | "dog"

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

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

आखिरकार आपका कार्यक्रम एक वैध कमांड के साथ समाप्त होता है, जिसमें सभी विभिन्न भागों की जाँच की गई है; तब यह कार्रवाई करने के लिए तर्कों के साथ सही फ़ंक्शन को कॉल करने का मामला है।


6

पाठ रोमांच बनाने के लिए कला की स्थिति आज Inform 7 का उपयोग कर रही है । सूचना 7 स्रोत "अंग्रेजी की तरह," उसी तरह से पढ़ता है जैसे कि सूचना-आधारित खेल आपको "अंग्रेजी लिखने" देते हैं। उदाहरण के लिए, एमिली शॉर्ट्स ब्रोंज़ से :

एक चीज में गंध नामक कुछ पाठ होता है। किसी चीज की गंध आमतौर पर "कुछ भी नहीं" होती है।
ब्लॉक महक नियम किसी भी नियम पुस्तिका में सूचीबद्ध नहीं है।
कुछ सूँघने के लिए बाहर निकलें:
    कहते हैं "से [संज्ञा] आप गंध [संज्ञा की गंध]।"
एक कमरे को सूँघने के बजाय:
    यदि खिलाड़ी द्वारा किसी सुगंधित चीज़ को छुआ जा सकता है, तो कहें "आप गंध [सुगंधित चीजों की सूची जो खिलाड़ी द्वारा छुआ जा सकता है];";
    अन्यथा कहें "वह स्थान आनंदमय गंधहीन है।"

सूचित 7 पार्सर सूचना 7 आईडीई के साथ घनिष्ठ रूप से जुड़ा हुआ है, और संपूर्ण स्रोत कोड अभी तक अध्ययन के लिए उपलब्ध नहीं है:


5

पाठ एडवेंचर पार्सर बनाने के लिए सीखने के लिए दो सर्वोत्तम वर्तमान स्रोत हैं (जैसा कि उल्लेख किया गया था) IF समुदाय और कीचड़ समुदाय। यदि आप उन (Intfiction.org/forum, newsgroup rec.arts.int-fiction, Mud Connector, Mudbytes, Mudlab, Top Mud Sites) के लिए प्रमुख फ़ोरम खोजते हैं, तो आपको कुछ उत्तर मिलेंगे, लेकिन यदि आप अभी देख रहे हैं लेखों के लिए मैं MUD II में रिचर्ड बार्सले के पार्सर के स्पष्टीकरण की सिफारिश करूंगा:

http://www.mud.co.uk/richard/commpars.htm

और इस स्पष्टीकरण पर rec.arts.int-fiction:

http://groups.google.com/group/rec.arts.int-fiction/msg/f545963efb72ec7b?dmode=source

अन्य उत्तरों के लिए कोई अनादर नहीं था, लेकिन सीएफ व्याकरण बनाना या बीएनएफ का उपयोग करना इस समस्या का समाधान नहीं है। यह कहना नहीं है कि यह एक अलग समस्या के लिए समाधान नहीं हो सकता है, अर्थात्, एक अधिक उन्नत प्राकृतिक भाषा पार्सर बना रहा है, लेकिन यह काफी शोध का विषय है और पाठ साहसिक के दायरे में आईएमओ नहीं है।


4

विश्वविद्यालय में मेरे पहले साल में हमने प्रोलॉग में एक साहसिक खेल बनाया, और उपयोगकर्ता इनपुट के लिए हमें निश्चित क्लॉज व्याकरण या डीसीजी का उपयोग करना था । इसे कमांड भाषा के रूप में उपयोग करने के उदाहरण के लिए http://www.amzi.com/manuals/amzi/pro/ref_dcg.htm#DCGCommandLanguage देखें । यह एक राजसी की तरह लग रहा था (यह सभी के बाद यूनी था) और उस समय लचीला दृष्टिकोण।


1

आपको एक डोमेन विशिष्ट भाषा को परिभाषित करने की आवश्यकता है जो सभी वाक्य हैं जो आपके गेम में सही हैं। इसके लिए आपको अपनी भाषा (शब्दावली और वाक्य रचना) के लिए एक व्याकरण को परिभाषित करना होगा। आपको जिस प्रकार के व्याकरण की आवश्यकता होती है वह एक Context Free Grammar है और ऐसे उपकरण हैं जो स्वचालित रूप से व्याकरण के सिंथेटिक विवरण जैसे ANTLR (www.antlr.org) से शुरू होने वाले एक पार्सर को उत्पन्न करते हैं। पार्सर केवल यह जांचता है कि कोई वाक्य सही है या नहीं और वाक्य का एक सार सिंटेक्स ट्री (एएसटी) का उत्पादन करता है जो वाक्य का एक नेविगेट करने योग्य प्रतिनिधित्व है जहां प्रत्येक शब्द की भूमिका है जिसे आपने व्याकरण में निर्दिष्ट किया है। एएसटी को नेविगेट करके आपको उस कोड को जोड़ना होगा जो यह आकलन करता है कि प्रत्येक शब्द में जो शब्दार्थ है वह क्या है जब वाक्य में अन्य शब्दों के संबंध में उस भूमिका को निभाते हैं और सत्यापित करते हैं कि क्या शब्दार्थ सही है।

उदाहरण के लिए वाक्य 'पत्थर आदमी को खा जाता है' वाक्य रचना में सही है लेकिन जरूरी नहीं कि शब्दार्थ सही हो (जब तक कि आपके विश्व के पत्थर, शायद जादू के पत्थर, पुरुषों को खा सकते हैं)।

यदि शब्दार्थ भी सही है तो आप उदाहरण के लिए, इसके अनुसार दुनिया को बदल सकते हैं। यह संदर्भ बदल सकता है और इस प्रकार एक ही वाक्य शब्दार्थ रूप से सही नहीं हो सकता है (उदाहरण के लिए खाने के लिए कोई आदमी नहीं हो सकता है)


1

मैंने लिखे गए कुछ टेक्स्ट एडवेंचर के लिए Tads3 (www.tads3.org) इंजन का इस्तेमाल किया। यह कंप्यूटर प्रोग्रामर के लिए अधिक है, लेकिन बहुत शक्तिशाली भाषा है। यदि आप एक प्रोग्रामर हैं तो Tads3 को Inform7 की तुलना में चीजों को तेजी से कोड करना आसान होगा, जिसे मैंने पहले भी इस्तेमाल किया है। प्रोग्रामर के लिए Inform7 की समस्या उतनी ही प्रसिद्ध है जितनी "अंदाज क्रिया" पाठ रोमांच के खिलाड़ियों के लिए है कि यदि आप अपने वाक्य नहीं लिखते हैं तो बहुत सावधानी से आप खेल को तोड़ने जा रहे हैं। यदि आपके पास ऐसा करने का धैर्य है, तो आप टोकनर क्लास का उपयोग करके आसानी से जावा में एक पार्सर लिख सकते हैं। उदाहरण मैंने एक वैश्विक JTextArea और एक वैश्विक स्ट्रिंग [] सरणी का उपयोग करके लिखा है। यह AZ और 0-9 के साथ-साथ प्रश्न चिह्न ("मदद" कमांड शॉर्टकट के लिए) को छोड़कर अवांछित वर्णों को अलग करता है:

// put these as global variables just after your main class definition
public static String[] parsed = new String[100];
// outputArea should be a non-editable JTextArea to display our results
JTextArea outputArea = new JTextArea();
/*
 * parserArea is the JTextBox used to grab input
 * and be sure to MAKE sure somewhere to add a 
 * java.awt.event.KeyListener on it somewhere where
 * you initialize all your variables and setup the
 * constraints settings for your JTextBox's.
 * The KeyListener method should listen for the ENTER key 
 * being pressed and then call our parseText() method below.
 */
JTextArea parserArea = new JTextArea();

public void parseText(){
    String s0 = parserArea.getText();// parserArea is our global JTextBox
    s0 = s0.replace(',',' ');
    s0 = s0.replaceAll("[^a-zA-Z0-9? ]","");
    // reset parserArea back to a clean starting state
    parserArea.setCaretPosition(0);
    parserArea.setText("");
    // erase what had been parsed before and also make sure no nulls found
    for(int i=0;i < parsed.length; i++){
      parsed[i] = "";
    }
    // split the string s0 to array words by breaking them up between spaces
    StringTokenizer tok = new StringTokenizer(s0, " ");
    // use tokenizer tok and dump the tokens into array: parsed[]
    int iCount = 0;
    if(tok.countTokens() > 0){
      while(tok.hasMoreElements()){
        try{
          parsed[iCount] = tok.nextElement().toString();
          if(parsed[iCount] != null && parsed[iCount].length()>1){
            // if a word ENDS in ? then strip it off
            parsed[iCount] = parsed[iCount].replaceAll("[^a-zA-Z0-9 ]","");
           }
        }catch(Exception e){
          e.printStackTrace();
        }
          iCount++;
        }


      /*
       * handle simple help or ? command.
       * parsed[0] is our first word... parsed[1] the second, etc.
       * we can use iCount from above as needed to see how many...
       * ...words got found.
       */
      if(parsed[0].equalsIgnoreCase("?") || 
        parsed[0].equalsIgnoreCase("help")){
          outputArea.setText("");// erase the output "screen"
          outputArea.append("\nPut help code in here...\n");
        }
      }

      // handle other noun and verb checks of parsed[] array in here...

    }// end of if(tok.countTokens() > 0)... 

}// end of public void parseText() method

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

आदर्श - ठीक है, तो अब आप आगे क्या करेंगे एक एक्शन क्लास बनाएं और एक एक्शन के लिए स्कैन करें (यानी "दीपक प्राप्त करें" या "ड्रॉप तलवार")। इसे सरल बनाने के लिए आपको गुंजाइश में दिखाई देने वाली हर चीज को स्कैन करने के लिए एक रूमस्कैन ऑब्जेक्ट या तरीका होना चाहिए और उस एक्शन पर केवल उन ऑब्जेक्ट्स के लिए स्कैन करना होगा। ऑब्जेक्ट स्वयं एक्शन हैंडलिंग को संभालता है और डिफ़ॉल्ट रूप से आपके पास एक आइटम क्लास होना चाहिए जो सभी ज्ञात क्रियाओं को डिफ़ॉल्ट रूप से संभालता है, जिसे ओवर-राइड किया जा सकता है। अब, यदि उदाहरण के लिए, एक आइटम जिसे आप "प्राप्त करना चाहते हैं" एक गैर-खिलाड़ी चरित्र द्वारा आयोजित किया जाता है, तो उस आइटम को उसके मालिक द्वारा प्राप्त करने के लिए डिफ़ॉल्ट प्रतिक्रिया कुछ इस तरह होनी चाहिए "जैसे कि आपके पास यह नहीं होगा।" अब आपको आइटम या थिंग क्लास में इस पर डिफ़ॉल्ट कार्रवाई प्रतिक्रियाओं का एक टन बनाना होगा। यह मूल रूप से सभी डिजाइन पर एक Tads3 परिप्रेक्ष्य से आ रहा है। क्योंकि Tads3 में प्रत्येक आइटम का अपना डिफॉल्ट एक्शन हैंडलिंग रूटीन होता है, जिस पर पार्सर कॉल करता है यदि उस पर कोई कार्रवाई शुरू होती है। तो ... मैं आपको बता रहा हूं, Tads3 में पहले से ही यह सब है, इसलिए यह बहुत ही आसान है कि उस भाषा में एक टेक्स्ट एडवेंचर में कोड करें। लेकिन अगर आप इसे स्क्रैच से करना चाहते हैं, जैसे कि जावा (ऊपर) में, तो मैं व्यक्तिगत रूप से इसे उसी तरह से संभालूंगा जिस तरह से टैडस 3 को डिजाइन किया गया था। इस तरह, आप विभिन्न ऑब्जेक्ट्स पर रूटीन को संभालने वाली डिफ़ॉल्ट क्रियाओं को स्वयं ओवरराइड कर सकते हैं, इसलिए उदाहरण के लिए यदि आप "दीपक प्राप्त करना चाहते हैं" और बटलर इसे पकड़ रहा है, तो यह आइटम के लिए डिफ़ॉल्ट के "प्राप्त" एक्शन विधि में एक प्रतिक्रिया को ट्रिगर कर सकता है। या ऑब्जेक्ट और आपको बता दें कि "बटलर पीतल के दीपक को सौंपने से इनकार करता है।" मेरा मतलब है ... एक बार जब आप एक प्रोग्रामर की तरह लंबे समय तक मेरे पास हैं, तो यह सब बहुत आसान सामान है। मैं 50 साल से अधिक उम्र का हूं और जब मैं 7 साल का था तब से ऐसा कर रहा हूं। मेरे पिता 70 के दशक में हेवलेट पैकर्ड इंस्ट्रक्टर थे इसलिए मैंने शुरू में उनसे कंप्यूटर प्रोग्रामिंग पर एक TON सीखा। मैं यूएस आर्मी रिज़र्व में भी मूल रूप से सर्वर प्रशासक के रूप में हूँ। बेनाम: उम ... बेनाम: हाँ, तो हार मत करो। यह कठिन नहीं है कि एक बार आप वास्तव में इसे तोड़ दें जो आप अपने कार्यक्रम को करना चाहते हैं। कभी-कभी परीक्षण और त्रुटि इस तरह के सामान पर जाने का सबसे अच्छा तरीका है। बस इसे परखें और देखें और कभी हार न मानें। ठीक है? कोडिंग एक कला है। यह कई अलग-अलग तरीकों से किया जा सकता है। एक तरह से या दूसरे को डिजाइन पर एक कोने में ब्लॉक करने न दें। अमेरिकी सेना में भी मी मूल रूप से एक सर्वर प्रशासक के रूप में आरक्षित है। बेनाम: उम ... बेनाम: हाँ, तो हार मत करो। यह कठिन नहीं है कि एक बार आप वास्तव में इसे तोड़ दें जो आप अपने कार्यक्रम को करना चाहते हैं। कभी-कभी परीक्षण और त्रुटि इस तरह के सामान पर जाने का सबसे अच्छा तरीका है। बस इसे परखें और देखें और कभी हार न मानें। ठीक है? कोडिंग एक कला है। यह कई अलग-अलग तरीकों से किया जा सकता है। एक तरह से या दूसरे को डिजाइन पर एक कोने में ब्लॉक करने न दें। अमेरिकी सेना में भी मी मूल रूप से एक सर्वर प्रशासक के रूप में आरक्षित है। बेनाम: उम ... बेनाम: हाँ, तो हार मत करो। यह कठिन नहीं है कि एक बार आप वास्तव में इसे तोड़ दें जो आप अपने कार्यक्रम को करना चाहते हैं। कभी-कभी परीक्षण और त्रुटि इस तरह के सामान पर जाने का सबसे अच्छा तरीका है। बस इसे परखें और देखें और कभी हार न मानें। ठीक है? कोडिंग एक कला है। यह कई अलग-अलग तरीकों से किया जा सकता है। एक तरह से या दूसरे को डिजाइन पर एक कोने में ब्लॉक करने न दें।


यह दुर्भाग्य से एक पाठ पार्सर के सबसे कठिन हिस्से को छोड़ देता है, अर्थात् उपयोगकर्ता इनपुट की क्रिया, विषय और वस्तु की पहचान करता है और इसे एक कार्रवाई के लिए मैप करता है।
फिलिप

सही है, लेकिन मैं यह कैसे करूंगा कि एक एक्शन क्लास बनाऊं और एक डिक्शनरी स्टोर करूं, कहूं, एक डिक्शनरी क्लास, फिर एक्शन शब्दों के लिए स्कैन करें। यदि कार्रवाई में एक 2 शब्द शामिल होता है (जैसे "ले" कार्रवाई के लिए, शायद "दीपक ले") तो आइटम का एक गुच्छा (या संज्ञा) वस्तुओं को स्कैन किया जाए, जहां उन वस्तुओं के लिए खुद उन पर किए गए कार्यों को संभालने के लिए स्क्रिप्ट होगी। यह सब मान रहा है कि आप पूरी चीज़ को जावा में सही कोड करेंगे और कोशिश नहीं करेंगे और पाठ रोमांच को संकलित करने के लिए एक वास्तविक बाहरी फ़ाइल पढ़ें।
विलियम चेलोनीस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.