1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4: */ 3// +----------------------------------------------------------------------+ 4// | PHP version 4 | 5// +----------------------------------------------------------------------+ 6// | Copyright (c) 2003 The PHP Group | 7// +----------------------------------------------------------------------+ 8// | This source file is subject to version 3.0 of the PHP license, | 9// | that is bundled with this package in the file LICENSE, and is | 10// | available through the world-wide-web at | 11// | http://www.php.net/license/3_0.txt. | 12// | If you did not receive a copy of the PHP license and are unable to | 13// | obtain it through the world-wide-web, please send a note to | 14// | license@php.net so we can mail you a copy immediately. | 15// +----------------------------------------------------------------------+ 16// | Authors: Gregory Beaver <cellog@php.net> | 17// +----------------------------------------------------------------------+ 18// 19// $Id: Losers.php,v 1.3 2004/04/09 06:22:30 cellog Exp $ 20/** 21 * A Losers chess game representation (wild 16 on ICC) 22 * @package Games_Chess 23 * @author Gregory Beaver <cellog@php.net> 24 */ 25/** 26 * The parent class 27 */ 28require_once 'Games/Chess/Standard.php'; 29 30/** 31 * Losers chess game 32 * 33 * The goal of the game is to lose all of your pieces or force your opponent 34 * to checkmate you. The only differences from standard chess are that if 35 * a capture is possible it must be executed, similar to checkers, and 36 * checkmate actually loses the game! 37 * @package Games_Chess 38 * @author Gregory Beaver <cellog@php.net> 39 */ 40class Games_Chess_Losers extends Games_Chess_Standard { 41 /** 42 * Determine whether it is possible to capture an opponent's piece 43 * @access protected 44 */ 45 function _capturePossible() 46 { 47 $allmoves = array(); 48 $color = $this->_move == 'W' ? 'B' : 'W'; 49 foreach ($this->_pieces as $name => $loc) { 50 if (!$loc) { 51 continue; 52 } 53 if ($name{0} == $this->_move) { 54 // don't return castle move shortcuts 55 if ($name{1} == 'P') { 56 $allmoves = array_merge($allmoves, 57 $this->getPossibleMoves($loc[1], $loc[0], $this->_move, false)); 58 } else { 59 $allmoves = array_merge($allmoves, 60 $this->getPossibleMoves($name{1}, $loc, $this->_move, false)); 61 } 62 } 63 } 64 foreach ($this->_pieces as $name => $loc) { 65 if ($name{0} == $this->_move || !$loc) { 66 continue; 67 } 68 if (is_array($loc)) { 69 if (in_array($loc[0], $allmoves)) { 70 return true; 71 } 72 } else { 73 if (in_array($loc, $allmoves)) { 74 return true; 75 } 76 } 77 } 78 return false; 79 } 80 81 /** 82 * Validate a move 83 * @param array parsed move array from {@link _parseMove()} 84 * @return true|PEAR_Error 85 * @throws GAMES_CHESS_ERROR_MOVE_MUST_CAPTURE 86 * @access protected 87 */ 88 function _validMove($move) 89 { 90 list($type, $info) = each($move); 91 if ($this->_capturePossible() && 92 ($type == GAMES_CHESS_CASTLE || 93 $this->_board[$info['square']] == $info['square'])) { 94 if ($type == GAMES_CHESS_CASTLE) { 95 $san = $info == 'K' ? 'O-O' : 'O-O-O'; 96 } else { 97 $san = $info['piece'] . $info['disambiguate'] . $info['takes'] . $info['square']; 98 } 99 return $this->raiseError(GAMES_CHESS_ERROR_MOVE_MUST_CAPTURE, 100 array('san' => $san)); 101 } 102 return parent::_validMove($move); 103 } 104 105 /** 106 * @return W|B|D winner of game, or draw 107 */ 108 function gameOver() 109 { 110 $opposite = $this->_move == 'W' ? 'B' : 'W'; 111 if ($this->inCheckmate()) { 112 return $this->_move; 113 } 114 if ($this->inDraw()) { 115 return 'D'; 116 } 117 $W = array(); 118 $B = array(); 119 foreach ($this->_pieces as $name => $loc) { 120 if (!$loc || $name{1} == 'K') { 121 continue; 122 } 123 if ($name{0} == 'W') { 124 $W[] = 1; 125 } else { 126 $B[] = 1; 127 } 128 } 129 if (!count($W)) { 130 return 'W'; 131 } 132 if (!count($B)) { 133 return 'B'; 134 } 135 return false; 136 } 137} 138?>