我正在尝试使用php制作一个wordsearch游戏。首先,我将创建表格/网格,然后用随机字母填充表格,然后我将随机字母替换为单词的字母,以及确定单词的方向,水平,垂直或DIAGONAL。问题是,单词的字母相互交叉,这搞砸了表格。问题是,
我对他们保持相互交叉的字母有疑问。 任何的想法?
$row = 5;
$col = 5;
$characters = range('a','z');
$max = count($characters) - 1;
$rc = array();
for ($r=1;$r<=$row;$r++)
{
for ($c=1;$c<=$col;$c++)
{
$rc['r'.$r.'c'.$c] = $characters[mt_rand(0,$max)];
$fill['r'.$r.'c'.$c] = '';
}
}
$directions = array('H', 'V', 'D');
$wrdList =array('four', 'data', 'howl');
foreach ($wrdList as $wrd)
{
$wrdLen = strlen($wrd);
$dir = $directions[mt_rand(0,2)];
if ($dir =="H" or $dir=="D" )
{
$limitRow = $row - $wrdLen+1;
$limitCol = $col - $wrdLen+1;
$startPointRow = 1;
$startPointCol = 1;
}
elseif ($dir=="V")
{
$limitRow = $row - $wrdLen + 1;
$limitCol = $col;
$startPointRow = 1;
$startPointCol = 1;
}
$temprow = mt_rand($startPointRow,$limitRow);
$tempcol = mt_rand($startPointCol,$limitCol);
while($wrdLen >0)
{
$thisChar= substr($wrd,0,1);
$wrd = substr($wrd,1);
$wrdLen--;
$x = 'r'.$temprow.'c'.$tempcol;
$rc[$x] = $thisChar;
$fill[$x] = '#2952f8';
if($dir=="D")
{
$tempcol++;
$temprow++;
}
elseif($dir=="V")
{
$temprow++;
}
elseif($dir=="H")
{
$tempcol++;
}
}
}
#--Display the random letters and the words
echo '<table style="border:1px solid #000">';
for ($r=1;$r<=$row;$r++)
{
echo '<tr style="border:1px solid #000">';
for ($c=1;$c<=$col;$c++)
{
$thisChar=$rc['r'.$r.'c'.$c];
$fills = $fill['r'.$r.'c'.$c];
echo '<td style="border:1px solid #000; background-color: '.$fills.'">';
echo $thisChar;
echo '</td>';
}
echo '</tr>';
}
echo '</table>';
?>
答案 0 :(得分:0)
你正在倒退。首先输入你想要的单词,然后输入随机字母。
在输入每个连续的单词之前,选择该单词的随机路径,然后沿着该路径检查是否存在任何不匹配的字母。 (例如,如果'字母'在一个字母'a'的地方穿过'graph'这个词,那就没关系;否则,找到'alphabet'的不同位置)。最后,在所有单词都到位后,仔细检查整个内容,并在没有字母的位置放置随机字母。或者,如果找不到所有单词的位置,请重新开始。
编辑:
如何在特定地点找到字母。好的。所以,看看你的代码,你在做一些不合逻辑的事情:
$rc['r'.$r.'c'.$c] = $characters[mt_rand(0,$max)];
您正在创建一个基本上是两个键的乘积的一维数组。相反,你想做一个二维数组。这完全有道理,因为a)你有两个键,b)单词搜索有两个维度。
$rc[$r][$c] = $characters[mt_rand(0,$max)];
所以,让我们从一开始就重新安排一切。请注意,我已经重写了一些事情来开始你的行/列计数为0而不是1,因为这是数组的编程约定,我不会试图弯曲我的大脑围绕从1算起。
$wrdList =array('four', 'banana', 'howl');
$row = 5; //six rows counting from 0
$col = 5; //six columns counting from 0
$rc = array(); //our tableau array
$directions = array('H', 'V', 'D');
foreach ($wrdList as $wrd)
{
$found = false; // by default, no spot has been found
$tries = $row*$col; // we will try a reasonable number of times to find a spot
while(!$found && $tries > 0) {
$wrdLen = strlen($wrd);
$dir = $directions[mt_rand(0,2)];
if ($dir =="H")
{
$limitRow = $row;
$limitCol = $col - ($wrdLen - 1);
}
elseif($dir=="D")
{
$limitRow = $row - ($wrdLen - 1);
$limitCol = $col - ($wrdLen - 1);
}
elseif ($dir=="V")
{
$limitRow = $row - ($wrdLen - 1);
$limitCol = $col;
}
$temprow = mt_rand(0,$limitRow);
$tempcol = mt_rand(0,$limitCol);
//this is my temporary placement array
$placement = array();
//let's use for loop so we can capitalize on having numeric keys
$r = $temprow;
$c = $tempcol;
for($w = 0; $w < $wrdLen; $w++) {
$thisChar = $wrd{$w};
//find array keys
if($dir == 'V' || $dir == 'D') {
$r = $temprow + $w;
}
if($dir == 'H' || $dir == 'D') {
$c = $tempcol + $w;
}
//look at the current tableau
if(isset($rc[$r][$c])) { //the intended spot has a letter
if($rc[$r][$c] == $thisChar) { //the intended spot's letter is the same
$placement[$r][$c] = $thisChar;
if($w == $wrdLen-1) { // this is the last letter
$found = true; // we have found a path
}
} else {
break; //this path doesn't work
}
} else {
$placement[$r][$c] = $thisChar;
if($w == $wrdLen-1) { // this is the last letter
$found = true; // we have found a path
}
}
}
if($found) {
//put the letters out of the temporary array and into the tableau
foreach($placement as $r=>$set) {
foreach($set as $c=>$letter) {
$rc[$r][$c] = $letter;
}
}
}
$tries--;
}
//handle the error where no spot was found for the word
if(!$found) {
//your error handling here
}
}
//random fillers
$characters = range('a','z');
$max = count($characters) - 1;
for($r = 0; $r <= $row; $r++) {
for($c = 0; $c <= $col; $c++) {
if(!isset($rc[$r][$c])) {
$rc[$r][$c] = $characters[mt_rand(0,$max)];
}
}
}