Aqui el codigo, el resultado es una linea de texto que tiene el modelo no resuelto y las palabras y la ubiciacion me parece, la verdad seria de darle seguimiento si vas a implementarlo por que hay cosas que al parecer no funcionan por conexion y esas cosas, como pueden ver el codigo original del generador no es mio, nunca le quito esas cosas, me parece bien asi :)
   Código PHP:
    <?php
/*
Crossing Words for
Codewalkers PHP Coding Contest of July 2002
(http://{$_SERVER['SERVER_NAME']}/php-contest.php)
Author Àngel Fenoy from Arenys de Mar, Barcelona.
*/
set_time_limit($time_limit = 10);
$t1 = time();
mt_srand((double)(microtime()*100000000));
$tamaño = 10;
define('MAXW', 8);
define('MAXW1', MAXW + 1);
define('N20', $tamaño);
define('N19', N20 - 1);
define('N21', N20 + 1);
define('N22', N20 + 2);
define('N2222', N22 * N22);
define('N2221', N2222 - 1);
define('N2200', N2222 - N22);
/*$file = "wordlist.txt";
if (! file_exists($file)) die("File <b>$file</b> inexistent. Matt's fault ;)</body></html>");
if (! is_readable($file)) die("File <b>$file</b> is not readable. Matt's fault ;)(</body></html>");
$arrfile = file($file);*/
include("connect.php");
$query = "SELECT COUNT(*) FROM crucigrama WHERE resuelto != 1";//alistar
        $result = mysql_query($query);
        $existe_cruci = mysql_result($result, 0);
        if($existe_cruci <= 2){
        
$query = "SELECT DISTINCT (palabra) from diccionario  ORDER BY RAND() limit 10";
$result = mysql_query($query);
$i= 0;
while ($row = mysql_fetch_assoc($result)){
    $arrfile[$i] = $row["palabra"];
    $i++;
    }
$lens = array_pad(array(), 21, 0);
foreach($arrfile as $n => $wordn) {
   $lens[strlen($arrfile[$n] = trim($wordn))] ++;
}
$sum = 0;
$base_words = array();
foreach($arrfile as $n => $wordn) {
   if (strlen($t = trim($wordn)) > (MAXW1)) continue;
   $base_words[$n] = $t;
  
}
$base_puzzle = str_repeat('0', N22) . str_repeat('0' . str_repeat('.', N20) . '0', N20) . str_repeat('0', N22);
$best_score = 0;
$best_puzzle = '';
$best_palabras = '';
$the_end = false;
while (! $the_end) {
   
   $magics = array();
   for ($n = 2; $n < N21; $n++) {   
      $a = array();
      for ($r = 2; $r < ($n + 2); $r++) {
         $a[] = $r;
      }
      uasort($a, 'cmp_magic');
      $magics[$n] = $a;
   }
    
   $arr_words = $base_words;
   uasort($arr_words, 'cmp');
  
   $words = ';' . implode(';', $arr_words) . ';';
   
   $puzzle = $base_puzzle;
   
   $row = mt_rand(3, 10);
   $col = mt_rand(3, 10);
   $pos = N22 * $row + $col;
   
   $poss = array();
   
   $palabras = '';
   scan_pos($pos, 'h', true);
   $n_words = 1;
   
   
   while ($s = sizeof($poss)) {
      
      $p = array_shift($poss);
        
      if (scan_pos($p[0], $p[1], false)) {
         $n_words++;
         
      }
      
      if (time() - $t1 > $time_limit - 2) {
         $the_end = true;
         break;
      }
   }
   
   $n_connectors = $n_filleds = 0;
   $puzzle00 = str_replace('.', '0', $puzzle);
   for ($n = 0; $n < N2222; $n++) {
      if ($puzzle00[$n]) {
         if (($puzzle00[$n - 1] or $puzzle00[$n + 1]) and
             ($puzzle00[$n - N22] or $puzzle00[$n + N22])) {
            $n_connectors++;
         } else {
            $n_filleds++;
         }
      }
   }
   
   $score = ($n_words * 5) + ($n_connectors * 3) + $n_filleds;
    
   if ($score > $best_score) {
      
      
      $bests = array('Words' => "$n_words * 5 = " . ($n_words * 5), 
                     'Connectors' => "$n_connectors * 3 = " . ($n_connectors * 3),
                     'Filled in spaces' => $n_filleds
                     );
      $best_score = $score;
      $best_puzzle = $puzzle;
         $best_palabras = $palabras;
   }
   
   if (time() - $t1 > $time_limit - 2) break;
} 
//publicar
$best_palabras = strtoupper($best_palabras);
//echo '&palabras='.$best_palabras;
//echo strtoupper(disp_puzzle($best_puzzle));
$crucigrama=strtoupper(disp_puzzle($best_puzzle));
$query = "INSERT INTO `crucigrama` ( `id_crucigrama` , `crucigrama` , `palabras` , `resuelto` ) 
VALUES (
'', '$crucigrama', '$best_palabras', '0'
);
";
$result = mysql_query($query);
  
}//fin alistar
include("disconnect.php");
function disp_puzzle($puzzle) {
   $ret = "";
   for ($n = 0;; $n ++) {
      if (($m = $n % N22) == 0 or $n < N22 ) {
         $ret .= "-";
      } elseif ($m == N21 ) {
         $ret .= "-";
      } elseif ($n > N2200) {
         $ret .= "-";
      } elseif ($puzzle[$n] == '0') {
         $ret .= "-";
      } elseif ($puzzle[$n] == '.') {
         $ret .= "-";
      } else {
         if (($puzzle[$n - 1] > '0' or $puzzle[$n + 1] > '0') and
             ($puzzle[$n - N22] > '0' or $puzzle[$n + N22] > '0')) {
            $ret .= "$puzzle[$n]";
         } else {
            $ret .= "$puzzle[$n]";
         }
            
      }
      if ($n == N2221) {
         return  "$ret";
      } elseif ($m == N21) {
      }
   }
    return  "$ret";
}
function scan_pos($pos, $dir, $val_blanc) {
   if ($dir == 'h') {
      $inc = 1;
      if ($pos + $inc >= N2222) return false;
      $oinc = N22;
      $new_dir = 'v';
   } else { 
      $inc = N22;
      if ($pos + $inc >= N2222) return false;
      $oinc = 1;
      $new_dir = 'h';
   }
   
   global $puzzle;
   
   if ($puzzle[$pos] < 'a' and (! $val_blanc)) return false;
   
   if (($puzzle[$pos -  $inc] > '0') or ($puzzle[$pos +  $inc] > '0')) {
      return false;
   }
   
   global $palabras;
   global $words;
   global $magics;
   global $poss;
   $regex = $puzzle[$pos];
   
   $left = $right = 0;
   for ($limit_a = $pos - $inc; ($w = $puzzle[$limit_a]) !== '0'; $limit_a -= $inc) {  
      if ($puzzle[$limit_a] == '.' and (($puzzle[$limit_a -  $oinc] > '0') or ($puzzle[$limit_a +  $oinc] > '0'))) {
         break;
      }
      if (++$left == MAXW) {
         $left --;
         break;
      }
      $regex = $w . $regex;
   }
   for ($limit_b = $pos + $inc; ($w = $puzzle[$limit_b]) !== '0'; $limit_b += $inc) {
      if ($puzzle[$limit_b] == '.' and (($puzzle[$limit_b -  $oinc] > '0') or ($puzzle[$limit_b +  $oinc] > '0'))) {
         break;
      }
      if (++$right == MAXW) {
         $right--;
         break;
      }
      $regex .= $w;
   }
   if (($len_regex = strlen($regex)) < 2) return false;
   foreach ($magics[$len_regex] as $m => $lens) {
      
      $ini = max(0, ($left + 1) - $lens);
      $fin = $left;
      
      $pos_p = max($limit_a + $inc, $pos - (($lens - 1 ) * $inc));
      for($pos_c = $ini; $pos_c <= $fin; $pos_c++, $pos_p += $inc) {
        
         if ($puzzle[$pos_p - $inc] > '0') continue;
         
         $r = '/;' . str_replace('.', '\w', substr($regex, $pos_c, $lens)) . ';/';
         if (! preg_match($r, $words, $arr)) continue;
         
         $larr0 = $pos_p + ((strlen($arr[0]) - 2) * $inc);
         
         if ($larr0 >= N2222) continue;
         if ($puzzle[$larr0] > '0') continue;
         
         $words = str_replace("$arr[0]", ';', $words);
         for ($n = 1, $pp = $pos_p; $n < strlen($arr[0]) - 1; $n++, $pp += $inc) {
            
            $puzzle[$pp] = $arr[0][$n];
            if ($pp == $pos) continue;
            
            
            $poss[] = array($pp, $new_dir, ord($puzzle[$pp]));
         }
         $puzzle[$pos_p - $inc] = '0';
         $puzzle[$pp] = '0';
         
         $palabras .=$pos_p."-".$dir."-0-".substr($arr[0],1);    
        
         return true;
      }
   }
   
   return false;
}   
    
?><?php
function cmp($a, $b) {
   return strlen($b) - strlen($a);
}
function cmp_magic($a, $b) {
   return (strlen($a) + mt_rand(0, 3)) - (strlen($b) - mt_rand(0, 1));
}
?>