2012-07-08 9 views
9

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

अस्वीकरण: यहां कुछ और "स्टैक ओवरफ्लो" पर कुछ "अंतर खोजें" कोड मिल सकता है, लेकिन मैं जिस कार्यक्षमता की तलाश में था, वह कुछ नहीं मिला।

मैं इन terminoligy पर बाद में उपयोग करेंगे:
'userguess': एक शब्द है कि उपयोगकर्ता द्वारा दर्ज किया जाएगा
'समाधान': गुप्त शब्द अनुमान लगाया जाना चाहिए ।

मैं खेल है जहाँ अनुमान लगा

एक शब्द बनाने के लिए आवश्यक:

  • उपयोगकर्ता एक शब्द में प्रवेश करती है (मैं जावास्क्रिप्ट/jQuery के माध्यम से सुनिश्चित करेंगे कि में प्रवेश शब्द पर शब्द के रूप में अक्षरों की संख्या समान है)।

  • एक PHP समारोह फिर 'userguess' और प्रकाश डाला (हरे रंग में) कि शब्द में पत्र जो सही स्थान पर हैं, और पर प्रकाश डाला (लाल रंग में) पत्र है कि सही जगह में अभी तक नहीं कर रहे हैं की जाँच करता है , लेकिन शब्द में कहीं और दिखाएं।
    अक्षरों में दिखाई देने वाले अक्षरों को काला छोड़ दिया गया है।



ख़तरा परिदृश्य: - मान लीजिए कि 'समाधान' 'aabbc' है और उपयोगकर्ता 'abaac'
अनुमान लगा लेता उपरोक्त परिदृश्य इस में परिणाम होगा में करते हैं: (हरा) एक (/ हरा) (लाल) (/ लाल) (लाल) एक (/ लाल) (काला) एक (/ काला) (हरा) (/ हरी)
सूचना कैसे पिछले "एक" काला कारण 'userguess' है 3 एक है लेकिन 'समाधान' केवल 2

क्या मैं अब तक

कोड है कम या ज्यादा काम कर रहा है, लेकिन मुझे लगता है कि यह 10 गुना अधिक दुबला और मतलब हो सकता है।
मैं 2 नए Arrays (समाधान के लिए एक और उपयोगकर्ता के लिए एक) भर रहा हूं क्योंकि मैं गड़बड़ी से ऊपर (ऊपर देखें) को रोकने के लिए साथ जाता हूं।

function checkWord($toCheck) { 
     global $solution;  // $solution word is defined outside the scope of this function 
     $goodpos = array(); // array that saves the indexes of all the right letters in the RIGHT position 
     $badpos = array(); // array that saves the indexes of all the right letters in the WRONG position 
     $newToCheck = array(); // array that changes overtime to help us with the Pitfall (see above) 
     $newSolution = array();// array that changes overtime to help us with the Pitfall (see above) 

     // check for all the right letters in the RIGHT position in entire string first 
     for ($i = 0, $j = strlen($toCheck); $i < $j; $i++) { 
      if ($toCheck[$i] == $solution[$i]) { 
       $goodpos[] = $i; 
       $newSolution[$i] = "*"; // RIGHT letters in RIGHT position are 'deleted' from solution 
      } else { 
       $newToCheck[] = $toCheck[$i]; 
       $newSolution[$i] = $solution[$i]; 
      } 
     } 

     // go over the NEW word to check for letters that are not in the right position but show up elsewhere in the word 
     for ($i = 0, $j = count($newSolution); $i <= $j; $i++) { 
      if (!(in_array($newToCheck[$i], $newSolution))) { 
       $badpos[] = $i; 
       $newSolution[$i] = "*"; 
      } 
     } 

     // use the two helper arrays above 'goodpos' and 'badpos' to color the characters 
     for ($i = 0, $j = strlen($toCheck), $k = 0; $i < $j; $i++) { 
      if (in_array($i,$goodpos)) { 
       $colored .= "<span class='green'>"; 
       $colored .= $toCheck[$i]; 
       $colored .= "</span>"; 
      } else if (in_array($i,$badpos)) { 
       $colored .= "<span class='red'>"; 
       $colored .= $toCheck[$i]; 
       $colored .= "</span>"; 
      } else { 
       $colored .= $toCheck[$i]; 
      } 
     } 

     // output to user 
     $output = '<div id="feedbackHash">'; 
     $output .= '<h2>Solution was : &nbsp;' . $solution . '</h2>'; 
     $output .= '<h2>Color corrected: ' . $colored . '</h2>'; 
     $output .= 'Correct letters in the right position : ' . count($goodpos) . '<br>'; 
     $output .= 'Correct letters in the wrong position : ' . count($badpos) . '<br>'; 
     $output .= '</div>'; 

     return $output; 
    } // checkWord 
