एक क्रॉसवर्ड उत्पन्न करने के लिए एल्गोरिदम


123

शब्दों की एक सूची को देखते हुए, आप उन्हें एक क्रॉसवर्ड ग्रिड में व्यवस्थित करने के बारे में कैसे जाएंगे?

यह एक "उचित" क्रॉसवर्ड पहेली की तरह नहीं होगा जो सममित या ऐसा कुछ भी हो: मूल रूप से प्रत्येक शब्द के लिए एक प्रारंभिक स्थिति और दिशा का उत्पादन होता है।

जवाबों:


62

मैं एक समाधान के साथ आया था जो शायद सबसे कुशल नहीं है, लेकिन यह काफी अच्छी तरह से काम करता है। मूल रूप से:

  1. उतरते हुए सभी शब्दों को क्रमबद्ध करें।
  2. पहला शब्द लें और इसे बोर्ड पर रखें।
  3. अगला शब्द लीजिए।
  4. उन सभी शब्दों के माध्यम से खोजें जो पहले से ही बोर्ड पर हैं और देखें कि क्या इस शब्द के साथ कोई संभावित चौराहे (कोई भी सामान्य अक्षर) हैं।
  5. यदि इस शब्द के लिए एक संभावित स्थान है, तो उन सभी शब्दों के माध्यम से लूप करें जो बोर्ड पर हैं और यह देखने के लिए जांचें कि क्या नया शब्द हस्तक्षेप करता है।
  6. यदि यह शब्द बोर्ड को नहीं तोड़ता है, तो इसे वहां रखें और चरण 3 पर जाएं, अन्यथा, एक स्थान (चरण 4) की खोज जारी रखें।
  7. इस लूप को तब तक जारी रखें जब तक कि सभी शब्दों को या तो रखा न जाए या रखा न जाए।

यह एक काम करता है, अभी तक अक्सर काफी गरीब वर्ग। बेहतर परिणाम के साथ आने के लिए मैंने ऊपर दिए गए मूल नुस्खा में कई परिवर्तन किए।

  • एक क्रॉसवर्ड उत्पन्न करने के अंत में, इसे यह स्कोर दें कि कितने शब्दों को रखा गया (अधिक बेहतर), बोर्ड कितना बड़ा (बेहतर छोटा), और ऊंचाई और चौड़ाई के बीच का अनुपात (करीब) 1 से बेहतर)। कई वर्ग पहेली उत्पन्न करें और फिर अपने स्कोर की तुलना करें और सर्वश्रेष्ठ चुनें।
    • पुनरावृत्तियों की एक मनमानी संख्या को चलाने के बजाय, मैंने समय की एक मनमानी मात्रा में यथासंभव अधिक से अधिक वर्ग पहेली बनाने का निर्णय लिया है। यदि आपके पास केवल एक छोटी सी शब्द सूची है, तो आपको 5 सेकंड में दर्जनों संभावित क्रॉसवर्ड मिलेंगे। एक बड़ा क्रॉसवर्ड केवल 5-6 संभावनाओं से चुना जा सकता है।
  • जब कोई नया शब्द रखते हैं, तो उसे स्वीकार्य स्थान खोजने के बजाय तुरंत रखने के बजाय, उस शब्द स्थान को ग्रिड के आकार को बढ़ाता है और कितने चौराहों पर आधारित है (आदर्श रूप से आप प्रत्येक शब्द चाहते हैं) 2-3 अन्य शब्दों के पार)। सभी पदों और उनके स्कोर पर नज़र रखें और फिर सबसे अच्छा चुनें।

7
जैसा कि हम बोलते हैं, वैसे ही मैं इस कार्यक्रम को लिखता जा रहा हूं, और यह वही अलगोर्म है जिसे मैंने भी चुना था। शब्दों की छोटी संख्या (10 या उससे कम) के लिए, कार्यक्रम को मिलीसेकंड में सभी संभावित समाधानों की गणना करने में कोई परेशानी नहीं है। हालांकि, एलगोरिटम घातीय है। आसान हिस्सा बुनियादी एल्गोरिथ्म लिख रहा है जो सभी संभावित संयोजनों के माध्यम से बल देता है। कठिन हिस्सा दर्जन या तो 'शॉर्ट-कट' है आपको कार्यक्रम को सभी मृत-अंत समाधानों की कोशिश करने से रोकने की आवश्यकता है।
user31586

2
"5. ... और जांचें कि क्या नया शब्द हस्तक्षेप करता है" आप उन स्थितियों के लिए कैसे खाते हैं जहां नया शब्द किसी मौजूदा शब्द के साथ है, जो उन स्थानों पर जिबरिश पैदा करता है जहां उसके आस-पास के वर्ग हैं? जैसे: LEMON ERASE if "LE", "ER" और "MA" आदि आपकी सूची में शब्द नहीं हैं, तो यह गलत है। दूसरी ओर, इस तरह की आसन्नता को खारिज करना वास्तव में अच्छे ग्रिड को फेंक सकता है, जैसे: W LEMON
ERASE

4
@ कैफीन, हां मुझे पता है कि आपका क्या मतलब है - मुझे इन विकल्पों को बाहर फेंकना पड़ा क्योंकि भले ही वे वास्तव में अच्छे ग्रिड बना सकें, यह जांचना बहुत मुश्किल है (पढ़ें: मुझे परेशान नहीं किया जा सकता) , और संभावना है कि यह सिर्फ वैसे भी हस्तक्षेप है ।
निक सिप

4
ऊपर की सिफारिशों और मेरे खुद के कुछ का उपयोग करके jQuery / जावास्क्रिप्ट के साथ बनाया गया ... mlewiscs.com/crossword
MLewisCodeSolutions

