2013-04-23 9 views
14

एचटीएमएलजावास्क्रिप्ट भूलभुलैया सॉल्वर एल्गोरिथ्म

<div id="labirinth"> 
    <form style="text-align:center" name="forma1" autocomplete="on"> 
     <table style="margin:0 auto;"> 
      <tr> 
       <td style="float:right;">Height:</td> 
       <td><input type="text" id="height" name="height" autofocus="autofocus" maxlength="2" size="6" /></td> 
      </tr> 
      <tr> 
       <td style="float:right;">Width:</td> 
       <td><input type="text" id="width" name="width" maxlength="2" size="6" /></td> 
      </tr> 
     </table> 
    </form> 
    <input type="button" alt="submit" onClick="datas();" value="New" style="margin-top:10px;" /> 
</div> 
<pre id="out"></pre> 

जावास्क्रिप्ट

function datas() { 

    var height = parseInt(document.getElementById("height").value); 
    var width = parseInt(document.getElementById("width").value); 

    document.getElementById('out').innerHTML = display(maze(height,width)); 
} 

function maze(x,y) { 
    var n=x*y-1; 
    if (n<0) {alert("Bad numbers!");return;} 
    var horiz=[]; 
     for (var j= 0; j<x+1; j++) horiz[j]= []; 
    var verti=[]; 
     for (var j= 0; j<y+1; j++) verti[j]= []; 

    var here= [Math.floor(Math.random()*x), Math.floor(Math.random()*y)]; 
    var path= [here]; 
    var unvisited= []; 
    for (var j= 0; j<x+2; j++) { 
     unvisited[j]= []; 
     for (var k= 0; k<y+1; k++) 
      unvisited[j].push(j>0 && j<x+1 && k>0 && (j != here[0]+1 || k != here[1]+1)); 
    } 
    while (0<n) { 
     var potential= [[here[0]+1, here[1]], [here[0],here[1]+1], 
      [here[0]-1, here[1]], [here[0],here[1]-1]]; 
     var neighbors= []; 
     for (var j= 0; j < 4; j++) 
      if (unvisited[potential[j][0]+1][potential[j][1]+1]) 
       neighbors.push(potential[j]); 
     if (neighbors.length) { 
      n= n-1; 
      next= neighbors[Math.floor(Math.random()*neighbors.length)]; 
      unvisited[next[0]+1][next[1]+1]= false; 
      if (next[0] == here[0]) 
       horiz[next[0]][(next[1]+here[1]-1)/2]= true; 
      else 
       verti[(next[0]+here[0]-1)/2][next[1]]= true; 
      path.push(here= next); 
     } else 
      here= path.pop(); 
    } 
    return ({x: x, y: y, horiz: horiz, verti: verti}); 
} 

function display(m) { 
    var text= []; 
    for (var j= 0; j<m.x*2+1; j++) { 
     var line= []; 
     if (0 == j%2) 
      for (var k=0; k<m.y*4+1; k++) 
       if (0 == k%4) 
        line[k]= 'X'; 
       else 
        if (j>0 && m.verti[j/2-1][Math.floor(k/4)]) 
         line[k]= ' '; 
        else 
         line[k]= 'X'; 
     else 
      for (var k=0; k<m.y*4+1; k++) 
       if (0 == k%4) 
        if (k>0 && m.horiz[(j-1)/2][k/4-1]) 
         line[k]= ' '; 
        else 
         line[k]= 'X'; 
       else 
        line[k]= ' '; 
     if (0 == j) line[1]=line[3]=' ',line[2]= '1'; 
     if (m.x*2-1 == j) line[4*m.y]= '2'; 
     text.push(line.join('')+'\r\n'); 

    } 
    return text.join(''); 
} 

मैं HTML तालिका कोशिकाओं का उपयोग किए बिना जावास्क्रिप्ट में पूरी तरह से काम कर रहा भूलभुलैया जनरेटर बनाने के लिए कोशिश कर रहा हूँ। अब मुझे इस भूलभुलैया के लिए सृजन सॉल्वर के साथ समस्याएं हैं।

प्रश्न: मुझे अपने कोड के लिए उपयोग करने के लिए किस भूलभुलैया एल्गोरिदम की आवश्यकता है? मुझे किसके साथ शुरू करना चाहिए? मुझे पूरे एल्गोरिदम की आवश्यकता नहीं है - मुझे सलाह है कि इस भूलभुलैया जनरेटर में भूलभुलैया हल करने के लिए यह संभव है या नहीं।

JSbin - http://jsbin.com/uwoyon/1

+2

आप एक जे एस बेला में इस कर सकते हैं तो हम देख सकते हैं कि यहाँ हो रहा है? – mpen

+1

किया गया, http://jsbin.com/uwoyon/1 –

+1

जेएस फिडल साइट jsfiddle को संदर्भित करता है :-P – Neal

उत्तर

5

एक solver कि mazes आप डिज्कस्ट्रा एल्गोरिथ्म होगा पैदा कर रहे हैं के लिए काम करना चाहिए के लिए मेरे सिफारिश। हालांकि मुझे यकीन नहीं है कि क्षैतिज और ऊर्ध्वाधर पैरामीटर भूलभुलैया संरचना को कैसे परिभाषित करते हैं, डिजस्ट्रा का एल्गोरिदम '1' के बगल में सेल से शुरू करके और वहां से बाहर निकलने से आपकी स्थिति में काम करेगा।

