view index.php @ 45:4617c39366a5

Put program name and copyright into variables, and use them.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 22 Mar 2011 20:10:01 +0200
parents ebd29544477c
children dd39f6bbc4cb
line wrap: on
line source

<?
// Settings
$dataFile = "results.txt";
$cacheFile = "cache.php";
$imagePath = "img/";

// Execution time measurement
$tick = array_sum(explode(" ", microtime()));

if (!extension_loaded('gd')) {
   if (!dl('gd.so')) {
       echo "Could not load extension GD!";
       exit;
   }
}

$dbModes = array(
  "min"  => array("Mineral",     0, "minerals"),
  "org"  => array("Organ",       1, "organs"),
  "herb" => array("Herb",        2, "herbs"),
  "list" => array("Potion list", 3, "potions"),
);

$dbNames = array(
  array(
    "adamantium", "aluminium", "anipium", "batium", "brass", "bronze",
    "cesium", "chromium", "cobalt", "copper", "darksteel", "diggalite",
    "dukonium", "duraluminium", "durandium", "electrum", "gold",
    "graphite", "hematite", "highsteel", "illumium", "indium", "iridium",
    "iron", "kryptonite", "lead", "magnesium", "mithril", "molybdenum",
    "mowgles", "mowglite", "nickel", "nullium", "osmium", "palladium",
    "pewter", "platinum", "potassium", "pyrite", "quicksilver", "rhodium",
    "silicon", "silver", "starmetal", "steel", "tadmium", "tin", "titanium",
    "tormium", "tungsten", "uranium", "vanadium", "zhentorium", "zinc"
  ),

  array(
    "antenna", "arm", "beak", "bladder", "brain", "ear", "eye", "foot",
    "gill", "heart", "horn", "kidney", "leg", "liver", "lung", "nose",
    "paw", "snout", "spleen", "stomach", "tail", "tendril", "wing"
  ),

  array(
    array("apple",       "wormwood"),       array("barberry",    "yarrow"),
    array("blueberry",   "wolfbane"),       array("burdock",     "chickweed"),
    array("cabbage",     "arnica"),         array("carrot",      "thistle"),
    array("cauliflower", "costmary"),       array("chicory",     "borage"),
    array("cotton",      "mysticspinach"),  array("crystalline", "jaslah"),
    array("elder",       "honeysuckle"),    array("foxglove",    "holly"),
    array("garlic",      "nightshade"),     array("ginseng",     "mistletoe"),
    array("hemlock",     "tomato"),         array("henbane",     "jimsonweed"),
    array("lettuce",     "water_lily"),     array("lobelia",     "comfrey"),
    array("mushroom",    "mangrel"),        array("onion",       "moss"),
    array("pear",        "boneset"),        array("plum",        "sweetflag"),
    array("potato",      "mandrake"),       array("raspberry",   "bloodroot"),
    array("rhubarb",     "soapwort"),       array("spinach",     "hcliz"),
    array("strawberry",  "mugwort"),        array("turnip",      "mysticcarrot"),
    array("vine_seed",   "lungwort")
  ),
  
  array("sorted by mineral", "sorted by organ", "sorted by herb pair", "sorted by potion name"),
);


$dbDims = array();
foreach ($dbNames as $key => $data)
  $dbDims[$key] = count($data);
$db = array();


function alch_matrix_clear($val = ".")
{
  global $dbDims, $db;
  
  for ($x = 0; $x < $dbDims[0]; $x++)
    for ($y = 0; $y < $dbDims[1]; $y++)
      for ($z = 0; $z < $dbDims[2]; $z++)
        $db[$x][$y][$z] = $val;
}


function alch_matrix_set_col_if($x, $y, $z, $idx, $ifval, $setval, $equals = TRUE)
{
  global $dbDims, $db;

  if ($x < 0) { $col = 0; $x = &$i; } else
  if ($y < 0) { $col = 1; $y = &$i; } else 
              { $col = 2; $z = &$i; }

  for ($i = 0; $i < $dbDims[$col]; $i++) {
    if (($db[$x][$y][$z][$idx] == $ifval) == $equals)
         $db[$x][$y][$z][$idx] = $setval;
  }
}


