对不起,长标题.
希望它尽可能具有描述性.
免责声明:可以在这里和Stackoverflow上的其他地方找到一些"找到差异"代码,但不是我想要的功能.
我将在稍后使用这些术语:
'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 : ' . $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)
好问题。我的做法可能与你略有不同:)(我想这就是你所希望的!)
您可以在这里找到我的完整解决方案功能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>"
| 归档时间: |
|
| 查看次数: |
1899 次 |
| 最近记录: |