2012-09-21 3 views
0

J'ai écrit un programme qui crée un puzzle basé sur les entrées de l'utilisateur. Il existe un formulaire html qui accepte les mots de l'utilisateur et les publie dans le programme php. Ensuite, le programme PHP crée le puzzle et l'imprime.Erreur PHP: Offset non défini: 10

Une démo est en cours here. Vous pouvez taper vos propres mots.

Cela semble bon, mais quand je l'exécute dans mon serveur local avec l'invite d'erreur php activée, je vois l'erreur msg disant Undefined offset: 10 at line 147 and 148. L'erreur est générée à partir de la ligne de code PHP à partir de if ($board[$curr_row][$curr_col] == '.' ... Vous pouvez utiliser Ctrl + F pour trouver le code. Je ne comprends pas comment pourrais-je obtenir 10 $curr_col ou $curr_row puisque la boucle doit arrêter après avoir atteint 9.

S'il vous plaît me aider à comprendre comment la course en boucle pourrait après avoir atteint 10, merci beaucoup!

La version compressée du programme est here.

Voici le code du 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

La première chose que vous devez faire est de trouver quelle variable atteint 10. Ne pas deviner. Par exemple: 'if (! Isset ($ board [$ curr_row] [$ curr_col])) {echo $ curr_row; echo $ curr_row;} ' – Tchoupi

Répondre

2

Je ne pense pas que le fragment de code suivant est droit.

strlen($single_word - 1) 

situé dans les lignes:

$curr_col = rand(0, ($boardData["width"] - (strlen($single_word - 1)) - 1)); 

et

$curr_row = rand(0, ($boardData["height"] - (strlen($single_word - 1)) - 1)); 

Il convertit le mot en entier. Soustrayez-en un de ce nombre. Puis convertissez-le en une chaîne et prenez la longueur. Donc, vous avez une valeur de déchets pour la longueur.

+0

Vous avez raison. J'ai fixé cela à '$ curr_col = rand (0, ($ boardData [" largeur "] - (strlen ($ single_word) -1) - 1));', ce qui était ce que je voulais dire à l'origine. Maintenant, il n'y a pas d'erreurs! Merci! :RÉ – fall