function alch_find_pairs($item, $key)
{
  foreach ($item as $key => $val) {
    $minTab[$val[0]]++;
    $orgTab[$val[1]]++;
    $herbTab[$val[2]]++;
    
    // why?
    if ($val[0] == 255) $t = true;
  }
  
  // why?
  if ($t) return 0;


  // ??? is it necessary to go through the whole array?
  foreach ($minTab as $key => $val) if ($val > 1) $min = $key;
  foreach ($orgTab as $key => $val) if ($val > 1) $org = $key;
  foreach ($herbTab as $key => $val) if ($val > 1) $her = $key;

  if ($min != "" && $org != "") alch_matrix_set_col_if($min, $org,   -1, 1, "", "*", TRUE);
  if ($min != "" && $her != "") alch_matrix_set_col_if($min,   -1, $her, 1, "", "*", TRUE);
  if ($org != "" && $her != "") alch_matrix_set_col_if(  -1, $org, $her, 1, "", "*", TRUE);
}


function array_search_multi($val, $arr)
{
  foreach ($arr as $key => $pair)
    if ($pair[0] == $val || $pair[1] == $val)
      return $key;

  return false;
}


function alch_matrix_cell($r)
{
  $res = $r[0];
  switch ($r[0]) {
    case "!": $class = "accepted"; break;

    case "?": $class = ($r[1] == "*") ? "pairclose" : "close"; break;

    case "-": if ($r[1] == "-") $class = "nomatch";
              else if ($r[1] == "*") $class = "pairno";
              else if ($r[1] !== "") $class = "noclose";
              else $class = "nomark";
              break;

    case ".": if ($r[1] == "*") $class = "pair"; 
              $res = "&nbsp;";
              break;
    default: $class = "notres"; break;
  }
  echo "<td class=\"".$class."\" title=\"".$r."\">".$res."</td>";
}


function alch_matrix_print($mode, $active)
{
  global $dbNames, $dbModes, $db, $imagePath;

  $pkey = $dbModes[$mode][1];
  
  if ($pkey == 0) { $key1 = 2; $key2 = 1; $px =  $active; $py = &$colKey; $pz = &$rowKey; } else
  if ($pkey == 1) { $key1 = 2; $key2 = 0; $px = &$colKey; $py =  $active; $pz = &$rowKey; } else
                  { $key1 = 1; $key2 = 0; $px = &$colKey; $py = &$rowKey; $pz =  $active; }

  $pdata = $dbNames[$pkey];
  $data1 = $dbNames[$key1];
  $data2 = $dbNames[$key2];

  // Determine number of columns by number of cells
  $max = count($pdata);
  if ($max / 3 > 10)
    $div = $max / 3;
  else
    $div = $max / 2;
    
  // Print selection for primary key
  echo "<table class=\"seltable\" border=\"1\" cellspacing=\"0\">\n";
  $n = 0;
  foreach ($pdata as $key => $val) {
    if ($n == 0) echo " <tr>\n";

    echo "  <td class=\"".
    ($key == $active ? "atab" : "tab").
    "\"><a href=\"?".$mode."=".$key."\">";
    
    if (is_array($val))
      echo htmlentities($val[0])."<br />".htmlentities($val[1]);
    else 
      echo htmlentities($val);

    echo "</a></td>\n";

    if (++$n >= $div) {
      echo " </tr>\n";
      $n = 0;
    }
  }
  if ($n != 0)
    echo " </tr>\n";


  // Print mix table header
  $str = is_array($pdata[0]) ? $pdata[$active][0]." or ".$pdata[$active][1] : $pdata[$active];

  echo "</table>\n".
  "<h1>".htmlentities($str)."</h1>\n".
  "<table class=\"mixtable\" border=\"1\" cellspacing=\"0\">\n".
  " <tr>\n".
  "  <th></th>\n";

  $imgWidth = 12;
  $imgHeight = 80;
  foreach ($data2 as $key => $val) {
    $str = is_array($val) ? $val[0]." / ".$val[1] : $val;

    // Create image files for the text entries, if they don't already exist
    $filename = "txt_".preg_replace("/[^a-z0-9]/", "_", strtolower($str)).".png";
    echo "  <th><img src=\"".$imagePath.urlencode($filename)."\" alt=\"".htmlentities($str)."\" width=\"".$imgWidth."\" height=\"".$imgHeight."\"></th>\n";

    if (!file_exists($imagePath.$filename)) {
      $image = imagecreate($imgWidth, $imgHeight);
      $c_black = imagecolorallocate($image,   0,   0,   0);
      $c_white = imagecolorallocate($image, 255, 255, 255);

      imagefill($image, 0, 0, $c_black);
      imagestringup($image, 2, -2, 78, $str, $c_white);

      imagepng($image, $imagePath.$filename);
      imagedestroy($image);
      chmod($imagePath.$filename, 0644);
    }
  }
  
  echo " </tr>\n";

  // Print the table itself
  foreach ($data1 as $rowKey => $rowVal) {
    $str = is_array($rowVal) ? $rowVal[0]." / ".$rowVal[1] : $rowVal;
    echo " <tr><th>".htmlentities($str)."</th>";
    foreach ($data2 as $colKey => $colVal) {
      alch_matrix_cell($db[$px][$py][$pz]);
    }
    echo "</tr>\n";
  }
  echo "</table>\n";
}