जिस तरह से यह चल रहा है वह प्रत्येक सेल को इसके और प्रारंभिक सेल के बीच कोशिकाओं की संख्या के साथ लेबल करना है। एक 3x3 के लिए भूलभुलैया प्रथम कक्ष होगा:

x 1 xxxxxxxxx 
x 1   x 
x xxxxxxxxx 
x   x 
x xxxxxxxxx 
x   2 
xxxxxxxxxxxxx 

एक लेबल सेल की जांच से कार्य करता है, तो वहाँ एक खाली आसन्न सेल (एक एक दीवार द्वारा अवरुद्ध नहीं) है, द्वारा 1. दोहराएँ लिए इस प्रक्रिया को सेल मूल्य को बढ़ा सभी रिक्त कक्षों:

x 1 xxxxxxxxx 
x 1 2 3 x 
x xxxxxxxxx 
x 2 3 4 x 
x xxxxxxxxx 
x 3 4 5 2 
xxxxxxxxxxxxx 

अब कोशिका अंत के निकट से पीछे की ओर काम करते हैं '2'। इससे पता चलता है कि समाधान में 5 चरणों की पथ है, इसलिए 5 से शुरू करें, आसन्न 4, फिर 3, आदि को वापस देखें 1.

नोट: मैं कोशिकाओं को लेबल करने के लिए कतारों का उपयोग करके एक पुनरावर्ती समाधान की अनुशंसा करता हूं :

1- पहले सेल को '1' के साथ लेबल करें और इसे कतार में रखें।

2- कतार से सेल लें: - जांचें कि क्या एक कानूनी पड़ोसी (जो दीवार से अवरुद्ध नहीं हैं) अनलॉक है। - यदि पड़ोसी सेल को अनलॉक किया गया है, तो उसे वर्तमान सेल + 1 के साथ लेबल करें। - कतार में पड़ोसी सेल जोड़ें। - सभी 4 संभावित पड़ोसियों के लिए दोहराएं

3- चरण 1 और 2 दोहराएं जब तक कि कोई और अनलॉक कोशिकाएं न हों।

संपादित: यहाँ एक solver मैं क्या सुझाव दिया प्रयोग करने के लिए fiddle है, यह प्रश्न में भूलभुलैया जनरेटर से संबंधित नहीं है इसलिए जब तक पूछा, मैं इसे कैसे संचालित के बारे में विस्तार में नहीं जाना होगा (यह एक सा मोटा, लेकिन इसका कार्यान्वयन पालन करने के लिए काफी आसान होना चाहिए)।

+0

शानदार जवाब। बकाया एक कार्यान्वयन के लिए था, लेकिन मुझे इस सलाह का उपयोग करके बहुत दूर मिल गया है, इसलिए यदि कोई और समाप्ति से पहले कोई भी झटके नहीं देता है तो मैं आपको बक्षीस दूंगा। अनेक अनेक धन्यवाद। – elzi

+0

@elzi मैं अपने सिर को विस्तृत तरीके से नहीं प्राप्त कर सकता था जिसमें horzi और verti पैरामीटर भूलभुलैया संरचना को परिभाषित करते हैं, अन्यथा मैं एक कार्यान्वयन प्रदान करता। यदि दिलचस्पी है तो भी मैं कर सकता हूं, हालांकि भूलभुलैया संरचना को 2 डी सरणी में परिभाषित किया जाएगा। – Ayb4btu

+0

मैं ईमानदारी से किसी भी जावास्क्रिप्ट भूलभुलैया हल उदाहरण ले जाएगा। इस भूलभुलैया जनरेटर के लिए विशेष नहीं होना चाहिए (जिसमें से मुझे विशेष रूप से पसंद नहीं है - कैनवास पसंद करते हैं)। या तो मेरा google-fu भयानक है या वहां पूरा उदाहरण नहीं हो सकते हैं। – elzi

0

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

आप कैसे मैं GitHub पर मेरी उलझन एल्गोरिदम में हल देख सकते हैं:

https://github.com/mdchaney/jsmaze

आप jsmaze2.html समारोह "find_depth" को देखें, तो वास्तव में एक solver है।

jsmaze4.html बहुत अधिक जटिल है लेकिन यह वास्तव में रिकर्सिव एल्गोरिदम के साथ मैज़ बनाने के दौरान समाधान बनाता है। जब यह इमारत के दौरान एक सेल "प्रवेश" होता है तो ट्रैक को ट्रैक करके यह दीवार को खारिज कर दिया जाता है। चूंकि अन्य एल्गोरिदम भी हैं, मैंने "find_depth" भी शामिल किया है जो किसी भी भूलभुलैया के लिए प्रवेश दीवार सेट करता है।

यह शुरू करने के लिए पर्याप्त है।

0

गैर पुनरावर्ती तरीका आपके लिए भूलभुलैया को हल करेगा। रिकर्सन (बैकट्रैकिंग अलगो) के साथ, आप अपनी किस्मत पर सवारी कर सकते हैं।

इस दस्तावेज़ को देखें: - इस सवाल सप्ताह के अंत तक खुला होगा http://cs.stanford.edu/people/eroberts/courses/cs106b/chapters/07-backtracking-algorithms.pdf

हैं। मैं एक कोडित उत्तर पोस्ट करूंगा।

धन्यवाद

संबंधित मुद्दे