@MLewisCodeSolutions बहुत बढ़िया लग रहा है। क्या आप इसे ओपन-सोर्स कर रहे हैं?
GKS

23

मैंने हाल ही में पायथन में अपना खुद का लिखा है। आप इसे यहाँ पा सकते हैं: http://bryanhelmig.com/python-crossword-puzzle-generator/ । यह घने NYT शैली वर्ग पहेली नहीं बनाता है, लेकिन वर्ग पहेली की शैली आपको एक बच्चे की पहेली पुस्तक में मिल सकती है।

कुछ एल्गोरिदम के विपरीत मुझे वहां पता चला कि शब्दों को रखने का एक यादृच्छिक जानवर-बल पद्धति लागू की गई है जैसे कुछ ने सुझाव दिया है, मैंने शब्द प्लेसमेंट पर थोड़ा चालाक जानवर-बल दृष्टिकोण लागू करने की कोशिश की। यहाँ मेरी प्रक्रिया है:

  1. जो भी आकार और शब्दों की सूची का एक ग्रिड बनाएं।
  2. शब्द सूची में फेरबदल करें, और फिर शब्दों को सबसे लंबे समय तक छोटा करके क्रमबद्ध करें।
  3. ऊपरी और सबसे बाईं ओर स्थित पहला और सबसे लंबा शब्द रखें, 1,1 (लंबवत या क्षैतिज)।
  4. अगले शब्द पर आगे बढ़ें, शब्द के प्रत्येक अक्षर पर लूप और ग्रिड में प्रत्येक सेल को लेटर टू लेटर मैचों की तलाश करें।
  5. जब एक मैच पाया जाता है, तो बस उस शब्द के लिए सुझाई गई समन्वय सूची में उस स्थिति को जोड़ें।
  6. सुझाए गए निर्देशांक सूची और "स्कोर" शब्द प्लेसमेंट के आधार पर लूप करें कि यह कितने अन्य शब्दों को पार करता है। 0 का स्कोर या तो खराब प्लेसमेंट (मौजूदा शब्दों से सटे) या कोई शब्द क्रॉस नहीं थे।
  7. शब्द सूची समाप्त होने तक चरण # 4 पर वापस जाएं। वैकल्पिक दूसरा पास।
  8. अब हमारे पास एक क्रॉसवर्ड होना चाहिए, लेकिन कुछ यादृच्छिक प्लेसमेंट के कारण गुणवत्ता हिट या मिस हो सकती है। इसलिए, हम इस क्रॉसवर्ड को बफर करते हैं और # 2 चरण पर वापस जाते हैं। यदि अगले क्रॉसवर्ड में बोर्ड पर अधिक शब्द हैं, तो यह बफर में क्रॉसवर्ड को बदल देता है। यह समय सीमित है (x सेकंड में सबसे अच्छा क्रॉसवर्ड ढूंढें)।

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


@ नील एन: संभवतः दूसरे शब्दों के लिए एक बेहतर पत्र मिलान संभावना है। संभवत: प्रति शब्द में निहित अलग-अलग अक्षरों की गिनती के आधार पर छांटने के लिए भी एक दृष्टिकोण होगा, जो ज्यादातर उसी परिणाम को जन्म देगा।
कार्ल एडलर

@ नील मिलन array.sort(key=f)स्थिर है, जिसका अर्थ है (उदाहरण के लिए) जो केवल लंबाई द्वारा एक वर्णमाला शब्द सूची को क्रमबद्ध कर रहा है, सभी 8-अक्षर शब्दों को वर्णानुक्रम में क्रमबद्ध रखेगा।
लिन

4
@ ब्रायन, आपकी वेबसाइट लिंक मेरे लिए काम नहीं करती है, और प्राथमिक डोमेन ट्विटर पर पुनर्निर्देशित करता है। क्या आपके पास अपने कोड का अद्यतन लिंक है?
माइकल ए

2
यहाँ (जाहिरा तौर पर) ब्रायन के जनरेटर का एक क्लोन है: github.com/jeremy886/crossword_helmig
lvictorino

20

मैंने वास्तव में लगभग दस साल पहले एक क्रॉसवर्ड पीढ़ी का कार्यक्रम लिखा था (यह गूढ़ था लेकिन सामान्य वर्ग के लिए वही नियम लागू होंगे)।

इसमें शब्दों की एक सूची थी (और संबद्ध सुराग) एक फ़ाइल में संग्रहित थी जो आज तक अवरोही उपयोग द्वारा सॉर्ट की गई थी (ताकि कम-उपयोग किए गए शब्द फ़ाइल के शीर्ष पर थे)। एक टेम्पलेट, जो मूल रूप से काले और मुक्त वर्गों का प्रतिनिधित्व करने वाला एक बिट-मास्क था, जिसे क्लाइंट द्वारा प्रदान किए गए पूल से बेतरतीब ढंग से चुना गया था।

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

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

एक बार जब शब्द / सुराग फ़ाइल एक निश्चित आकार तक बढ़ जाती है (और इस ग्राहक के लिए एक दिन में 50-100 सुराग जोड़ रहा था), तो शायद ही कभी दो या तीन से अधिक मैनुअल फिक्स अप का मामला था जो प्रत्येक क्रॉसवर्ड के लिए किया जाना था। ।


यह वास्तव में मेरी स्थिति में मेरी मदद नहीं करता है, क्योंकि मेरे पास केवल 6-12 शब्दों की एक सूची होगी। मेरा एक शब्द पहेली की तुलना में उपयोगकर्ता के लिए सीखने के व्यायाम की तरह है। वैसे भी दिलचस्प एल्गोरिथ्म के लिए +1!
निक