+0

"// दाएं स्थिति में सभी सही अक्षरों की जांच करें" क्या यह एक === जांच जैसा नहीं है? यदि अधिकांश पेपर इसे सही तरीके से प्राप्त करेंगे तो आपको "असफल पहले" के विपरीत करने की आवश्यकता है यानी जांच करें, पहले पास करें, वापसी करें। – Cups

+0

+1, मैंने कभी नवागंतुक को इतना विस्तृत प्रश्न नहीं देखा है! :) – SuperSaiyan

+0

+1 एक साफ सवाल के लिए +1 ... – Red

उत्तर

2

अच्छा सवाल। मैं शायद यह आपके लिए थोड़ा अलग करूँगा :) (मुझे लगता है कि आप यही उम्मीद कर रहे थे!)

आप मेरा पूरा समाधान फ़ंक्शन यहां देख सकते हैं http://ideone.com/8ojAG - लेकिन मैं इसे चरण-दर-चरण भी नीचे तोड़ने जा रहा हूं।

सबसे पहले, कृपया global का उपयोग करके देखें और टालें।

function checkWord($toCheck, $solution) {

आप में समाधान गुजरती हैं और बाद में संभावित ख़राबियों से बच सकते हैं: कोई कारण नहीं है आप के रूप में अपने कार्य को परिभाषित नहीं कर सकता है।

मैं दोनों उपयोगकर्ता अनुमान है, और विन्यास में, समाधान बंटवारे से शुरू करना चाहते हैं, और एक अन्य सरणी में मेरी उत्पादन स्टोर करने के लिए किया है।

$toCheck = str_split($toCheck, 1); 
$solution = str_split($solution, 1); 
$out = array(); 

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

तो मैचों की जांच करने के लिए।

foreach ($toCheck as $pos => $char) { 
    if ($char == $solution[$pos]) { 
     $out[$pos] = "<span class=\"green\">$char</span>"; 
     unset($toCheck[$pos], $solution[$pos]); 
    } 
} 
अपने उदाहरण अनुमान/समाधान के लिए

तो, $out अब एक हरे रंग होता है 'एक' स्थिति 0 और स्थिति 4. दोनों अनुमान और समाधान अब इन सूचकांक होते हैं पर एक हरे रंग की सी, और कम से नहीं होगा फिर से जांचें।

मौजूद अक्षरों की जांच करने के लिए एक समान प्रक्रिया, लेकिन गलत जगह पर।

foreach ($toCheck as $pos => $char) { 
    if (false !== $solPos = array_search($char, $solution)) { 
     $out[$pos] = "<span class=\"red\">$char</span>"; 
     unset($toCheck[$pos], $solution[$solPos]); 
    } 
} 

इस मामले में हम समाधान में अनुमानित पत्र की खोज कर रहे हैं, और इसे प्राप्त करने पर इसे हटा रहे हैं। हमें घटनाओं की संख्या गिनने की आवश्यकता नहीं है क्योंकि जब हम जाते हैं तो पत्र हटा दिए जाते हैं।

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

$out += $toCheck;

लगभग वहां। $out में हमें जो कुछ भी चाहिए, वह है, लेकिन यह सही क्रम में नहीं है। हालांकि सूचकांक संख्यात्मक हैं, फिर भी उन्हें आदेश नहीं दिया जाता है। हम साथ खत्म:

ksort($out); 
return implode($out); 

इस से परिणाम है:

"<span class="green">a</span><span class="red">b</span><span class="red">a</span>a<span class="green">c</span>"

+0

इसे लिखने में समय लगाने के लिए बहुत बहुत धन्यवाद। जैसे मैंने कहा: कट्टर एल्गोरिदम की बात आती है जब मेरा दिमाग केवल मध्यम होता है। मैं एक डेवलपर की तुलना में एक वेब डिज़ाइनर हूं। मैं आपको धन्यवाद नहीं दे सकता 1) मुझे कोड पर अपनी दृष्टि प्रदान करना और 2) विस्तार से व्याख्या करने के लिए अतिरिक्त समय लेना कि आपने इसे कैसे बनाया है। बस कामना की है कि मैं अपने स्वीकृत उत्तर के रूप में 2 उत्तरों का चयन कर सकता हूं। – Wayfarer

