function reachable_squares() { #Array of square where the piece can move to $squares = array(); $csq = $this->get_current_square(); $tsq = Board::add_vert_distance($csq, 2); if ($tsq) { $sq = Board::square_right_of($tsq); if ($sq) { $squares[] = $sq; } $sq = Board::square_left_of($tsq); if ($sq) { $squares[] = $sq; } } $tsq = Board::add_vert_distance($csq, -2); if ($tsq) { $sq = Board::square_right_of($tsq); if ($sq) { $squares[] = $sq; } $sq = Board::square_left_of($tsq); if ($sq) { $squares[] = $sq; } } $tsq = Board::add_horz_distance($csq, 2); if ($tsq) { $sq = Board::square_up_from($tsq); if ($sq) { $squares[] = $sq; } $sq = Board::square_down_from($tsq); if ($sq) { $squares[] = $sq; } } $tsq = Board::add_horz_distance($csq, -2); if ($tsq) { $sq = Board::square_up_from($tsq); if ($sq) { $squares[] = $sq; } $sq = Board::square_down_from($tsq); if ($sq) { $squares[] = $sq; } } return $squares; }
function reachable_squares() { #Array of square where the piece can move to $squares = array(); $csq = $this->get_current_square(); $sq1 = Board::square_left_of($csq); if ($sq1) { $squares[] = $sq1; $sq2 = Board::square_up_from($sq1); if (defined($sq2)) { $squares[] = $sq2; } $sq2 = Board::square_down_from($sq1); if (defined($sq2)) { $squares[] = $sq2; } } $sq1 = Board::square_right_of($csq); if ($sq1) { $squares[] = $sq1; $sq2 = Board::square_up_from($sq1); if ($sq2) { $squares[] = $sq2; } $sq2 = Board::square_down_from($sq1); if ($sq2) { $squares[] = $sq2; } } $sq1 = Board::square_up_from($csq); if ($sq1) { $squares[] = $sq1; } $sq1 = Board::square_down_from($csq); if ($sq1) { $squares[] = $sq1; } $sq1 = Board::add_horz_distance($csq, 2); if ($sq1 && !$this->moved()) { $squares[] = $sq1; } $sq1 = Board::add_horz_distance($csq, -2); if ($sq1 && !$this->moved()) { $squares[] = $sq1; } return $squares; }
function reachable_squares() { #Array of square where the piece can move to $squares = array(); $color = $this->get_player(); $csq = $this->get_current_square(); if ($color == 'white') { if ($csq) { $tsq1 = Board::square_up_from($csq); } } else { if ($csq) { $tsq1 = Board::square_down_from($csq); } } if (isset($tsq1)) { $squares[] = $tsq1; } if ($color == 'white') { if ($tsq1) { $tsq2 = Board::square_up_from($tsq1); } } else { if ($tsq1) { $tsq2 = Board::square_down_from($tsq1); } } if (!$this->moved() and $tsq2) { $squares[] = $tsq2; } if ($tsq1) { $tsq2 = Board::square_left_of($tsq1); } if ($tsq2) { $squares[] = $tsq2; } if ($tsq1) { $tsq2 = Board::square_right_of($tsq1); } if ($tsq2) { $squares[] = $tsq2; } 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 prior to calling. Returns true * if the provided move is legal within the context of the current game. * * @param string $sq1 current position of the piece * @param string $sq2 destination of the piece * * @return bool true if the move is legal or false otherwise */ public function is_move_legal($sq1, $sq2) { #check squares are on the board if (Board::square_is_valid($sq1) == false) { return false; } if (Board::square_is_valid($sq2) == false) { return false; } $player1 = $this->players[0]; $player2 = $this->players[1]; $board = $this->board; $piece = $board->get_piece_at($sq1); #trying to move invisible piece if ($piece == NULL) { return -1; } $player = $piece->get_player(); $movelist = $this->movelist; $last_moved = $movelist->get_last_moved(); #check whose turn is if ($last_moved != NULL && $last_moved == $player || $last_moved == NULL && $player != $player1) { $this->message = "Not your turn"; return false; } #square not reacheable for this piece if ($piece->can_reach($sq2) == false) { return false; } #if capturing anything $capture = $board->get_piece_at($sq2); if ($capture) { if ($capture->get_player() == $player) { $this->message = "You can't capture your own piece"; return false; } #Pawn try to capture if ($piece instanceof Pawn) { if (abs(Board::horz_distance($sq1, $sq2)) != 1) { $this->message = "Pawns may only capture diagonally"; return false; } } elseif ($piece instanceof King) { if (abs(Board::horz_distance($sq1, $sq2)) >= 2) { $this->message = "You can't capture while castling"; return false; } } } else { #Check "en passant" capture if ($piece instanceof Pawn) { $ml = $piece->movelist; if (Board::horz_distance($sq1, $sq2) != 0 && $this->_is_valid_en_passant($piece, $sq1, $sq2) == false) { $this->message = "Pawns must capture on a diagonal move"; return false; } } } $valid_castle = 0; $clone = clone $this; $king = $clone->kings[$player == $player1 ? 0 : 1]; #Piece is a King if ($piece instanceof King) { $hdist = Board::horz_distance($sq1, $sq2); if (abs($hdist) == 2) { self::_mark_threatened_kings($clone); if ($king->threatened()) { $this->message = "Can't castle out of check"; return false; } if ($hdist > 0) { if ($this->_is_valid_short_castle($piece, $sq1, $sq2) == false) { return false; } $valid_castle = self::__MOVE_CASTLE_SHORT__; } else { if ($this->_is_valid_long_castle($piece, $sq1, $sq2) == false) { return false; } $valid_castle = self::__MOVE_CASTLE_LONG__; } } } elseif (!$piece instanceof King) { $board_c = clone $board; $board_c->set_piece_at($sq1, NULL); $board_c->set_piece_at($sq2, NULL); if ($board_c->line_is_open($sq1, $sq2) == false) { $this->message = "Line '{$sq1}' - '{$sq2}' is blocked"; return false; } } #move is not a castle if (!$valid_castle) { $clone->make_move($sq1, $sq2, false); self::_mark_threatened_kings($clone); if ($king->threatened()) { $this->message = "Move leaves your king in check"; return false; } } else { #Short castle move if ($valid_castle == self::__MOVE_CASTLE_SHORT__) { $tsq = Board::square_right_of($sq1); $clone->make_move($sq1, $tsq, 0); self::_mark_threatened_kings($clone); if ($king->threatened()) { $this->message = "Can't castle through check"; return false; } $clone->make_move($tsq, $sq2, 0); self::_mark_threatened_kings($clone); if ($king->threatened()) { $this->message = "Move leaves your king in check"; return false; } } else { $tsq = Board::square_left_of($sq1); $clone->make_move($sq1, $tsq, 0); self::_mark_threatened_kings($clone); if ($king->threatened()) { $this->message = "Can't castle through check"; return false; } $clone->make_move($tsq, $sq2, 0); self::_mark_threatened_kings($clone); if ($king->threatened()) { die; $this->message = "Move leaves your king in check"; return false; } } } $this->message = ''; return true; }