1
अच्छा वर्णन। मैंने अतीत में कुछ बार इस बारे में सोचा था, लेकिन कभी कोशिश नहीं की। अब जादू के सवाल के लिए: यह कितना अच्छा था? बस विरल पहेली के लिए, या घने लोगों के लिए भी (जैसे कागज में)? और घनी पहेली के लिए आपको कितने सुराग चाहिए?
dmckee --- पूर्व-मध्यस्थ ने

1
@ मिकी, यह कुछ समय पहले था, लेकिन स्मृति से, यहां तक ​​कि घनी पहेलियाँ भी बहुत अच्छी थीं। कई हस्तक्षेप के बिना पूरा हो गए थे, लेकिन आपको अभी भी एक पांचवें को एक या दो अतिरिक्त शब्दों की आवश्यकता होगी। और हम फाइल में हजारों शब्दों के बारे में बात कर रहे हैं। कोई संदेह नहीं है कि बैकग्राउंडिंग मदद कर सकती थी, लेकिन क्लाइंट के लिए अतिरिक्त सुरागों के साथ आने की कोशिश करने की चिंता की तुलना में एक (जैसे) 5 अधूरे शब्दों को अस्वीकार करना आसान था। पाँच बाहरी सीमा के बारे में थे जो मैंने अधूरे शब्दों के लिए देखे थे।
पैक्सडिब्लो

16

यह एल्गोरिथ्म 50 घना 6x9 बनाता है 60 सेकंड में एरो क्रॉसवर्ड । यह एक शब्द डेटाबेस (शब्द + युक्तियों के साथ) और एक बोर्ड डेटाबेस (पूर्व-कॉन्फ़िगर बोर्डों के साथ) का उपयोग करता है।

1) Search for all starting cells (the ones with an arrow), store their size and directions
2) Loop through all starting cells
2.1) Search a word
2.1.1) Check if it was not already used
2.1.2) Check if it fits
2.2) Add the word to the board
3) Check if all cells were filled

एक बड़ा शब्द डेटाबेस पीढ़ी समय को काफी कम कर देता है और कुछ प्रकार के बोर्डों को भरना मुश्किल होता है! बड़े बोर्डों को सही ढंग से भरने के लिए अधिक समय की आवश्यकता होती है!


उदाहरण:

पूर्व-कॉन्फ़िगर 6x9 बोर्ड:

(# मतलब एक सेल में एक टिप,% का मतलब है एक सेल में दो टिप्स, नहीं दिखाए गए तीर)

# - # # - % # - # 
- - - - - - - - - 
# - - - - - # - - 
% - - # - # - - - 
% - - - - - % - - 
- - - - - - - - - 

उत्पन्न 6x9 बोर्ड:

# C # # P % # O # 
S A T E L L I T E 
# N I N E S # T A 
% A B # A # G A S 
% D E N S E % W E 
C A T H E D R A L 

युक्तियाँ [पंक्ति, स्तंभ]:

[1,0] SATELLITE: Used for weather forecast
[5,0] CATHEDRAL: The principal church of a city
[0,1] CANADA: Country on USA's northern border
[0,4] PLEASE: A polite way to ask things
[0,7] OTTAWA: Canada's capital
[1,2] TIBET: Dalai Lama's region
[1,8] EASEL: A tripod used to put a painting
[2,1] NINES: Dressed up to (?)
[4,1] DENSE: Thick; impenetrable
[3,6] GAS: Type of fuel
[1,5] LS: Lori Singer, american actress
[2,7] TA: Teaching assistant (abbr.)
[3,1] AB: A blood type
[4,3] NH: New Hampshire (abbr.)
[4,5] ED: (?) Harris, american actor
[4,7] WE: The first person of plural (Grammar)

11

हालांकि यह एक पुराना सवाल है, मैं इसी तरह के काम के आधार पर उत्तर देने का प्रयास करूंगा।

बाधा समस्याओं को हल करने के लिए कई दृष्टिकोण हैं (जो कि सामान्य रूप से एनपीसी जटिलता वर्ग में हैं)।

यह कॉम्बिनेटरियल ऑप्टिमाइज़ेशन और बाधा प्रोग्रामिंग से संबंधित है। इस मामले में अड़चनें ग्रिड की ज्यामिति और आवश्यकता है कि शब्द अद्वितीय आदि हैं।

रैंडमाइजेशन / एनलिंग दृष्टिकोण भी काम कर सकते हैं (हालांकि उचित सेटिंग के भीतर)।

कुशल सादगी सिर्फ परम ज्ञान हो सकता है!

आवश्यकताएँ अधिक या कम पूर्ण क्रॉसवर्ड कंपाइलर और (विज़ुअल WYSIWYG) बिल्डर के लिए थीं।

WYSIWYG बिल्डर भाग को छोड़कर, संकलक रूपरेखा यह थी:

  1. उपलब्ध शब्दसूची लोड करें (शब्द की लंबाई के आधार पर छांटे, अर्थात 2,3, .., 20)

  2. उपयोगकर्ता-निर्मित ग्रिड (जैसे x पर शब्द, लंबाई L, क्षैतिज या लंबवत) (जटिलता O (N)) पर शब्द-शब्द (यानी ग्रिड शब्द) खोजें

  3. ग्रिड शब्दों (जो भरे जाने की आवश्यकता है) के जटिल बिंदुओं की गणना करें (जटिलता O (N ^ 2))

  4. उपयोग किए गए वर्णमाला के विभिन्न अक्षरों के साथ शब्दसूची में शब्दों के अंतरों की गणना करें (यह एक टेम्पलेट का उपयोग करके मिलान शब्दों की खोज करने की अनुमति देता है। सीसीकंबॉन थीसिस का उपयोग cwc द्वारा किया जाता है ) (जटिलता ओ (WL * AL))

चरण .3 और .4 इस कार्य को करने की अनुमति देते हैं:

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

ख। वर्णमाला के साथ एक शब्दसूची में शब्दों के अंतर मिलान (उम्मीदवार) शब्दों को खोजने में सक्षम होते हैं जो किसी दिए गए "टेम्पलेट" से मेल खाते हैं (उदाहरण के लिए 1 स्थान पर 'ए' और तीसरे स्थान पर 'बी' आदि)।

इसलिए इन डेटा संरचनाओं को लागू करने के लिए इस्तेमाल किया एल्गोरिथ्म इस तरह से था:

नोट: यदि ग्रिड और शब्दों का डेटाबेस स्थिर है तो पिछले चरण सिर्फ एक बार किए जा सकते हैं।

  1. एल्गोरिथ्म का पहला चरण यादृच्छिक पर एक खाली शब्द-शब्द (ग्रिड शब्द) का चयन करें और इसे अपने संबंधित शब्दसूची से एक उम्मीदवार शब्द के साथ भरें (रैंडमाइजेशन एल्गोरिदम के लगातार निष्पादन में विभिन्न विलेयन्स बनाने में सक्षम बनाता है) (जटिलता ओ (1) या ओ) एन))

  2. प्रत्येक अभी भी खाली शब्द स्लॉट के लिए (जिसमें पहले से ही भरे हुए शब्द-बिंदुओं के साथ चौराहे हैं), एक बाधा अनुपात की गणना करें (यह अलग-अलग हो सकता है, sth सरल उस चरण में उपलब्ध समाधानों की संख्या है) और इस अनुपात द्वारा रिक्त शब्द-बिंदुओं को क्रमबद्ध करें (Complex O) (NlogN) ) या ओ (एन)

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

  4. उस शब्द को भरें (भरे हुए के रूप में चिह्नित करें और चरण 2 पर जाएं)

  5. यदि कोई शब्द नहीं मिला जो कि चरण के मानदंड को संतुष्ट करता है। 3 कुछ पिछले चरण के दूसरे उम्मीदवार समाधान के लिए पीछे हटने का प्रयास करें (मानदंड यहां भिन्न हो सकते हैं) (जटिलता ओ (एन))

  6. यदि बैकट्रैक मिला, तो वैकल्पिक का उपयोग करें और वैकल्पिक रूप से किसी भी पहले से भरे शब्दों को रीसेट करें जिन्हें रीसेट की आवश्यकता हो सकती है (उन्हें फिर से अनफिल्टर्ड करें) (जटिलता ओ (एन))

  7. यदि कोई बैकट्रैक नहीं मिला, तो कोई समाधान नहीं मिल सकता है (कम से कम इस कॉन्फ़िगरेशन, प्रारंभिक बीज आदि के साथ)।

  8. जब सभी शब्द-पत्र भर जाते हैं तो आपके पास एक ही उपाय होता है

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

