我写了一个基于用户输入创建拼图的程序。有一个html表单接受用户的单词并将它们发布到php程序。然后php程序创建拼图并打印出来。
有一个现场演示here。你可以输入你自己的单词。
它看起来不错但是当我在本地服务器上运行它并启用了php错误提示时,我看到错误消息说Undefined offset: 10 at line 147 and 148
。从if ($board[$curr_row][$curr_col] == '.'
开始的PHP代码行生成错误...您可以使用Ctrl + F查找代码。我不明白如何在$curr_col
或$curr_row
中获得10,因为循环应该在达到9之后停止。
请帮助我了解循环在达到10之后如何运行,非常感谢!
该程序的压缩版本为here。
以下是php的代码:
<html>
<body>
<?php
/* word Find
Generates a word search puzzle based on a word list entered by user.
User can also specify the size of the puzzle and print out
an answer key if desired
*/
//If there is no data from the form, prompt the user to go back
if (!filter_has_var(INPUT_POST, "puzzle_name")) {
print <<<MUL_LINE
<!DOCTYPE html>
<html >
<head>
<title>Oops!</title>
</head>
<body>
<p>This page should not be called directly, please visit
the <a href="./form.html">puzzle form</a> to continue.</p>
</body>
</html>
MUL_LINE;
} else {
$boardData = array("name" => filter_input(INPUT_POST, "puzzle_name"), "width" => filter_input(INPUT_POST, "grid_width"), "height" => filter_input(INPUT_POST, "grid_height"));
if (parseList() == TRUE) {//parse the word list in textarea to an array of words
//keep trying to fill the board untill a valid puzzle is made
do {
clearBoard();
//reset the board
$pass = fillBoard();
} while($pass == FALSE);
printBoard();
//if the board if successfully filled, print the puzzle
}
}//end word list exists if
//parse the word list in textarea to an array of words
function parseList() {
//get word list, creates array of words from it
//or return false if impossible
global $word, $wordList, $boardData;
$wordList = filter_input(INPUT_POST, "wordList");
$itWorked = TRUE;
//convert word list entirely to upper case
$wordList = strtoupper($wordList);
//split word list into array
$word = explode("\n", $wordList);
//an array of words
foreach ($word as $key => $currentWord) {
//trim all the beginning and trailer spaces
$currentWord = rtrim(ltrim($currentWord));
//stop if any words are too long to fit in puzzle
if ((strlen($currentWord) > $boardData["width"]) && (strlen($currentWord) > $boardData["height"])) {
print "$currentWord is too long for puzzle";
$itWorked = FALSE;
}//end if
$word[$key] = $currentWord;
}//end foreach
return $itWorked;
}//end parseList
//reset the board by filling each cell with "."
function clearBoard() {
//initialize board with a . in each cell
global $board, $boardData;
for ($row = 0; $row < $boardData["height"]; $row++) {
for ($col = 0; $col < $boardData["width"]; $col++) {
$board[$row][$col] = ".";
}//end col for loop
}//end row for loop
}//end clearBoard
//fill the board
function fillBoard() {
global $word;
$pass = FALSE;
//control the loop of filling words, false will stop the loop
//control the loop, if all the words are filled, the counter will be as equal to the number
//of elements in array $words, thus the loop stops successfully
$counter = 0;
do {
$pass = fillWord($word[$counter]);
//if a word is filled, $pass is set to true
$counter++;
}
//if a word can't be filled, pass==FALSE and loop stops
//or if all words are through, loop stops
while($pass==TRUE && $counter<count($word));
//return TRUE if all filled successfully, FALSE if not
if ($pass == TRUE && $counter == count($word)) {
return TRUE;
} else {
return FALSE;
}
}
//function used to fill a single word
function fillWord($single_word) {
global $board, $boardData;
//the direction of how the word will be filled, 50% chance to be H, and 50% chance to be V
$dir = (rand(0, 1) == 0 ? "H" : "V");
//H(horizontal) means fill the word from left to right
//V(vertical) means fill the word from up to down
//loop control. if a letter is not filled, $pass is set to false and loop stops
$pass = TRUE;
//loop control. if all letters are filled successfully, loop stops too.
$counter = 0;
//decide the cell to fill the first word. the cell is located at $board[$curr_row][$curr_col]
if ($dir == "H") {//if the word will be fileld from left to right
$curr_row = rand(0, $boardData["height"] - 1);
//pick up a random row of the 10 rows ( rand(0,9) )
$curr_col = rand(0, ($boardData["width"] - ( strlen($single_word - 1)) - 1));
//pick up a random column of fillable columns
//if the word is "banana" and the board's width
//is 10, the starting column can only be rand(0, 4)
} else if ($dir == "V") {//if the word will be fileld from up to down
$curr_row = rand(0, ($boardData["height"] - ( strlen($single_word - 1)) - 1));
$curr_col = rand(0, $boardData["width"] - 1);
} else {
print "invalid direction";
}
//the loop that keeps trying to fill letters of the word
while ($pass && ($counter < strlen($single_word))) {//while the $pass is true AND there are still letters
//to fill, keep the loop going
//the next line and the line after generate the msg "Undefined offset: 10",
//$curr_row and $curr_col should never be 10 because the loop should be stopped
//if the last letter of the word is filled
if ($board[$curr_row][$curr_col] == '.' || //if the cell is not filled, reset fillboard() to "."
$board[$curr_row][$curr_col] == substr($single_word, $counter, 1))//or it has already been filled with the same letter
{
$board[$curr_row][$curr_col] = substr($single_word, $counter, 1);
// write/fill the letter in the cell
$counter++;
if ($dir == "H") {
$curr_col++;
//next column, move to the next right cell
} else if ($dir == "V") {
$curr_row++;
//next row, move to the next lower cell
} else {
print "\nHuge direction error!";
}
} else {
$pass = FALSE;
// failed to fill a letter, stop the loop
}
}
//if all the letters are filled successfully, the single word is filled successfully
//return true, let $fillBoard go filling next single word
if ($pass && ($counter == strlen($single_word))) {
/* for debug purpose
print "<hr />";print "<p>TRUE</p>";print "<hr />";
print $single_word;
print $curr_row . "," . $curr_col . "<br />";
print "<hr />";*/
return TRUE;
} else {
//failed to fill the word, reset the board and start all over again
return FALSE;
}
}//end function fillWord
//print the successful filled puzzle
function printBoard() {
global $board;
print <<<MULLINE
<style type="text/css">
table, td{
border: 1px solid black;
}
</style>
MULLINE;
print '<table >';
foreach ($board as $row) {
print '<tr>';
foreach ($row as $cell) {
print '<td>';
print $cell;
print '</td>';
}
print("<br />");
print '</tr>';
}
print "</table>";
}
?>
</body>
</html>
答案 0 :(得分:2)
我不认为以下代码片段是正确的。
strlen($single_word - 1)
位于以下行:
$curr_col = rand(0, ($boardData["width"] - ( strlen($single_word - 1)) - 1));
和
$curr_row = rand(0, ($boardData["height"] - ( strlen($single_word - 1)) - 1));
它会将单词转换为整数。从该数字中减去一个。然后将其转换回字符串并获取长度。所以你有一个长度的垃圾值。