Zend - The PHP Company




Games

Add Code


Cross Word Generator  

Type: application
Added by: codewalkers
Entered: 04/08/2002
Last modified: 08/12/2001
Rating: - (fewer than 3 votes)
Views: 10850
This is a winner from the PHP Coding Contest at Codewalkers.com Given a list of words provided by wordlist.txt, this script will create a crossword puzzle.


<?

/*
Crossing Words for
Codewalkers PHP Coding Contest of July 2002
(http://codewalkers.com/php-contest.php)

Author �ngel Fenoy from Arenys de Mar, Barcelona.
*/

set_time_limit($time_limit 30);
$t1 time();
//error_reporting(E_ALL);

mt_srand((double)(microtime()*100000000));

echo 
"<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1'>
<title>Crossing Words - Codewalkers PHP Coding Contest - July 2002</title>
<style type='text/css'>
th, td, body { font-family: monospace; font-size: 12px }
.marc { background-color: #667966; color: #b0b0b0 }
.limit { background-color: #d0e0d0; color: #c0c0c0 }
.blanc { background-color: #d0e0d0; color: #f9fff9 }
.connector { background-color: #494900; color: #ffffff }
.filled { background-color: #004949; color: #ffffff }
</style>
</head>
<body text='#000000' bgcolor='#ffffff'>
"
;


define('N20'20);
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);

$lens array_pad(array(), 210);
foreach(
$arrfile as $n => $wordn) {
   
$lens[strlen($arrfile[$n] = trim($wordn))] ++;
}

$sum 0;
foreach(
$lens as $len => $q) {
   
$sum += $q;
   if ( (
$sum 160 and $len 5) or
        (
$sum 140 and $len 6) or
        (
$sum 120 and $len 7) or
        (
$sum >  99 and $len 8) ) {

      
define('MAXW'$len);
      
define('MAXW1'MAXW 1);
      break;
   }
}


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

$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(310);
   
$col mt_rand(310);
   
$pos N22 $row $col;
   
   
$poss = array();
   
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;
   }
   
   if (
time() - $t1 $time_limit 2) break;
}   

echo 
"n<table border=0 cellpadding=10>n<tr>n<td>";

echo 
disp_puzzle($best_puzzle);

echo 
"n</td>n<td align=right>";

foreach(
$bests as $field => $value) {
   echo 
"n$field: <b>$value</b><br>";
}

echo 
"nTotal score: <b>$best_score</b><br>";

echo 
"n<br><br>Elapsed time: <b>" . (time() - $t1) . " seconds</b>";

echo 
"
</td>
</tr>
</table>
</body>
</html>"
;

function 
disp_puzzle($puzzle) {

   
$ret "n<table border=0 cellpadding=2 cellspacing=1>n<tr>";
   for (
$n 0;; $n ++) {
      if ((
$m $n N22) == or $m == N21 or $n N22 or $n N2200) {
         
$ret .= "n<td class=marc>&nbsp;&nbsp;</td>";
      } elseif (
$puzzle[$n] == '0') {
         
$ret .= "n<td class=limit>&nbsp;</td>";
      } elseif (
$puzzle[$n] == '.') {
         
$ret .= "n<td class=blanc>&nbsp;</td>";
      } else {
         if ((
$puzzle[$n 1] > '0' or $puzzle[$n 1] > '0') and
             (
$puzzle[$n N22] > '0' or $puzzle[$n N22] > '0')) {
            
$ret .= "n<td align=center class=connector>$puzzle[$n]</td>";
         } else {
            
$ret .= "n<td align=center class=filled>$puzzle[$n]</td>";
         }
            
      }

      if (
$n == N2221) {
         return 
"$retn</tr>n</table>";
      } elseif (
$m == N21) {
         
$ret .= "n</tr>n<tr>";
      }
   }
   return 
"$retn</tr>n</table>";
}


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 
$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 ) * $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_dirord($puzzle[$pp]));
         }
         
$puzzle[$pos_p $inc] = '0';
         
$puzzle[$pp] = '0';
         
         return 
true;
      }
   }
   
   return 
false;
}         

?><?

function cmp($a$b) {
   return 
strlen($b) - strlen($a);
}

function 
cmp_magic($a$b) {
   return (
strlen($a) + mt_rand(03)) - (strlen($b) - mt_rand(01));
}

?>   


Usage Example




Rate This Script





Search



This Category All Categories