संगतता भाग सुनिश्चित करता है कि पाया गया एक समाधान वास्तव में एक समाधान है और यादृच्छिक भाग विभिन्न निष्पादन में विभिन्न समाधानों का उत्पादन करने में सक्षम बनाता है और औसतन बेहतर प्रदर्शन भी करता है।

पुनश्च। यह सब (और अन्य) शुद्ध जावास्क्रिप्ट (समानांतर प्रसंस्करण और WYSIWYG) क्षमता के साथ लागू किया गया था

पीएस 2। एक ही समय में एक से अधिक (अलग) समाधान का उत्पादन करने के लिए एल्गोरिथ्म को आसानी से समानांतर किया जा सकता है

उम्मीद है की यह मदद करेगा


1
क्या यह घने लेआउट (NY Times like) या विरल लेआउट बनाने के लिए है?
जिम

1
@ जिम, यह ज्यादातर घने लेआउट के लिए है, लेकिन विरल के लिए भी समायोजित किया जा सकता है। अंतर घने लेआउट (जैसे क्लासिक, स्कैंडिनेविक आदि) में है, एक में ग्रिड और शब्दों की खोज होती है, जबकि फ्रीफॉर्म लेआउट (विरल) के लिए शब्द और ग्रिड के लिए खोज होती है।
निकोस एम।

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

1
@ मुझे, जैसा कि यह पहले से ही उपयोग किया जाता है, लेकिन यह मेरे पास एक नौकरी के लिए विशिष्ट रूप से किया गया था, यह संभव है कि मैं अपने खुले स्रोत परियोजनाओं पर एक हल्के वजन वाला संस्करण पोस्ट करूं, यदि आपको अधिक सहायता की आवश्यकता हो तो मुझसे संपर्क करें (ps वास्तव में) कुछ मामलों में जो एल्गोरिथ्म मैंने पोस्ट किया है वह बहुत लंबा हो सकता है, लेकिन औसतन यह नहीं होता है)
निकोस एम।

1
@Jim, इस वर्ग पहेली साइट (अभी भी प्रगति पर) istavrolexo.gr (ग्रीक में) पर विभिन्न (घने) वर्ग पहेली (यानी स्कैंडिनेविक, क्लासिक, सुडोकू) पर एक नज़र डालें , जो एक समान एल्गोरिथ्म ( एक बड़े स्कैंडिनेविक क्रॉसवर्ड ) से उत्पन्न हुए हैं
निकोस एम।

9

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

आपको आश्चर्य होगा कि इस तरह का मोंटे कार्लो दृष्टिकोण कितनी बार काम करता है।


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