// Select view mode based on script GET arguments
$mode = "min";
$active = 0;
foreach ($dbModes as $name => $data) {
  if (isset($_GET[$name])) {
    $active = intval($_GET[$name]);
    if ($active < 0 || $active >= $dbDims[$data[1]])
      $active = 0;
    $mode = $name;
    break;
  }
}

// Copyright information etc.
$progName = "AlchTool 1.9.0&beta;";
$progCopyright ="&copy; 2006-2011 Jeskko &amp; Ggr Pupunen";

?>
<html>
 <head>
  <title><? echo $progName." - ".$dbModes[$mode][0]." view (".$dbNames[$dbModes[$mode][1]][$active].")"; ?></title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <link href="alch.css" title="compact" rel="stylesheet" type="text/css">
 </head>
<script type="text/javascript">
<!--
var savePos = 0;
function vis()
{
  var e = document.getElementById('legend');
  e.style.height = "3em";
  if (e.style.top != "0px") {
    savePos = e.style.top;
    e.style.top = "0px";
  } else {
    e.style.top = savePos;
  }
}
-->
</script>
<body>
<div id="info">
<?

alch_matrix_clear();

#if (1)
if (filemtime($dataFile) > filemtime($cacheFile))
{
  $file = fopen($dataFile, "r");

  while (($rawline = fgets($file)) !== FALSE) {
    $line = trim($rawline);
    if ($line == "" || $line[0] == '#') continue;

    list ($m, $o, $h, $r) = preg_split("/\s+/", $line, 4);

    // Get indexes
    $mn = array_search($m, $dbNames[0]);
    $on = array_search($o, $dbNames[1]);
    $hn = array_search_multi($h, $dbNames[2]);

    if ($mn === false || $on === false || $hn === false) {
      echo "# Invalid data: '$line'<br />\n";
      continue;
    }

    if ($r== "-") {
      alch_matrix_set_col_if( -1, $on, $hn, 0, "!", "-", FALSE);
      alch_matrix_set_col_if($mn,  -1, $hn, 0, "!", "-", FALSE);
      alch_matrix_set_col_if($mn, $on,  -1, 0, "!", "-", FALSE);

      $db[$mn][$on][$hn][1] = "-";
    }
    else
    if ($r[0] == "?") {
      if ($r[1] != "?")
        $mat[$r][] = array($mn, $on, $hn);

      if ($db[$mn][$on][$hn][0] == "-") {
        $db[$mn][$on][$hn] = $r;
        $db[$mn][$on][$hn][0] = "-";
      } else
        $db[$mn][$on][$hn] = $r;
    }
    else
    if ($r[0] == "!") {
      $t = $r;
      $t[0] = "?";
   
      $mat[$t][] = array(255, 255, 255);
      $db[$mn][$on][$hn] = $r;
    }
  } // while

  array_walk($mat, "alch_find_pairs");

  $cache = @fopen($cacheFile, "w");
  if ($cache !== false) {
    fwrite($cache, serialize($db));
    fclose($cache);
    echo "Made a new cache.<br />\n";
  } else
    echo "Error writing cache file!<br />\n";

} else {

  $cache = @file_get_contents($cacheFile);

  if ($cache !== false)
    $db = unserialize($cache);

  if (isset($db) && $db !== false)
    echo "Using cache made at " . date ("F d Y H:i:s.", filemtime($cacheFile))."<br>";
}


// Calculate statistics
$results = array();
for ($x = 0; $x < $dbDims[0]; $x++)
for ($y = 0; $y < $dbDims[1]; $y++)
for ($z = 0; $z < $dbDims[2]; $z++)
  $results[$db[$x][$y][$z][0]]++;

