0

我正在尝试使用 php 制作文字搜索游戏。首先,我将创建表格/网格,然后用随机字母填充表格,然后我将用单词的字母替换随机字母,并确定单词水平、垂直或对角线的方向。问题是,单词的字母相互交叉,这把桌子弄乱了。问题是,

  • 如何设置单词字母不相交的条件
  • 如何判断当前位置是否已经被其他单词字母占据?

我对它们不断相互交叉的单词字母有疑问。任何的想法?

$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>';
?>
4

1 回答 1

0

你倒着做。首先输入你想要的单词,然后输入随机字母。

在输入每个连续的单词之前,为该单词选择随机路径,然后沿着该路径检查是否有任何不匹配的字母。(例如,如果 'alphabet' 与单词 'graph' 在它们都有字母 'a' 的地方交叉,没关系;否则,为 '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)];
        }
    }
}
于 2014-01-21T01:58:14.767 回答