6

यहाँ कुछ जावास्क्रिप्ट कोड है जो कि निक के उत्तर और ब्रायन के पायथन कोड पर आधारित है। बस इसे पोस्ट करने की स्थिति में किसी और को इसकी आवश्यकता होती है।

function board(cols, rows) { //instantiator object for making gameboards
this.cols = cols;
this.rows = rows;
var activeWordList = []; //keeps array of words actually placed in board
var acrossCount = 0;
var downCount = 0;

var grid = new Array(cols); //create 2 dimensional array for letter grid
for (var i = 0; i < rows; i++) {
    grid[i] = new Array(rows);
}

for (var x = 0; x < cols; x++) {
    for (var y = 0; y < rows; y++) {
        grid[x][y] = {};
        grid[x][y].targetChar = EMPTYCHAR; //target character, hidden
        grid[x][y].indexDisplay = ''; //used to display index number of word start
        grid[x][y].value = '-'; //actual current letter shown on board
    }
}

function suggestCoords(word) { //search for potential cross placement locations
    var c = '';
    coordCount = [];
    coordCount = 0;
    for (i = 0; i < word.length; i++) { //cycle through each character of the word
        for (x = 0; x < GRID_HEIGHT; x++) {
            for (y = 0; y < GRID_WIDTH; y++) {
                c = word[i];
                if (grid[x][y].targetChar == c) { //check for letter match in cell
                    if (x - i + 1> 0 && x - i + word.length-1 < GRID_HEIGHT) { //would fit vertically?
                        coordList[coordCount] = {};
                        coordList[coordCount].x = x - i;
                        coordList[coordCount].y = y;
                        coordList[coordCount].score = 0;
                        coordList[coordCount].vertical = true;
                        coordCount++;
                    }

                    if (y - i + 1 > 0 && y - i + word.length-1 < GRID_WIDTH) { //would fit horizontally?
                        coordList[coordCount] = {};
                        coordList[coordCount].x = x;
                        coordList[coordCount].y = y - i;
                        coordList[coordCount].score = 0;
                        coordList[coordCount].vertical = false;
                        coordCount++;
                    }
                }
            }
        }
    }
}

function checkFitScore(word, x, y, vertical) {
    var fitScore = 1; //default is 1, 2+ has crosses, 0 is invalid due to collision

    if (vertical) { //vertical checking
        for (i = 0; i < word.length; i++) {
            if (i == 0 && x > 0) { //check for empty space preceeding first character of word if not on edge
                if (grid[x - 1][y].targetChar != EMPTYCHAR) { //adjacent letter collision
                    fitScore = 0;
                    break;
                }
            } else if (i == word.length && x < GRID_HEIGHT) { //check for empty space after last character of word if not on edge
                 if (grid[x+i+1][y].targetChar != EMPTYCHAR) { //adjacent letter collision
                    fitScore = 0;
                    break;
                }
            }
            if (x + i < GRID_HEIGHT) {
                if (grid[x + i][y].targetChar == word[i]) { //letter match - aka cross point
                    fitScore += 1;
                } else if (grid[x + i][y].targetChar != EMPTYCHAR) { //letter doesn't match and it isn't empty so there is a collision
                    fitScore = 0;
                    break;
                } else { //verify that there aren't letters on either side of placement if it isn't a crosspoint
                    if (y < GRID_WIDTH - 1) { //check right side if it isn't on the edge
                        if (grid[x + i][y + 1].targetChar != EMPTYCHAR) { //adjacent letter collision
                            fitScore = 0;
                            break;
                        }
                    }
                    if (y > 0) { //check left side if it isn't on the edge
                        if (grid[x + i][y - 1].targetChar != EMPTYCHAR) { //adjacent letter collision
                            fitScore = 0;
                            break;
                        }
                    }
                }
            }

        }

    } else { //horizontal checking
        for (i = 0; i < word.length; i++) {
            if (i == 0 && y > 0) { //check for empty space preceeding first character of word if not on edge
                if (grid[x][y-1].targetChar != EMPTYCHAR) { //adjacent letter collision
                    fitScore = 0;
                    break;
                }
            } else if (i == word.length - 1 && y + i < GRID_WIDTH -1) { //check for empty space after last character of word if not on edge
                if (grid[x][y + i + 1].targetChar != EMPTYCHAR) { //adjacent letter collision
                    fitScore = 0;
                    break;
                }
            }
            if (y + i < GRID_WIDTH) {
                if (grid[x][y + i].targetChar == word[i]) { //letter match - aka cross point
                    fitScore += 1;
                } else if (grid[x][y + i].targetChar != EMPTYCHAR) { //letter doesn't match and it isn't empty so there is a collision
                    fitScore = 0;
                    break;
                } else { //verify that there aren't letters on either side of placement if it isn't a crosspoint
                    if (x < GRID_HEIGHT) { //check top side if it isn't on the edge
                        if (grid[x + 1][y + i].targetChar != EMPTYCHAR) { //adjacent letter collision
                            fitScore = 0;
                            break;
                        }
                    }
                    if (x > 0) { //check bottom side if it isn't on the edge
                        if (grid[x - 1][y + i].targetChar != EMPTYCHAR) { //adjacent letter collision
                            fitScore = 0;
                            break;
                        }
                    }
                }
            }

        }
    }

    return fitScore;
}

function placeWord(word, clue, x, y, vertical) { //places a new active word on the board

    var wordPlaced = false;

    if (vertical) {
        if (word.length + x < GRID_HEIGHT) {
            for (i = 0; i < word.length; i++) {
                grid[x + i][y].targetChar = word[i];
            }
            wordPlaced = true;
        }
    } else {
        if (word.length + y < GRID_WIDTH) {
            for (i = 0; i < word.length; i++) {
                grid[x][y + i].targetChar = word[i];
            }
            wordPlaced = true;
        }
    }

    if (wordPlaced) {
        var currentIndex = activeWordList.length;
        activeWordList[currentIndex] = {};
        activeWordList[currentIndex].word = word;
        activeWordList[currentIndex].clue = clue;
        activeWordList[currentIndex].x = x;
        activeWordList[currentIndex].y = y;
        activeWordList[currentIndex].vertical = vertical;

        if (activeWordList[currentIndex].vertical) {
            downCount++;
            activeWordList[currentIndex].number = downCount;
        } else {
            acrossCount++;
            activeWordList[currentIndex].number = acrossCount;
        }
    }

}

function isActiveWord(word) {
    if (activeWordList.length > 0) {
        for (var w = 0; w < activeWordList.length; w++) {
            if (word == activeWordList[w].word) {
                //console.log(word + ' in activeWordList');
                return true;
            }
        }
    }
    return false;
}

this.displayGrid = function displayGrid() {

    var rowStr = "";
    for (var x = 0; x < cols; x++) {

        for (var y = 0; y < rows; y++) {
            rowStr += "<td>" + grid[x][y].targetChar + "</td>";
        }
        $('#tempTable').append("<tr>" + rowStr + "</tr>");
        rowStr = "";

    }
    console.log('across ' + acrossCount);
    console.log('down ' + downCount);
}

//for each word in the source array we test where it can fit on the board and then test those locations for validity against other already placed words
this.generateBoard = function generateBoard(seed = 0) {

    var bestScoreIndex = 0;
    var top = 0;
    var fitScore = 0;
    var startTime;

    //manually place the longest word horizontally at 0,0, try others if the generated board is too weak
    placeWord(wordArray[seed].word, wordArray[seed].displayWord, wordArray[seed].clue, 0, 0, false);

    //attempt to fill the rest of the board 
    for (var iy = 0; iy < FIT_ATTEMPTS; iy++) { //usually 2 times is enough for max fill potential
        for (var ix = 1; ix < wordArray.length; ix++) {
            if (!isActiveWord(wordArray[ix].word)) { //only add if not already in the active word list
                topScore = 0;
                bestScoreIndex = 0;

                suggestCoords(wordArray[ix].word); //fills coordList and coordCount
                coordList = shuffleArray(coordList); //adds some randomization

                if (coordList[0]) {
                    for (c = 0; c < coordList.length; c++) { //get the best fit score from the list of possible valid coordinates
                        fitScore = checkFitScore(wordArray[ix].word, coordList[c].x, coordList[c].y, coordList[c].vertical);
                        if (fitScore > topScore) {
                            topScore = fitScore;
                            bestScoreIndex = c;
                        }
                    }
                }

                if (topScore > 1) { //only place a word if it has a fitscore of 2 or higher

                    placeWord(wordArray[ix].word, wordArray[ix].clue, coordList[bestScoreIndex].x, coordList[bestScoreIndex].y, coordList[bestScoreIndex].vertical);
                }
            }

        }
    }
    if(activeWordList.length < wordArray.length/2) { //regenerate board if if less than half the words were placed
        seed++;
        generateBoard(seed);
    }
}
}
function seedBoard() {
    gameboard = new board(GRID_WIDTH, GRID_HEIGHT);
    gameboard.generateBoard();
    gameboard.displayGrid();
}

