Code Viewer

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
<head><title>Mastermind</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head><body style="text-align:center;font-family:monospace;white-space:pre"><div><?
 
// check if no options have been set
// if so, allow the user to start a new game
if (!$_POST['opt_columns'])
{
?>
 
<div><b>Mastermind</b></div><form action="mastermind.php" method="post"><div>
Colours: <select name="opt_colours">
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>
<option value="6" selected="selected">Six</option>
<option value="7">Seven</option>
<option value="8">Eight</option>
<option value="9">Nine</option>
<option value="10">Ten</option>
</select>
Columns: <select name="opt_columns">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4" selected="selected">Four</option>
<option value="5">Five</option>
<option value="6">Six</option>
<option value="7">Seven</option>
<option value="8">Eight</option>
<option value="9">Nine</option>
<option value="10">Ten</option>
</select>
 
<input type="submit" value="Play" /></div></form><?
}
else
{
   // this checks how much the guess matches the sequences
   // it returns 'correct if it's perfect and a bunch of B's and W's if it isn't
   // b means a colour is correct and in the correct place
   // w means a colour is correct, but in the wrong place
   function test_sequence($guess, $sequence)
   {
       // check if any are perfect to begin with
       for ($n = 0; $n < count($guess); $n++)
           if ($sequence[$n] == $guess[$n])
               $answer[$n] = 'B';
       // check if everything matches
       if (count($answer) == count($guess) && array_unique($answer) == array('B'))
           return 'correct';
       else
       {
           // check if any are there, but in a different place
           for ($n = 0; $n < count($guess); $n++)
           {
               for ($x = 0; $x < count($guess); $x++)
               {
                   // don't check perfect colours again
                   if ($answer[$n] <> 'B' && $answer[$x] <> 'B' && $guess[$n] == $sequence[$x])
                   {
                       // set to negative so it doesn't get matched again
                       $sequence[$x] = -1;
                       $answer[$n] = 'W';
                   }
               }
           }        
           return $answer;
       }
   }
 
   // only colours that are valid according to the w3c are used
   // any colours that are too light aren't used, like silver/yellow/grey
   $colours = array('Red', 'Blue', 'Green', 'Orange', 'Purple', 'Olive', 'Teal', 'Maroon', 'Fuchsia', 'Lime');
   // slice off any unneccessary colours
   $colours = array_slice($colours, 0, $_POST['opt_colours']);
 
   // check if no sequence was sent
   if (!$_POST['sequence'])
       // generate a new sequence
       for ($a = 0; $a < $_POST['opt_columns']; $a++)
           $sequence[] = array_rand($colours);    
   else
   {
       // i can't use str_split on the server, so i have to do this instead    
       unset($sequence);
       for ($n = 0; $n < strlen($_POST['sequence']); $n++)
           $sequence[] = substr($_POST['sequence'], $n, 1);
   }
   
   /*
   
   // this would output the answer at the top
   // obviously this is just for debugging!
   
   echo '<b> ';
   for ($a = 0; $a < count($sequence); $a++)
       echo $colours[$sequence[$a]] . ' ';
   echo '</b><br/> <br/>';
   */
   
   // first, show any previous guesses
   if ($_POST['previous'])
   {
       $previous_guesses = explode('|', $_POST['previous']);
       // loop through each previous guess
       foreach($previous_guesses as $guess)
       {
           if ($guess)
           {
               // this ensures everything lines up
               echo ' ';
                                       
               // i can't use str_split on the server, so i have to do this instead    
               $guess2 = $guess;
               unset($guess);
               for ($n = 0; $n < strlen($guess2); $n++)
                   $guess[] = substr($guess2, $n, 1);                
               
               for ($a = 0; $a < count($guess); $a++)
                   echo '<span style="color:' . strtolower($colours[$guess[$a]]) . '">' . $colours[$guess[$a]] . '</span> ';
               echo '<br/>';
               // show the result
               $result = test_sequence($guess, $sequence);
               // sometimes there are no black or white results
               // so make sure there are some
               if (is_array($result))
                   echo implode(' ', $result);
               else
                   echo '-';
               echo '<br/> <br/>';                
           }
       }
   }
 
   // check if they have submitted a guess
   if (isset($_POST['check0']))
   {
       // clear the guess variable
       unset($guess);
       // add each colour to the guess array
       for ($n = 0; $n < $_POST['opt_columns']; $n++)
           $guess[] = $_POST['check' . $n];
       // this ensures everything lines up
       echo ' ';            
       // check how close this is
       $result = test_sequence($guess, $sequence);
       // check for perfect match
       if ($result == 'correct')
       {
           // show the colours
           for ($a = 0; $a < count($guess); $a++)
               echo '<span style="color:' . strtolower($colours[$guess[$a]]) . '">' . $colours[$guess[$a]] . '</span> ';
           // show that they have completed this game and how many turns it took them
           echo '<br/><b>Correct!<br/>Completed in ' . count($previous_guesses) . ' turns</b><br/>';
       }
       // it's not perfect, so show them how close
       else
       {
           // add to the previous list to send back later using the form
           $_POST['previous'] .= join($guess) . '|';
           // show the colours
           for ($a = 0; $a < count($guess); $a++)
               echo '<span style="color:' . strtolower($colours[$guess[$a]]) . '">' . $colours[$guess[$a]] . '</span> ';
           echo '<br/>';
           // show the result
           if (is_array($result))
               echo implode(' ', $result);
           else
               echo '-';
       }
 
   }
 
   if ($result != 'correct') {
?><form action="mastermind.php" method="post">
<div><input type="hidden" name="opt_colours" value="<?=$_POST['opt_colours']?>" /><input type="hidden" name="opt_columns" value="<?=$_POST['opt_columns']?>" /><input type="hidden" name="sequence" value="<?=join($sequence)?>" /><input type="hidden" name="previous" value="<?=$_POST['previous']?>" /><?
 
   // this code is responsible for showing the select boxes with the colours
   for ($a = 0; $a < $_POST['opt_columns']; $a++)
   {
       // start of the control
       echo '<select name="check' . $a . '">';
       // one list item per colour
       for ($b = 0; $b < count($colours); $b++)
       {
           // show the last colour selected
           if ($_POST['check' . $a] == $b)
               $selected = ' selected="selected"';
           else
               $selected = '';
               
           // colours are shown in their colour to make it easier to use
           echo '<option value="' . $b . '"' . $selected . ' style="color:' . strtolower($colours[$b]) . '">' . $colours[$b] . '</option>';
       }
       echo '</select> ';
   }
?><br/> <br/><input type="submit" value="Check" /></div></form><? } }
echo '<p>';
if ($_POST['opt_columns'])
   echo '<a href="mastermind.php">New Game</a> | ';
echo '<a href="/projects/littleredbook/9/9">About</a>';
 
?></p></div></body></html>