echo "<b>".$results["!"]."</b> found potions, ".
  "<b>".$results["?"]."</b> active partial matches, ".
  "<b>".$results["-"]."</b> combinations eliminated, ".
  "<b>".$results["."]."</b> combinations untested.\n".
  "</div>\n";


function printItem($x, $y, $z, $s, &$index)
{
  global $dbNames, $db;
  $index++;
  echo "<tr>".
    "<th>".$index."</th>".
    "<td>".$dbNames[0][$x]."</td>".
    "<td>".$dbNames[1][$y]."</td>".
    "<td>".$dbNames[2][$z][0]." / ".$dbNames[2][$z][1]."</td>".
    "<td>".$s."</td></tr>";
}

function checkItem($x, $y, $z, &$index)
{
  global $dbNames, $db;
  $s = $db[$x][$y][$z];
  if ($s[0] == "!")
    printItem($x, $y, $z, substr($s, 1), $index);
}

echo "<div id=\"controls\">Change index key to ";
foreach ($dbModes as $id => $data)
  echo "[<a href=\"?".$id."=0\">".$data[2]."</a>] ";
echo "</div>\n";

if ($mode == "list")
{
  $index = 0;
  echo "<h1>".$dbModes[$mode][0]." view (".$dbNames[$dbModes[$mode][1]][$active].")</h1>
  <table class=\"potlist\">
  <tr>
   <th>#</th>
   <th><a href=\"?list=0\">Mineral</a></th>
   <th><a href=\"?list=1\">Organ</a></th>
   <th><a href=\"?list=2\">Herb</a></th>
   <th><a href=\"?list=3\">Potion</a></th>
  </tr>
  ";
  if ($active == 0)
  {
    for ($x = 0; $x < $dbDims[0]; $x++)
    for ($y = 0; $y < $dbDims[1]; $y++)
    for ($z = 0; $z < $dbDims[2]; $z++)
      checkItem($x, $y, $z, $index);
  }
  else if ($active == 1)
  {
    for ($y = 0; $y < $dbDims[1]; $y++)
    for ($x = 0; $x < $dbDims[0]; $x++)
    for ($z = 0; $z < $dbDims[2]; $z++)
      checkItem($x, $y, $z, $index);
  }
  else if ($active == 2)
  {
    for ($z = 0; $z < $dbDims[2]; $z++)
    for ($x = 0; $x < $dbDims[0]; $x++)
    for ($y = 0; $y < $dbDims[1]; $y++)
      checkItem($x, $y, $z, $index);
  }
  else
  {
    $potions = array();
    for ($z = 0; $z < $dbDims[2]; $z++)
    for ($x = 0; $x < $dbDims[0]; $x++)
    for ($y = 0; $y < $dbDims[1]; $y++)
    {
      $s = $db[$x][$y][$z];
      if ($s[0] == "!")
        $potions[substr($s, 1)] = array($x, $y, $z);
    }
    ksort($potions);
    foreach ($potions as $name => $data)
      printItem($data[0], $data[1], $data[2], $name, $index);
  }
  echo "</table>\n";
}
else
{
  alch_matrix_print($mode, $active);
?>

<table id="legend" border="1" cellspacing="1" onmouseover="vis();">
 <tr><th colspan="2" class="noframe">Legend</th></tr>
 <tr><td width="10%" class="notres">&nbsp;</td><th class="noframe">Not researched yet</th></tr>
 <tr><td class="nomatch">-</td><th class="noframe">No match</th></tr>
 <tr><td class="nomark">-</td><th class="noframe">Marked to no potion by another no match.</th></tr>
 <tr><td class="noclose">-</td><th class="noframe">2 materials match, marked as no potion by another no match.</th></tr>
 <tr><td class="close">?</td><th class="noframe">2 materials match</th></tr>
 <tr><td class="accepted">!</td><th class="noframe">Accepted potion</th></tr>
 <tr><td class="pair">&nbsp</td><th class="noframe">Known to be possible potion by other attempts</th></tr>
 <tr><td colspan="2"><? echo $progName." ".$progCopyright; ?></td></tr>
</table>
<?
}

$tock = array_sum(explode(" ",microtime()));
echo "Page took " . round(($tock - $tick),2) . " seconds to process.<br />";
?>
</body>
</html>