शब्द वस्तु स्कीमा याद आ रही है, wordArray प्रदान करें
यानी

['सेब ’,, ऑरेंज’,] नाशपाती ’जैसे शब्दों का केवल एक सरणी
फासिस्ट डोनट

नमस्ते, FYI करें मेरे संपादन ने बहुत सारे कोड नहीं बदले, बस इसे स्वरूपित किया। मुझे पता है कि 'इनलाइन' देखने के दौरान यह बहुत गड़बड़ लगता है, लेकिन अगर आप कोड में वास्तविक बदलाव देखना चाहते हैं , तो 'साइड-बाय-साइड-मार्कडाउन' पर क्लिक करें। खैर ... मुझे संपादन विवरण में "प्रारूपित कोड" लिखना चाहिए था, लेकिन meh।
डबल बीप

यह कैसे काम करता है? क्या आप इस जावास्क्रिप्ट को शामिल करते हुए एक html फ़ाइल प्रदान कर सकते हैं?
GKS

5

मैं दो नंबर जेनरेट करूंगा: लंबाई और स्क्रैबल स्कोर। मान लें कि कम स्क्रैबल स्कोर का मतलब है कि इसमें शामिल होना आसान है (कम स्कोर = बहुत सारे सामान्य अक्षर)। सूची को लंबाई अवरोही और स्क्रैबल स्कोर आरोही द्वारा क्रमबद्ध करें।

अगला, बस सूची में नीचे जाएं। यदि शब्द किसी मौजूदा शब्द (क्रमशः उनकी लंबाई और स्क्रैबल स्कोर द्वारा प्रत्येक शब्द के खिलाफ जांच) के साथ पार नहीं करता है, तो इसे कतार में डालें, और अगले शब्द की जांच करें।

कुल्ला और दोहराएं, और यह एक क्रॉसवर्ड उत्पन्न करना चाहिए।

बेशक, मुझे पूरा यकीन है कि यह O (n!) है और यह आपके लिए क्रॉसवर्ड पूरा करने की गारंटी नहीं है, लेकिन शायद कोई इसे सुधार सकता है।


3

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

तो, मेरी सामान्य सोच यह है: कम घनत्व वाले क्रॉस को बनाने के लिए यहां वर्णित कुछ शब्दों के रूप में कुछ हद तक अपेक्षाकृत तेज बल दृष्टिकोण का निर्माण करें, और शब्दकोश शब्दों के साथ रिक्त स्थान भरें।

अगर किसी और ने यह तरीका अपनाया है, तो कृपया मुझे बताएं।


3

मैं क्रॉसवर्ड जनरेटर इंजन के आसपास खेल रहा था, और मुझे यह सबसे महत्वपूर्ण लगा:

0।!/usr/bin/python

  1. ए। allwords.sort(key=len, reverse=True)

    ख। जब तक आप बाद में यादृच्छिक विकल्प द्वारा पुनरावृति नहीं करना चाहते हैं, तब कुछ आइटम / ऑब्जेक्ट को कर्सर की तरह बनाएं जो कि आसान अभिविन्यास के लिए मैट्रिक्स के चारों ओर घूमेंगे।

  2. पहले, पहले जोड़े को उठाएं और उन्हें 0,0 से नीचे और नीचे रखें; हमारे वर्तमान क्रॉसवर्ड 'लीडर' के रूप में पहले स्टोर करें।

  3. आदेश विकर्ण या अगले खाली सेल के लिए अधिक विकर्ण संभावना के साथ यादृच्छिक चाल कर्सर

  4. शब्दों पर पुनरावृति और अधिकतम शब्द लंबाई को परिभाषित करने के लिए मुक्त स्थान लंबाई का उपयोग करें: temp=[] for w_size in range( len( w_space ), 2, -1 ) : # t for w in [ word for word in allwords if len(word) == w_size ] : # if w not in temp and putTheWord( w, w_space ) : # temp.append( w )

  5. मुक्त स्थान के खिलाफ शब्द की तुलना करने के लिए जिसका मैंने उपयोग किया है:

    w_space=['c','.','a','.','.','.'] # whereas dots are blank cells
    
    # CONVERT MULTIPLE '.' INTO '.*' FOR REGEX
    
    pattern = r''.join( [ x.letter for x in w_space ] )
    pattern = pattern.strip('.') +'.*' if pattern[-1] == '.' else pattern
    
    prog = re.compile( pattern, re.U | re.I )
    
    if prog.match( w ) :
        #
        if prog.match( w ).group() == w :
            #
            return True
    
  6. सफलतापूर्वक उपयोग किए गए प्रत्येक शब्द के बाद, दिशा बदलें। लूप जबकि सभी कोशिकाएं भरी हुई हैं या आप शब्दों से बाहर या पुनरावृत्तियों की सीमा से भागते हैं:

# CHANGE ALL WORDS LIST inexOf1stWord = allwords.index( leading_w ) allwords = allwords[:inexOf1stWord+1][:] + allwords[inexOf1stWord+1:][:]

... और फिर से नया क्रॉसवर्ड।

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

  2. पहले पुनरावृत्ति सत्र के बाद नौकरी खत्म करने के लिए किए गए वर्ग पहेली की सूची से फिर से पुनरावृति।

अधिक मापदंडों का उपयोग करके गति को एक विशाल कारक द्वारा सुधारा जा सकता है।


2

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

एक अन्य विचार एक आनुवंशिक एल्गोरिथ्म का निर्माण कर रहा है जहां ताकत मीट्रिक है कि आप ग्रिड में कितने शब्द डाल सकते हैं।

मेरे द्वारा पाया जाने वाला कठिन हिस्सा एक निश्चित सूची को जानना है जिसे संभवतः पार नहीं किया जा सकता है।


1
मैं एक आनुवंशिक एल्गोरिथ्म के बारे में भी सोच रहा था। फिटनेस फंक्शन यह हो सकता है कि शब्दों को कसकर ग्रिड में कैसे पैक किया जाए।
एड्रियन मैक्कार्थी

2

यह एआई CS50 पाठ्यक्रम में एक परियोजना के रूप में दिखाई देता है हार्वर्ड से । विचार यह है कि क्रॉसवर्ड पीढ़ी की समस्या को एक बाधा संतुष्टि समस्या के रूप में तैयार किया जाए और इसे खोज स्थान को कम करने के लिए विभिन्न उत्तराधिकारियों के साथ वापस हल किया जाए।

शुरू करने के लिए हमें कुछ इनपुट फ़ाइलों की आवश्यकता है:

  1. क्रॉसवर्ड पहेली की संरचना (जो निम्नलिखित की तरह दिखती है, उदाहरण के लिए, जहां '#' वर्णों से भरा नहीं जाता है और '_' वर्णों को भरने के लिए प्रतिनिधित्व करता है)

`

###_####_#
____####_#
_##_#_____
_##_#_##_#
______####
#_###_####
#_##______
#_###_##_#
_____###_#
#_######_#
##_______#    

`

  1. एक इनपुट शब्दावली (शब्द सूची / शब्दकोश) जिसमें से उम्मीदवार शब्द चुने जाएंगे (जैसे दिखाए गए एक प्रकार)।

    a abandon ability able abortion about above abroad absence absolute absolutely ...

अब सीएसपी को परिभाषित किया गया है और निम्नानुसार हल किया जा सकता है:

  1. चर को इनपुट के रूप में प्रदान किए गए शब्दों (शब्दावली) की सूची से मान (यानी, उनके डोमेन) परिभाषित किए गए हैं।
  2. प्रत्येक चर को 3 टपल द्वारा दर्शाया जाता है: (ग्रिड_कोर्डिनेट, डायरेक्शन, लेंथ) जहां निर्देशांक संबंधित शब्द की शुरुआत का प्रतिनिधित्व करता है, दिशा क्षैतिज या लंबवत हो सकती है और लंबाई को उस शब्द की लंबाई के रूप में परिभाषित किया जाता है जो चर होगा को सौंपना।
  3. बाधाएं प्रदान किए गए संरचना इनपुट द्वारा परिभाषित की जाती हैं: उदाहरण के लिए, यदि एक क्षैतिज और ऊर्ध्वाधर चर में एक सामान्य चरित्र होता है, तो यह ओवरलैप (आर्क) बाधा के रूप में प्रतिनिधित्व करेगा।
  4. अब, डोमेन को कम करने के लिए नोड संगति और AC3 चाप संगति एल्गोरिदम का उपयोग किया जा सकता है।
  5. फिर MRP (न्यूनतम शेष मूल्य), डिग्री आदि के साथ CSP के लिए एक समाधान (यदि कोई मौजूद है) प्राप्त करने के लिए बैकग्राउंडिंग का उपयोग किया जा सकता है, तो अगली वीसी के लिए बिना लाइसेंस वाले चर का चयन करने के लिए heuristics का उपयोग किया जा सकता है और LCV (कम से कम विवश मान) जैसे डोमेन के लिए उपयोग किया जा सकता है- आदेश, खोज एल्गोरिथ्म को तेज करने के लिए।

निम्नलिखित CSP हल एल्गोरिथ्म के कार्यान्वयन का उपयोग करके प्राप्त किया गया आउटपुट दिखाता है:

`
███S████D█
MUCH████E█
E██A█AGENT
S██R█N██Y█
SUPPLY████
█N███O████
█I██INSIDE
█Q███E██A█
SUGAR███N█
█E██████C█
██OFFENSE█

`

निम्नलिखित एनीमेशन पीछे के चरणों को दर्शाता है:

यहाँ छवि विवरण दर्ज करें

यहाँ बंगला (बंगाली) भाषा शब्द-सूची के साथ एक और है:

यहाँ छवि विवरण दर्ज करें


एक बहुत दिलचस्प स्पष्टीकरण के लिए +1। हालाँकि, मैं जिस समस्या को हल करने की कोशिश कर रहा था उसका संदर्भ यह था कि शब्दों का एक छोटा सा समूह था जिसका सभी को उपयोग करना चाहिए, और मैं एक लेआउट के साथ शुरू करने और शब्दों को खोजने के बजाय क्रॉसवर्ड के लिए एक इष्टतम लेआउट खोजने की कोशिश कर रहा था। जो फिट हो।
nickf

1

jQuery के क्रॉसवर्ड पहेली जेनरेटर और गेम

मैंने इस समस्या का एक जावास्क्रिप्ट / jQuery समाधान कोडित किया है:

नमूना डेमो: http://www.earthfluent.com/crossword-puzzle-demo.html

सोर्स कोड: https://github.com/HoldOffHunger/jquery-crossword-puzzle-generator

मैं इस्तेमाल किया एल्गोरिथ्म का इरादा:

  1. ग्रिड में अनुपयोगी वर्गों की संख्या को यथासंभव कम से कम करें।
  2. संभव के रूप में कई अंतर-मिश्रित शब्द हैं।
  3. बेहद तेज समय में गणना।

एक उत्पन्न क्रॉसवर्ड पहेली का प्रदर्शन।

मैं उपयोग किए गए एल्गोरिदम का वर्णन करूंगा:

  1. उन शब्दों को एक साथ समूहित करें जो एक आम पत्र साझा करते हैं।

  2. इन समूहों से, एक नई डेटा संरचना ("शब्द ब्लॉक") के सेट का निर्माण करते हैं, जो एक प्राथमिक शब्द है (जो सभी अन्य शब्दों से चलता है) और फिर अन्य शब्द (जो प्राथमिक शब्द के माध्यम से चलते हैं)।

  3. क्रॉसवर्ड पहेली के शीर्ष-बाएँ स्थिति में इन शब्द ब्लॉकों में से सबसे पहले क्रॉसवर्ड पहेली को शुरू करें।

  4. शेष शब्द ब्लॉक के लिए, क्रॉसवर्ड पहेली के दाईं ओर सबसे नीचे की ओर से शुरू करते हुए, ऊपर की ओर और बाईं ओर आगे बढ़ें, जब तक कि भरने के लिए अधिक उपलब्ध स्लॉट न हों। यदि बाईं ओर से अधिक खाली स्तंभ हैं, तो ऊपर की ओर बढ़ें, और इसके विपरीत।


@holdoffhunger क्या आपके पास क्रॉसवर्ड को दिखाने के लिए कोई विधि है? अक्षरों में भरे बॉक्स?
जॉन ग्लेज़र

@Jon Glazer: आमतौर पर, आप क्रॉसवर्ड कीज को फंक्शन में भेजते हैं, लेकिन आप क्रॉसवर्ड को 2d-array of chars के रूप में लॉग इन कर सकते हैं var crosswords = generateCrosswordBlockSources(puzzlewords);। बस कंसोल इस मान को लॉग इन करें। मत भूलो, गेम में एक "चीट-मोड" है, जहां आप तुरंत "रिवील आंसर" पर क्लिक कर सकते हैं, ताकि तुरंत मूल्य मिल सके।
होल्डऑफहुंगर

यह "नीचे" बक्से के साथ स्थानों में शब्द "भर में" और इसके विपरीत के साथ पहेली उत्पन्न करता है। मानक क्रॉसवर्ड पहेलियाँ इस तरह से काम नहीं करती हैं, हालांकि यह घनत्व को अधिकतम करती है।
बींजोर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.