+0

@belgianwolfie मैं कुछ आंतरिक सरणी लाइब्रेरी फ़ंक्शंस के आधार पर आपके लिए एक और कॉम्पैक्ट लिखने की कोशिश कर रहा था। वे उपयोगी कार्य हैं और आप अपनी भविष्य की परियोजनाओं में किसी भी तरह से उपयोग करने में सक्षम हो सकते हैं: ['array_intersect'] (http://php.net/manual/en/function.array-intersect.php) और [' array_diff'] (http://php.net/manual/en/function.array-diff.php) (उनके पास कुंजी को संरक्षित करने के लिए '_assoc' संस्करण भी हैं) - आपके प्रश्न में प्रयास करने के लिए धन्यवाद, बहुत से लोग SO को किसी स्थान के रूप में देखते हैं इन दिनों अपने लिए उनके काम करने के लिए अन्य लोगों को प्राप्त करने के लिए। अपने भविष्य के प्रश्नों और उत्तरों पर शुभकामनाएँ! – Leigh

1

यहाँ इस कोशिश, See In Action

उदाहरण आउटपुट: enter image description here

<?php 
echo checkWord('aabbc','abaac').PHP_EOL; 
echo checkWord('funday','sunday').PHP_EOL; 
echo checkWord('flipper','ripple').PHP_EOL; 
echo checkWord('monkey','kenney').PHP_EOL; 

function checkWord($guess, $solution){ 
    $arr1 = str_split($solution); 
    $arr2 = str_split($guess); 
    $arr1_c = array_count_values($arr1); 
    $arr2_c = array_count_values($arr2); 
    $out = ''; 
    foreach($arr2 as $key=>$value){ 
     $arr1_c[$value]=(isset($arr1_c[$value])?$arr1_c[$value]-1:0); 
     $arr2_c[$value]=(isset($arr2_c[$value])?$arr2_c[$value]-1:0); 

     if(isset($arr2[$key]) && isset($arr1[$key]) && $arr1[$key] == $arr2[$key]){ 
      $out .='<span style="color:green;">'.$arr2[$key].'</span>'; 
     }elseif(in_array($value,$arr1) && $arr2_c[$value] >= 0 && $arr1_c[$value] >= 0){ 
      $out .='<span style="color:red;">'.$arr2[$key].'</span>'; 
     }else{ 
      $out .='<span style="color:black;">'.$arr2[$key].'</span>'; 
     } 
    } 
    return $out; 
} 
?> 
+0

'foreet ($ arr2 [$ key]) के अंदर' foreach ($ arr2 $ key => $ value) के रूप में {'जहां आप सरणी या कुंजी नहीं बदलते हैं) करने के लिए वास्तव में आवश्यक नहीं है। प्रश्नकर्ता लेखक का मानना ​​है कि यह सुनिश्चित करने के लिए कहीं और जगह है कि अनुमान और समाधान एक ही लंबाई – Leigh

+0

है, यह चोट नहीं पहुंचाता है; पी, 'जारीकर्ता ($ arr1 [ $ कुंजी]) 'अनुमान के रूप में शब्द –

+0

हो सकता है जो एक सुंदरता है। अभी भी आंतरिक कामकाज के चारों ओर अपने मध्यस्थ मस्तिष्क को लपेटने की कोशिश कर रहा है, भले ही कोड इतना कॉम्पैक्ट है :) आपके समय के लिए बहुत बहुत धन्यवाद। – Wayfarer

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