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;
	}

}
Example #2
0
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;
    }

}