2012-09-21 101 views
0

我寫了一個程序,根據用戶的輸入創建一個謎題。有一個html表單接受用戶的單詞並將它們發佈到php程序中。然後,PHP程序創建難題並打印它。PHP錯誤:未定義抵消:10

有一個現場演示here。你可以輸入你自己的單詞。

它看起來不錯,但當我運行它在我的本地服務器與PHP錯誤提示打開時,我看到錯誤消息說Undefined offset: 10 at line 147 and 148。該錯誤是從if ($board[$curr_row][$curr_col] == '.'開始的php代碼行生成的...您可以使用Ctrl + F查找代碼。我不明白我怎麼能得到10在$curr_col$curr_row,因爲循環應該停止後,他們達到了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

你需要做的第一件事是找出哪個變量正在達到10.不要猜測。例如:'if(!isset($ board [$ curr_row] [$ curr_col])){echo $ curr_row; echo $ curr_row;}' – Tchoupi

回答

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)); 

將字轉換爲整數。從那個數字中減去一個。然後將其轉換回一個字符串並採取長度。所以你有一個垃圾長度的價值。

+0

你是對的。我將它固定爲'$ curr_col = rand(0,($ boardData [「width」] - (strlen($ single_word)-1) - 1));',這就是我最初的意思。現在沒有錯誤!謝謝! :d – fall