PHP Word猜谜游戏(在正确和错误的位置突出显示字母 - 像主脑一样)

Way*_*rer 9 php

对不起,长标题.
希望它尽可能具有描述性.

免责声明:可以在这里和Stackoverflow上的其他地方找到一些"找到差异"代码,但不是我想要的功能.

我将在稍后使用这些术语:
'userguess':用户
'解决方案'将输入的一个词:需要猜到的秘密词.

我需要创造什么

一个猜字游戏的地方:

  • 用户输入一个单词(我将通过Javascript/jQuery确保输入的单词包含与要猜测的单词相同数量的字母).

  • PHP函数然后检查'userguess'并突出显示(绿色)该单词中位于正确位置的字母,并突出显示(红色)尚未出现在正确位置的字母,但显示在其他位置在这个词中.
    未在"解决方案"中显示的字母为黑色.



陷阱场景: - 假设'解决方案'是 'aabbc'并且用户猜测'abaac'
在上面的场景中,这将导致:(绿色)a(/绿色)(红色)b(/红色)(红色)a(/红色)(黑色)a(/黑色)(绿色)c(/绿色)
请注意最后一个" a "是黑色的,因为'userguess'有3 个,但"解决方案"只有2个

到目前为止我有什么

代码工作或多或少,但我觉得它可以是精简和平均值的10倍.
我正在填写2个新阵列(一个用于解决方案,一个用于userguess),因为我一直在努力防止陷阱(见上文)搞乱.

 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
Run Code Online (Sandbox Code Playgroud)

Lei*_*igh 2

好问题。我的做法可能与你略有不同:)(我想这就是你所希望的!)

您可以在这里找到我的完整解决方案功能http://ideone.com/8ojAG - 但我也会一步一步地分解它。

首先,请尽量避免使用global. 没有理由不能将函数定义为:

function checkWord($toCheck, $solution) {

您可以传递解决方案并避免以后出现潜在的麻烦。

我首先将用户猜测和解决方案分成数组,并使用另一个数组来存储我的输出。

$toCheck = str_split($toCheck, 1);
$solution = str_split($solution, 1);
$out = array();
Run Code Online (Sandbox Code Playgroud)

在该过程的每个阶段,我都会从用户猜测或解决方案中删除已识别为正确或不正确的字符,因此我不需要以任何方式标记它们,并且函数的其余阶段将运行更有效率。

所以要检查匹配。

foreach ($toCheck as $pos => $char) {
    if ($char == $solution[$pos]) {
        $out[$pos] = "<span class=\"green\">$char</span>";
        unset($toCheck[$pos], $solution[$pos]);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,对于您的示例猜测/解决方案,$out现在在位置 0 处包含一个绿色“a”,在位置 4 处包含一个绿色 c。猜测和解决方案都不再具有这些索引,并且不会再次检查。

类似的过程用于检查存在但位置错误的字母。

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

在本例中,我们在解决方案中搜索猜测的字母,如果找到则将其删除。我们不需要计算出现的次数,因为字母会随着我们的移动而被删除。

最后,用户猜测中剩下的唯一字母是解决方案中根本不存在的字母,并且由于我们始终维护编号索引,因此我们可以简单地将剩余字母合并回来。

$out += $toCheck;

差不多了。$out拥有我们需要的一切,但顺序不正确。即使索引是数字,它们也没有排序。我们最终得到:

ksort($out);
return implode($out);
Run Code Online (Sandbox Code Playgroud)

由此得出的结果是:

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