bool Board::move(int cFrom,int rFrom,int cTo,int rTo) { const Cell *cellFrom = this->cellAt(cFrom,rFrom); const Cell *cellTo = this->cellAt(cTo,rTo); if( !cellFrom || !cellTo ) return false; Figure *fig = (Figure*)this->at(cFrom,rFrom); Figure *target = (Figure*)this->at(cTo,rTo); if( !fig || this->onMove != fig->getColor() || !fig->isValid(cellFrom,cellTo,this) ) return false; bool playerUnderAttack = this->isUnderAttack(this->onMove); const Pawn *pwn; const King *king; if( pwn = dynamic_cast<const Pawn *>(fig) ) { // check for pawn special moves if( rTo == 0 || rTo == 7 ) { // promotion } if( cFrom != cTo && !target) { // en passant const Figure *tmp = this->at(cTo,rFrom); this->field[cFrom][rFrom] = NULL; this->field[cTo][rFrom] = NULL; this->field[cTo][rTo] = fig; if( playerUnderAttack && this->isUnderAttack(this->onMove) ) { // did not protect -> undo move this->field[cFrom][rFrom] = this->field[cTo][rTo]; this->field[cTo][rTo] = NULL; this->field[cTo][rFrom] = (Figure*)tmp; return false;// failed en passant } else { this->onMove = (ChessColor)(-1*(int)this->onMove); fig->doMove(); delete tmp; return true; // succesful en passant } } } else if( (king = dynamic_cast<const King *>(fig)) && abs(cFrom-cTo) == 2) {// if move is valid and it is more than 1 space long -> castle // move king this->field[cTo][rTo] = this->field[cFrom][rFrom]; this->field[cFrom][rFrom] = NULL; // move rook if ( cFrom > cTo ) { if ( fig->isWhite() ) { this->field[0][3] = this->field[0][0]; this->field[0][0] = NULL; } else { this->field[7][3] = this->field[0][7]; this->field[7][0] = NULL; } } else { if( fig->isWhite() ) { this->field[0][5] = this->field[0][7]; this->field[0][7] = NULL; } else { this->field[7][5] = this->field[7][7]; this->field[7][7] = NULL; } } this->onMove = (ChessColor)(-1*(int)this->onMove); fig->doMove(); return true; // no need to check for check state as castle is not valid when checked } this->field[cTo][rTo] = fig; this->field[cFrom][rFrom] = NULL; if( playerUnderAttack && this->isUnderAttack(this->onMove) ) { // did not protect -> undo move this->field[cFrom][rFrom] = fig; this->field[cTo][rTo] = target; return false; } else { this->onMove = (ChessColor)(-1*(int)this->onMove); fig->doMove(); return true; } }
bool Board::move(int cFrom,int rFrom,int cTo,int rTo) { if( cFrom < 0 || cFrom >= Board::_bSize || rFrom < 0 || rFrom >= Board::_bSize || cTo < 0 || cTo >= Board::_bSize || rTo < 0 || rTo > Board::_bSize) return false; const Cell *cellFrom = this->cellAt(cFrom,rFrom); const Cell *cellTo = this->cellAt(cTo,rTo); if( !cellFrom || !cellTo ) return false; Figure *fig = this->field[cFrom][rFrom]; Figure *target = this->field[cTo][rTo]; if( !fig || this->onMove != fig->getColor() || !fig->isValid(cellFrom,cellTo,this) ) return false; const Pawn *pwn; const King *king; if( pwn = dynamic_cast<const Pawn *>(fig) ) { // check for pawn special moves if( rTo == 0 || rTo == 7 ) { // promotion Figure *prom; if(false && this->getPromotionPick ) prom = this->getPromotionPick(this); else prom = new Queen(this->onMove); Figure *tmp = this->field[cTo][rTo]; this->field[cFrom][rFrom] = NULL; this->field[cTo][rTo] = prom; if( this->isUnderAttack(this->onMove) ) { // can't move into check this->field[cFrom][rFrom] = fig; this->field[cTo][rTo] = tmp; delete prom; return false; } else { delete fig; delete tmp; this->onMove = Board::flipColor(this->onMove); return true; } } if( cFrom != cTo && !target) { // en passant const Figure *tmp = this->at(cTo,rFrom); this->field[cFrom][rFrom] = NULL; this->field[cTo][rFrom] = NULL; this->field[cTo][rTo] = fig; if( this->isUnderAttack(this->onMove) ) { // can't move into check this->field[cFrom][rFrom] = this->field[cTo][rTo]; this->field[cTo][rTo] = NULL; this->field[cTo][rFrom] = (Figure*)tmp; return false;// failed en passant } else { this->onMove = Board::flipColor(this->onMove); fig->doMove(); delete tmp; return true; // succesful en passant } } } else if( (king = dynamic_cast<const King *>(fig)) && std::abs(cFrom-cTo) == 2) {// if move is valid and it is more than 1 space long -> castle // move king this->field[cTo][rTo] = this->field[cFrom][rFrom]; this->field[cFrom][rFrom] = NULL; // move rook int mv = cFrom < cTo ? -1 : 1; int rookCol = mv == 1 ? 0 : 7; this->field[cFrom - mv][rFrom] = this->field[rookCol][rFrom]; this->field[rookCol][rFrom] = NULL; this->onMove = Board::flipColor(this->onMove); fig->doMove(); return true; // no need to check for check state as castle is not valid when checked } this->field[cTo][rTo] = fig; this->field[cFrom][rFrom] = NULL; if( this->isUnderAttack(this->onMove) ) { // can't move and become attacked this->field[cFrom][rFrom] = fig; this->field[cTo][rTo] = target; return false; } else { this->onMove = Board::flipColor(this->onMove); fig->doMove(); return true; } }