Games_Chess
[ class tree: Games_Chess ] [ index: Games_Chess ] [ all elements ]

Source for file HTMLChess.php

Documentation is available at HTMLChess.php

  1. <?php
  2. require_once 'Games/Chess/Standard.php';
  3. require_once 'Games/Chess/Losers.php';
  4. require_once 'Games/Chess/Crazyhouse.php';
  5.  
  6. if (!version_compare(phpversion()'4.2.0''>=')) {
  7.     die('Requires PHP version 4.2.0 or greater');
  8. }
  9.  
  10. // hack control
  11. if (!isset($_GET['start']|| !is_string($_GET['start'])) {
  12.     $_GET['start''';
  13. }
  14. if (strlen($_GET['start']!= 2{
  15.     $_GET['start''';
  16. elseif ($_GET['start'!= '' && !preg_match('/[a-h][1-8]/'$_GET['start'])) {
  17.     $_GET['start''';
  18. }
  19.  
  20. if (!isset($_GET['goto']|| !is_string($_GET['goto'])) {
  21.     $_GET['goto''';
  22. elseif (strlen($_GET['goto']!= 2{
  23.     $_GET['goto''';
  24. elseif (!preg_match('/[a-h][1-8]/'$_GET['goto'])) {
  25.     $_GET['goto''';
  26. }
  27.  
  28. if (!empty($_GET['promote']&& !in_array($_GET['promote']array('Q''R',
  29.       'N''B'))) {
  30.     $_GET['promote''Q';
  31. }
  32. /**
  33. * Creates the game and maintains persistence through sessions
  34. * Call this at the top of the webpage
  35. @param string name of the session containing the current game
  36. @param string name of the game variable (a {@link visualboard} class)
  37. */
  38. function setup_game($session_id$gamename)
  39. {
  40.     session_name($session_id);
  41.     session_start();
  42.     if (isset($_GET['newgame'])) {
  43.         session_destroy();
  44.     }
  45.     session_name($session_id);
  46.     session_register($gamename);
  47. }
  48.  
  49. /**
  50.  * The primary class - declare one of these at the top of the file
  51.  *
  52.  * Do it like this:
  53.  *
  54.  * <code>
  55.  * setup_game('mygame','x');
  56.  * $x = $_SESSION['x'];
  57.  * if (!isset($x)) $x = new visualboard;
  58.  * </code>
  59.  * @author Greg Beaver <cellog@users.sourceforge.net>
  60.  * @copyright Copyright 2002, Greg Beaver
  61.  * @version 1.0
  62.  */
  63. class visualboard
  64. {
  65.     /**
  66.      * The logical board
  67.      * @var Games_Chess 
  68.      */
  69.     var $_board;
  70.     /**
  71.      * Promotion contents
  72.      * @var false|array
  73.      */
  74.     var $promote = false;
  75.     /**
  76.      * Game type (Standard, Losers, Crazyhouse)
  77.      * @var string 
  78.      */
  79.     var $_type;
  80.     
  81.     /**
  82.      * Initializes {@link $moves, $board}
  83.      */
  84.     function visualboard($fen = false$type 'Standard')
  85.     {
  86.         $board 'Games_Chess_' $type;
  87.         $this->_board = new $board;
  88.         $this->_type $type;
  89.         $err $this->_board->resetGame($fen);
  90.         if ($this->_board->isError($err)) {
  91.             echo '<b>' .$err->getMessage('</b><br />';
  92.             $this->_board->resetGame();
  93.         }
  94.     }
  95.     
  96.     /**
  97.      * Prints javascript for the function addmove:
  98.      * {@source } 
  99.      */
  100.     function javascript()
  101.     {?>
  102. <script language="JavaScript" type="text/javascript">
  103. <!--
  104. function addMove(move, piece)
  105. {
  106.     if (document.forms[0].start.value == '')
  107.     {
  108.         document.forms[0].start.value = move;
  109.         switch (piece)
  110.         {
  111.             case "P" :
  112.             case "Q" :
  113.             case "R" :
  114.             case "B" :
  115.             case "N" :
  116.             case "K" :
  117.             break;
  118.             default :
  119.                 piece = null;
  120.             break;
  121.         }
  122.         document.forms[0].startpiece.value = piece;
  123.     } else
  124.     {
  125.         if (document.forms[0]["goto"].value == '')
  126.         {
  127.             document.forms[0]["goto"].value = move;
  128.             first = document.forms[0].startpiece.value;
  129.             if (first) {
  130.                 if (first == "P") {
  131.                     first = "";
  132.                     if (piece) {
  133.                         first = document.forms[0].start.value.charAt(0) + "x";
  134.                     }
  135.                 } else {
  136.                     if (piece) {
  137.                         first += "x";
  138.                     }
  139.                 }
  140.             }
  141.             if (confirm("Do this move? (" + first + move + ")"))
  142.             {
  143.                 document.forms[0].submit();
  144.             } else {
  145.                 document.forms[0].start.value = '';
  146.                 document.forms[0].startpiece.values = '';
  147.                 document.forms[0]["goto"].value = '';
  148.                 document.forms[0].SAN.value = '';
  149.             }
  150.         }
  151.     }
  152. }
  153.  
  154. function doPlacement(piece)
  155. {
  156.     switch (piece) {
  157.         case "P" :
  158.             name = "Pawn";
  159.         break;
  160.         case "Q" :
  161.             name = "Queen";
  162.         break;
  163.         case "R" :
  164.             name = "Rook";
  165.         break;
  166.         case "B" :
  167.             name = "Bishop";
  168.         break;
  169.         case "N" :
  170.             name = "Knight";
  171.         break;
  172.     }
  173.     square = prompt("Where should the " + name + " be placed (a1-h8, a1 is lower left)?", "e4");
  174.     if (square) {
  175.         document.forms[0].SAN.value = piece + "@" + square;
  176.         document.forms[0].start.value = "";
  177.         document.forms[0]["goto"].value = "";
  178.         if (square.charAt(1) == "1" || square.charAt(1) == "8") {
  179.             document.forms[0].SAN.value = '';
  180.             document.forms[0].start.value = "";
  181.             document.forms[0]["goto"].value = "";
  182.             alert("Cannot place a pawn on the first or last rank");
  183.         } else {
  184.             document.forms[0].submit();
  185.         }
  186.     }
  187. }
  188. //-->
  189. </script>
  190. <?php
  191.     }
  192.  
  193.     function doCaptured($captured)
  194.     {
  195.         $imagepath dirname(__FILE__. DIRECTORY_SEPARATOR . 'images';
  196.         echo '<table border="1">';
  197. //        echo '<tr><td>&nbsp;</td><td colspan="2">White</td><td colspan="2">Black</td></tr>';
  198.         foreach ($captured['W'as $piece => $number{
  199.             echo '<tr><td>';
  200.             if (file_exists($imagepath '/' $piece '.gif')) {
  201.                 $image $piece '.gif';
  202.                 $imgsize = GetImageSize($imagepath . DIRECTORY_SEPARATOR . $image);
  203.                 $click ($this->_board->toMove(== 'W' && $number?
  204.                     '<a href="#" onclick="doPlacement(\'' $piece '\')">' :
  205.                     '';
  206.                 echo $click '<img src="images/' $image '" border="0" width="' $imgsize[0.
  207.                      '" height="' $imgsize[1'" alt="'$piece '">';
  208.                 echo ($click '</a>' '');
  209.             else {
  210.                 echo $piece;
  211.             }
  212.             echo '</td><td>' $number '</td>';
  213.             $number $captured['B'][$piece];
  214.             echo '<td>';
  215.             if (file_exists($imagepath '/' $piece '.gif')) {
  216.                 $image 'dark/' $piece '.gif';
  217.                 $imgsize = GetImageSize($imagepath . DIRECTORY_SEPARATOR . $image);
  218.                 $click ($this->_board->toMove(== 'B' && $number?
  219.                     '<a href="#" onclick="doPlacement(\'' $piece '\')">' :
  220.                     '';
  221.                 echo $click '<img src="images/' $image '" border="0" width="' $imgsize[0.
  222.                      '" height="' $imgsize[1'" alt="'$piece '">';
  223.                 echo ($click '</a>' '');
  224.             else {
  225.                 echo $piece;
  226.             }
  227.             echo '</td><td>' $number '</td></tr>';
  228.         }
  229.         echo '</table>';
  230.     }
  231.  
  232.     /**
  233.      * Grabs the next move from form variables start, goto, kingcastle and queencastle
  234.      *
  235.      * If $_GET['start'] is not used, it checks for $_GET['kingcastle'] and tries
  236.      * to castle kingside if found.  Otherwise, it looks for $_GET['queencastle']
  237.      * and tries to castle queenside
  238.      */
  239.     function domove()
  240.     {
  241.         if (!empty($_GET['from']&& !empty($_GET['to']&& !empty($_GET['promote'])) {
  242.             $err $this->_board->moveSquare($_GET['from']$_GET['to'],
  243.                                              $_GET['promote']);
  244.             if ($this->_board->isError($err)) {
  245.                 echo '<b>' .$err->getMessage('</b><br />';
  246.             }
  247.             $this->promote = false;
  248.             return;
  249.         }
  250.         if (!empty($_GET['SAN'])) {
  251.             $err $this->_board->moveSAN($_GET['SAN']);
  252.             if ($this->_board->isError($err)) {
  253.                 echo '<b>' .$err->getMessage('</b><br />';
  254.             }
  255.             return;
  256.         }
  257.         if (!empty($_GET['start']&& !empty($_GET['goto'])) {
  258.             if ($this->_board->isPromoteMove($_GET['start']$_GET['goto'])) {
  259.                 $this->promote = array($_GET['start']$_GET['goto']);
  260.                 return;
  261.             else {
  262.                 $this->promote = false;
  263.             }
  264.             $err $this->_board->moveSquare($_GET['start']$_GET['goto']);
  265.             if ($this->_board->isError($err)) {
  266.                 echo '<b>' .$err->getMessage('</b><br />';
  267.             }
  268.         elseif (isset($_GET['kingcastle'])) {
  269.             $err $this->_board->moveSAN('O-O');
  270.             if ($this->_board->isError($err)) {
  271.                 echo '<b>' .$err->getMessage('</b><br />';
  272.             }
  273.         elseif (isset($_GET['queencastle'])) {
  274.             $err $this->_board->moveSAN('O-O-O');
  275.             if ($this->_board->isError($err)) {
  276.                 echo '<b>' .$err->getMessage('</b><br />';
  277.             }
  278.         }
  279.     }
  280.     
  281.     /**
  282.      * This function prints the javascript that will ask the user what to promote the pawn to
  283.      *
  284.      * Using the alert() function, this method asks the user if they want a queen.
  285.      * If they click Cancel, it asks if they want a rook, then knight, then
  286.      * bishop.  If they cancel on bishop, it promotes to queen
  287.      * to avoid any illogical possibilities
  288.      */
  289.     function dopromote()
  290.     {
  291.     ?>
  292. <form action="<?php echo $_SERVER['PHP_SELF'].'?'.session_name().'='.session_id(?>" name="chess" id="chess">
  293. <input type="hidden" name="promote" value=""><input type="hidden" name="from" value="">
  294. <input type="hidden" name="to" value="">
  295. <input type="submit" name="newmove" value="New move"></form>
  296. <script language="JavaScript" type="text/javascript">
  297. <!--
  298.  
  299. function promote(from, to)
  300. {
  301.     document.forms[0].from.value = from;
  302.     document.forms[0].to.value = to;
  303.     if (confirm("promote to Queen?"))
  304.     {
  305.         document.forms[0].promote.value = 'Q';
  306.         document.forms[0].submit();
  307.     } else 
  308.     {
  309.         if (confirm("promote to Rook?"))
  310.         {
  311.             document.forms[0].promote.value = 'R';
  312.             document.forms[0].submit();
  313.         } else
  314.         {
  315.             if (confirm("promote to Knight?"))
  316.             {
  317.                 document.forms[0].promote.value = 'N';
  318.                 document.forms[0].submit();
  319.             } else
  320.             {
  321.                 if (confirm("promote to Bishop?"))
  322.                 {
  323.                     document.forms[0].promote.value = 'B';
  324.                     document.forms[0].submit();
  325.                 } else
  326.                 {
  327.                     document.forms[0].promote.value = 'Q';
  328.                     document.forms[0].submit();
  329.                 }
  330.             }
  331.         }
  332.     }
  333. }
  334. promote('<?php print $this->promote[0"', '" $this->promote[1]?>');
  335. //-->
  336. </script>
  337. <?php
  338.     }
  339.     
  340.     /**
  341.     * Print out the chess game in its entirety: the board, move list and control buttons
  342.     *
  343.     * first, it checks for a pawn promotion and adds the promote move to {@link $moves} using
  344.     * {@link game::addpromote()}.  Then it moves the next piece by calling {@link domove()}.
  345.     * Then it checks for stalemate and checkmate, and stops the gameplay if either condition is met.
  346.     * It creates a visual representation of the board using {@link abstractboard::createrows()}, and
  347.     * displays the chessboard by linking together the display of each row on the chessboard using
  348.     * {@link row::draw()}, and finally the movelist using {@link game::draw()}
  349.     */
  350.     function draw()
  351.     {
  352.         $this->domove();
  353.         if ($this->promote)
  354.         {
  355.             return $this->dopromote();
  356.         }
  357.         $board $this->_board->toArray();
  358.         if ($this->_type == 'Crazyhouse'{
  359.             $captured $board['captured'];
  360.             $board $board['board'];
  361.         }
  362.         $checkmate $this->_board->inCheckmate();
  363.         $fen $this->_board->renderFen();
  364.         $colors = array('#999933''#FFFFFF');
  365.         $textcolors = array('#FFFFFF''#000000');
  366.         $cycle = 0;
  367.         if (!$checkmate$this->javascript();
  368.         echo '<table border="1">';
  369.         $imagepath dirname(__FILE__. DIRECTORY_SEPARATOR . 'images';
  370.         foreach($board as $square => $piece{
  371.             if ($square{0== 'a'{
  372.                 echo '<tr>';
  373.                 $cycle ($cycle + 1% 2;
  374.             }
  375.             echo '<td width="30" bgcolor="' .$colors[$cycle]'"><font color="' .$textcolors[$cycle]'">';
  376.             $upperpiece $piece strtoupper($piece: false;
  377.             echo "<a href=\"#\" onClick=\"addMove('$square', '$upperpiece');return false;" .
  378.                 "\" id=\"$square\">";
  379.  
  380.  
  381.             if ($piece{
  382.                 if (file_exists($imagepath '/' strtoupper($piece'.gif')) {
  383.                     if ($piece != strtoupper($piece)) {
  384.                         $image 'dark/' $piece '.gif';
  385.                     else {
  386.                         $image $piece '.gif';
  387.                     }
  388.                     $imgsize = GetImageSize($imagepath . DIRECTORY_SEPARATOR . $image);
  389.                     echo '<img src="images/' $image '" border="0" width="' $imgsize[0.
  390.                          '" height="' $imgsize[1'" alt="'$piece '">';
  391.                 else {
  392.                     echo $piece;
  393.                 }
  394.             else {
  395.                 if (file_exists($imagepath '/blank.gif')) {
  396.                     if ($this->_board->getDiagonalColor($square== 'W'{
  397.                         $image 'blank.gif';
  398.                     else {
  399.                         $image 'dark/blank.gif';
  400.                     }
  401.                     $imgsize = GetImageSize($imagepath . DIRECTORY_SEPARATOR . $image);
  402.                     echo '<img src="images/' $image '" border="0" width="' $imgsize[0.
  403.                          '" height="' $imgsize[1'" alt="'$piece '">';
  404.                 else {
  405.                     echo '&nbsp;';
  406.                 }
  407.             }
  408.             echo '</a>';
  409.             echo '</font></td>';
  410.             if ($square{0== 'h'{
  411.                 echo '</tr>';
  412.             }
  413.             $cycle ($cycle + 1% 2;
  414.         }
  415.         echo '</table>';
  416.  
  417.         $side $this->_board->toMove(== 'W' 'White' 'Black';
  418.         $gameOver $this->_board->gameOver();
  419.         if ($gameOver{
  420.             $winner $gameOver == 'W' 'White' 'Black';
  421.             if ($stalemate $this->_board->inStalemate())
  422.             {
  423.                 print "<h1>STALEMATE</h1>";
  424.             elseif ($draw $this->_board->inDraw())
  425.             {
  426.                 print "<h1>DRAW</h1>";
  427.             elseif ($this->_board->inCheckmate()) {
  428.                 if (!is_a($this->_board'games_chess_standard')) {
  429.                     $winner $side;
  430.                 else {
  431.                     $winner ($side == 'White''Black' 'White';
  432.                 }
  433.                 print "<h1>CHECKMATE! $winner WINS!</h1>";
  434.             else {
  435.                 print "<h1>$winner WINS!</h1>";
  436.             }
  437.         }
  438.  
  439. ?><form action="<?php echo $_SERVER['PHP_SELF'].'?'.session_name().'='.session_id(?>" name="chess" id="chess">
  440. <?php         if (!$gameOverecho "<b>{$side} to move</b><br>";
  441. if (isset($captured)) {
  442.     echo "<b>Crazyhouse captured pieces available for placement:</b><br>";
  443.     $this->doCaptured($captured);
  444. }
  445.  ?><input type="hidden" value="" name="startpiece">
  446. from <input type="text" name="start" size="2" maxlength="2"> to <input type="text" name="goto" size="2" maxlength="2">
  447. <input type="submit" name="newmove" value="New move"><br>
  448. (alternate) SAN move: <input type="text" name="SAN" size="5"><br>
  449. Reset with new FEN: <input type="text" name="FEN" size="70"><br>
  450. <br><input type="reset"><br>
  451. <?php $this->castlebutton()?><br><br>
  452.  
  453. <input type="submit" name="newgame" value="New Game"><input type="submit" name="newlosergame" value="New Losers Game"><input type="submit" name="newcrazyhousegame" value="New Crazyhouse Game"></form><?php if (!$gameOver?>
  454. for a friend to join, click here <a href="mailto:example@example.com?Subject=Join my chess game!&Body=<?php
  455. echo htmlentities("go to <a href=\"http://" $_SERVER['SERVER_NAME'$_SERVER['PHP_SELF'
  456. "?mygame=".session_id()."\">Here</a> to play me in chess! http://$_SERVER[SERVER_NAME]$_SERVER[PHP_SELF]?mygame=" .
  457. session_id())?>">Email my friend</a>
  458.  
  459. <form action="<?php echo $_SERVER['PHP_SELF'].'?'.session_name().'='.session_id(?>">
  460. <input type="submit" value="Check to see if opponent has moved"></form>
  461. <?php }
  462.         
  463.         echo "<blockquote>Current position FEN: <strong>$fen</strong></blockquote>";
  464.         $moves $this->_board->getMoveList(true);
  465.         echo '<table border="1"><th colspan="3" align="center">Moves</th><tr>' .
  466.              '<td>#</td><td>White</td><td>Black</td></tr>';
  467.         foreach($moves as $num => $moveset{
  468.             echo '<tr>';
  469.             echo "<td>$num</td>";
  470.             if (isset($moveset[0])) {
  471.                 echo "<td>$moveset[0]</td>";
  472.             else {
  473.                 echo "<td>&nbsp;</td>";
  474.             }
  475.             
  476.             if (isset($moveset[1])) {
  477.                 echo "<td>$moveset[1]</td>";
  478.             }
  479.             echo '</tr>';
  480.         }
  481.         echo '</table>';
  482.     }
  483.     
  484.     /**
  485.     * Prints the castling buttons after checking castling rights
  486.     *
  487.     * If castling rights have been taken away by a king or rook move, the button is not displayed.  This function
  488.     * uses {@link Games_Chess::canCastleKingside(), Games_Chess::canCastleQueenside()} to find out.
  489.     */
  490.     function castlebutton()
  491.     {
  492.         if ($this->_board->canCastleKingside())
  493.         echo '<input type="submit" name="kingcastle" value="Castle Your King Kingside">';
  494.         if ($this->_board->canCastleQueenside())
  495.         echo '<input type="submit" name="queencastle" value="Castle Your King Queenside">';
  496.     }
  497. }
  498.  
  499. setup_game('mygame','x');
  500. $x $_SESSION['x'];
  501. $fen = isset($_GET['FEN']$_GET['FEN': false;
  502. if (!isset($x|| isset($_GET['newgame']|| $fen
  503.       || isset($_GET['newlosergame']|| isset($_GET['newcrazyhousegame'])) {
  504.     if (isset($_GET['newcrazyhousegame'])) {
  505.         $x = new visualboard($fen'Crazyhouse');
  506.     elseif (isset($_GET['newlosergame'])) {
  507.         $x = new visualboard($fen'Losers');
  508.     else {
  509.         $x = new visualboard($fen'Standard');
  510.     }
  511. }
  512. ?>
  513. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  514.  
  515. <html>
  516. <head>
  517.     <title>PHP Chess!</title>
  518. </head>
  519.  
  520. <body>
  521. <h1>Welcome to <a href="http://www.chiaraquartet.net">The Chiara Quartet's</a> PHP Chess</h1>
  522. <?php
  523. $x->draw();
  524. $_SESSION['x'$x;
  525. ?>
  526.  
  527.  
  528. </body>
  529. </html>

Documentation generated on Mon, 11 Mar 2019 15:05:02 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.