function reachable_squares() { #Array of square where the piece can move to $squares = array(); $csq = $this->get_current_square(); $hdist = abs(Board::horz_distance("a1", $csq)); $vdist = abs(Board::vert_distance("a1", $csq)); $dist = $hdist > $vdist ? $vdist : $hdist; $sq = Board::add_horz_distance($csq, -$dist); $sq = Board::add_vert_distance($sq, -$dist); $squares = array_merge($squares, Board::squares_in_line($csq, $sq)); $hdist = abs(Board::horz_distance("h1", $csq)); $vdist = abs(Board::vert_distance("h1", $csq)); $dist = $hdist > $vdist ? $vdist : $hdist; $sq = Board::add_horz_distance($csq, $dist); $sq = Board::add_vert_distance($sq, -$dist); $squares = array_merge($squares, Board::squares_in_line($csq, $sq)); $hdist = abs(Board::horz_distance("a8", $csq)); $vdist = abs(Board::vert_distance("a8", $csq)); $dist = $hdist > $vdist ? $vdist : $hdist; $sq = Board::add_horz_distance($csq, -$dist); $sq = Board::add_vert_distance($sq, $dist); $squares = array_merge($squares, Board::squares_in_line($csq, $sq)); $hdist = abs(Board::horz_distance("h8", $csq)); $vdist = abs(Board::vert_distance("h8", $csq)); $dist = $hdist > $vdist ? $vdist : $hdist; $sq = Board::add_horz_distance($csq, $dist); $sq = Board::add_vert_distance($sq, $dist); $squares = array_merge($squares, Board::squares_in_line($csq, $sq)); #Removes current position square $squares = preg_grep("/^{$csq}\$/", $squares, PREG_GREP_INVERT); return $squares; }
function reachable_squares() { #Array of square where the piece can move to $squares = array(); $csq = $this->get_current_square(); $x = Board::horz_distance("a4", $csq); $y = Board::vert_distance("d1", $csq); $row_start = 'a' . ($y + 1); $row_end = 'h' . ($y + 1); $col_start = chr(ord('a') + $x) . '1'; $col_end = chr(ord('a') + $x) . '8'; $row = Board::squares_in_line($row_start, $row_end); $col = Board::squares_in_line($col_start, $col_end); $squares = array_merge($squares, $row, $col); #Removes current position square $squares = preg_grep("/^{$csq}\$/", $squares, PREG_GREP_INVERT); return $squares; }
/** * Takes two parameters containing the name of the square to move from and * the name of the square to move to. They should be validated with * "square_is_valid()" in Board before calling. Optionally takes a * third parameter, which can be set to zero to indicate that no legality * checking should be done. In this case, flags indicating 'en passant' pawn * captures or castling will not be set! Only by entirely validating the move * do these flags have any meaning. The default is to validate every move. * * @param string $sq1 current position of the piece * @param string $sq2 destination of the piece * @param bool $validate whether to validate the move * * @return MoveListEntry|NULL a MoveListEntry representing the move just made or NULL * if any errors occur and the move was not considered */ public function make_move($sq1, $sq2, $validate = true) { $move = NULL; #Invalid square if (Board::square_is_valid($sq1) == false) { return NULL; } if (Board::square_is_valid($sq2) == false) { return NULL; } if ($validate) { if ($this->is_move_legal($sq1, $sq2) == false) { return NULL; } } $player1 = $this->players[0]; $player2 = $this->players[1]; $board = $this->board; $piece = $board->get_piece_at($sq1); $player = $piece->get_player(); #if no piece at sq1 if ($piece == NULL) { return NULL; } $movelist = $this->movelist; $capture = $board->get_piece_at($sq2); $flags = 0x0; if ($validate && $piece instanceof Pawn) { if ($player == $player1) { if (Board::vert_distance("d8", $sq2) == 0) { $flags = $flags | self::__MOVE_PROMOTE__; } //Bitwise Or } else { if (Board::vert_distance("d1", $sq2) == 0) { $flags = $flags | self::__MOVE_PROMOTE__; } //Bitwise Or } } if ($capture) { $flags = $flags | self::__MOVE_CAPTURE__; //Bitwise Or $capture->set_captured(1); $board->set_piece_at($sq1, NULL); $board->set_piece_at($sq2, $piece); $piece->set_current_square($sq2); $piece->set_moved(1); $move = $movelist->add_move($piece, $sq1, $sq2, $flags); $movenum = $move->get_move_num(); $this->captures[$player][$movenum] = $capture; } else { if ($validate && $piece instanceof Pawn && $this->_is_valid_en_passant($piece, $sq1, $sq2)) { $last_moved = $movelist->get_last_moved(); $move = $movelist->get_move($movelist->get_move_num(), $last_moved); $capture = $move->get_piece(); $flags = $flags | self::__MOVE_CAPTURE__; $flags = $flags | self::__MOVE_EN_PASSANT__; $capture->set_captured(1); $board->set_piece_at($sq1, NULL); $board->set_piece_at($sq2, $piece); $piece->set_current_square($sq2); $move = $movelist->add_move($piece, $sq1, $sq2, $flags); $this->analyzed = 0; $movenum = $move->get_move_num(); $piece->_set_firstmoved($movenum); $this->captures[$player][$movenum] = $capture; } else { if ($validate && $piece instanceof King) { if ($this->_is_valid_short_castle($piece, $sq1, $sq2)) { $flags = $flags | self::__MOVE_CASTLE_SHORT__; } if ($this->_is_valid_long_castle($piece, $sq1, $sq2)) { $flags = $flags | self::__MOVE_CASTLE_LONG__; } } if ($flags & self::__MOVE_CASTLE_SHORT__ || $flags & self::__MOVE_CASTLE_LONG__) { $rook_sq = $king_sq = $rook_sq_new = $king_sq_new = NULL; $rook = $king = NULL; if ($player == $player1) { $rook_sq = $flags & self::__MOVE_CASTLE_SHORT__ ? "h1" : "a1"; $rook_sq_new = $flags & self::__MOVE_CASTLE_SHORT__ ? "f1" : "d1"; $king_sq = "e1"; $king_sq_new = $flags & self::__MOVE_CASTLE_SHORT__ ? "g1" : "c1"; } else { $rook_sq = $flags & self::__MOVE_CASTLE_SHORT__ ? "h8" : "a8"; $rook_sq_new = $flags & self::__MOVE_CASTLE_SHORT__ ? "f8" : "d8"; $king_sq = "e8"; $king_sq_new = $flags & self::__MOVE_CASTLE_SHORT__ ? "g8" : "c8"; } $king = $board->get_piece_at($king_sq); $rook = $board->get_piece_at($rook_sq); $board->set_piece_at($king_sq, NULL); $board->set_piece_at($king_sq_new, $king); $king->set_current_square($king_sq_new); $king->set_moved(1); $board->set_piece_at($rook_sq, NULL); $board->set_piece_at($rook_sq_new, $rook); $rook->set_current_square($rook_sq_new); $rook->set_moved(1); $move = $movelist->add_move($piece, $sq1, $sq2, $flags); $movenum = $move->get_move_num(); $this->analyzed = 0; $king->_set_firstmoved($movenum); $rook->_set_firstmoved($movenum); } else { $board->set_piece_at($sq1, NULL); $board->set_piece_at($sq2, $piece); $piece->set_current_square($sq2); $piece->set_moved(1); $move = $movelist->add_move($piece, $sq1, $sq2, $flags); $movenum = $move->get_move_num(); $piece->_set_firstmoved($movenum); } } } return $move; }