예제 #1
0
파일: board.c 프로젝트: Glank/chess
move_t ChessBoard_unmakeMove(ChessBoard* self){
    GameInfo* info = (GameInfo*)self->extra;
    assert(info->movesCount!=0);
    move_t move = info->moves[info->movesCount-1];
    BoardBackup* backup = &(info->backups[--(info->movesCount)]);
    int meta = GET_META(move);
    location_t from = GET_FROM(move);
    location_t to = GET_TO(move);
    //unmove the key piece
    __movePieceByLoc(self, to, from);
    //unpromote pawn
    if(meta&PROMOTION_MOVE_FLAG){
        ChessPiece* piece = self->squares[from];
        __removePiece(self, piece);
        piece->type=PAWN;
        __addPiece(self, piece);
    } 
    //uncapture piece
    if(meta&CAPTURE_MOVE_FLAG)
        __uncapturePiece(self);
    //uncastle
    else if(meta==KING_CASTLE_MOVE){
        int rank = GET_RANK(from);
        __movePieceByLoc(self, 
            RANK_FILE(rank, 5), RANK_FILE(rank, 7));
    }
    else if(meta==QUEEN_CASTLE_MOVE){
        int rank = GET_RANK(from);
        __movePieceByLoc(self, 
            RANK_FILE(rank, 3), RANK_FILE(rank, 0));
    }
    //restore flags and hash
    self->flags = backup->flags;
    self->hash = backup->hash;
    self->fiftyMoveCount = backup->fiftyMoveCount;
    return move;
}
예제 #2
0
PyObject* PyCOMPSPack_strget_(PyCOMPS_Package *self, void *closure) {
    char *tmp = GET_FROM(self->package, (size_t)closure);
    return PyUnicode_FromString(tmp);
}
예제 #3
0
파일: board.c 프로젝트: Glank/chess
void ChessBoard_makeMove(ChessBoard* self, move_t move){
    //push the move onto the move stack
    GameInfo* info = (GameInfo*)self->extra;
    BoardBackup* backup = &(info->backups[info->movesCount]);
    backup->hash = self->hash;
    backup->flags = self->flags;
    backup->fiftyMoveCount = self->fiftyMoveCount;
    info->moves[info->movesCount++] = move;
    if(self->flags&TO_PLAY_FLAG) //black
        self->fiftyMoveCount++;
    __toggleToPlay(self);
    __clearEnPassantFlags(self);
    int meta = GET_META(move);
    location_t from = GET_FROM(move);
    location_t to = GET_TO(move);
    if((self->squares[from]->type==PAWN) || (meta&CAPTURE_MOVE_FLAG))
        self->fiftyMoveCount=0;
    int rank, file;
    //do special moves
    switch(meta){
    case DOUBLE_PAWN_PUSH_MOVE:
        __setEnPassantFlags(self, GET_FILE(to));
        break;
    case KING_CASTLE_MOVE:
    case QUEEN_CASTLE_MOVE:
        rank = GET_RANK(from);
        if(meta==KING_CASTLE_MOVE)
            __movePieceByLoc(self, 
                RANK_FILE(rank, 7), RANK_FILE(rank, 5));
        else
            __movePieceByLoc(self, 
                RANK_FILE(rank, 0), RANK_FILE(rank, 3));
        if(rank==0){//white
            __unsetCastleFlag(self, WHITE_KING_CASTLE_FLAG);
            __unsetCastleFlag(self, WHITE_QUEEN_CASTLE_FLAG);
        }
        else{//black
            __unsetCastleFlag(self, BLACK_KING_CASTLE_FLAG);
            __unsetCastleFlag(self, BLACK_QUEEN_CASTLE_FLAG);
        }
        break;
    case EN_PASSANT_MOVE:
        rank = GET_RANK(from);
        file = GET_FILE(to);
        __capturePiece(self, 
            self->squares[RANK_FILE(rank,file)]);
        break;
    default:
        if(meta&CAPTURE_MOVE_FLAG){
            ChessPiece* captured = self->squares[to];
            __capturePiece(self, captured);
            if(captured->type==ROOK){
                switch(to){
                case WHITE_QUEEN_ROOK_START:
                    __unsetCastleFlag(self, WHITE_QUEEN_CASTLE_FLAG);
                    break;
                case WHITE_KING_ROOK_START:
                    __unsetCastleFlag(self, WHITE_KING_CASTLE_FLAG);
                    break;
                case BLACK_QUEEN_ROOK_START:
                    __unsetCastleFlag(self, BLACK_QUEEN_CASTLE_FLAG);
                    break;
                case BLACK_KING_ROOK_START:
                    __unsetCastleFlag(self, BLACK_KING_CASTLE_FLAG);
                    break;
                }
            }
        }
        if(meta&PROMOTION_MOVE_FLAG){
            ChessPiece* piece = self->squares[from];
            __removePiece(self, piece);
            switch(meta&PROMOTION_MASK){
            case QUEEN_PROMOTION:
                piece->type=QUEEN;
                break;
            case ROOK_PROMOTION:
                piece->type=ROOK;
                break;
            case KNIGHT_PROMOTION:
                piece->type=KNIGHT;
                break;
            case BISHOP_PROMOTION:
                piece->type=BISHOP;
                break;
            default:
                assert(0);
            }
            __addPiece(self, piece);
        }
    }
    if(meta==0 || meta==CAPTURE_MOVE_FLAG){
        switch(from){
        case WHITE_QUEEN_ROOK_START:
            __unsetCastleFlag(self, WHITE_QUEEN_CASTLE_FLAG);
            break;
        case WHITE_KING_ROOK_START:
            __unsetCastleFlag(self, WHITE_KING_CASTLE_FLAG);
            break;
        case WHITE_KING_START:
            __unsetCastleFlag(self, WHITE_QUEEN_CASTLE_FLAG);
            __unsetCastleFlag(self, WHITE_KING_CASTLE_FLAG);
            break;
        case BLACK_QUEEN_ROOK_START:
            __unsetCastleFlag(self, BLACK_QUEEN_CASTLE_FLAG);
            break;
        case BLACK_KING_ROOK_START:
            __unsetCastleFlag(self, BLACK_KING_CASTLE_FLAG);
            break;
        case BLACK_KING_START:
            __unsetCastleFlag(self, BLACK_QUEEN_CASTLE_FLAG);
            __unsetCastleFlag(self, BLACK_KING_CASTLE_FLAG);
            break;
        }
    }
    __movePieceByLoc(self, from, to);
}
예제 #4
0
파일: narrator.c 프로젝트: Glank/chess
void toAlgebraicNotation(move_t move, ChessBoard* board, char* out, int* outSize){
    location_t from = GET_FROM(move);
    location_t to = GET_TO(move);
    int meta = GET_META(move);
    int i = 0;
    ChessBoard_makeMove(board, move);
    int isInCheck = ChessBoard_testForCheck(board);
    ChessMoveGenerator* gen = ChessMoveGenerator_new(board);
    ChessMoveGenerator_generateMoves(gen, isInCheck, NULL);
    int isInCheckmate = isInCheck&&(gen->nextCount==0);
    ChessBoard_unmakeMove(board);
    ChessMoveGenerator_generateMoves(gen, ChessBoard_testForCheck(board), NULL);

    if(meta==KING_CASTLE_MOVE){
        char* notation = "O-O";
        for(i = 0; i < 3; i++)
            out[i] = notation[i];
    }
    else if(meta==QUEEN_CASTLE_MOVE){
        char* notation = "O-O-O";
        for(i = 0; i < 5; i++)
            out[i] = notation[i];
    }
    else{
        //write piece indicator
        ChessPiece* piece = board->squares[from];
        if(piece->type==KING)
            out[i++] = 'K';
        else{
            //for each other move,
            //check to see if there are multiple pieces
            //of this piece's type that can move to the 'to' square.
            int j;
            move_t otherMoves[20];
            int otherMovesCount = 0;
            move_t otherMove;
            for(j = 0; j < gen->nextCount; j++){
                otherMove = gen->next[j];
                if((GET_TO(otherMove)==to) && 
                    (GET_FROM(otherMove)!=from) &&
                    (board->squares[GET_FROM(otherMove)]->type==
                    piece->type)){
                    if(piece->type==PAWN &&
                        (move&CAPTURE_MOVE_FLAG)!=
                        (otherMove&CAPTURE_MOVE_FLAG))
                        continue;
                    if(otherMove==move)
                        continue;
                    otherMoves[otherMovesCount++] = otherMove;
                }
            }
            //note if there are multiple moves 
            //from the same rank or file
            int sameRank = 0, sameFile = 0;
            for(j = 0; j < otherMovesCount; j++){
                otherMove = otherMoves[j];
                if(GET_RANK(from)==GET_RANK(GET_FROM(otherMove)))
                    sameRank = 1;
                if(GET_FILE(from)==GET_FILE(GET_FROM(otherMove)))
                    sameFile = 1;
            }
            
            if(piece->type!=PAWN)
                out[i++] = __pieceTypeToChar(piece->type);
            else if(meta&CAPTURE_MOVE_FLAG)
                out[i++] = __fileToChar(GET_FILE(from));
            if(piece->type!=PAWN && otherMovesCount){
                if(!sameFile)
                    out[i++] = __fileToChar(GET_FILE(from));
                else if(!sameRank)
                    out[i++] = __rankToChar(GET_RANK(from));
                else{
                    out[i++] = __fileToChar(GET_FILE(from));
                    out[i++] = __rankToChar(GET_RANK(from));
                }
            }
        }
        //if capture
        if(meta&CAPTURE_MOVE_FLAG)
            out[i++] = 'x';
        //write destination
        out[i++] = __fileToChar(GET_FILE(to));
        out[i++] = __rankToChar(GET_RANK(to));
        if(meta&PROMOTION_MOVE_FLAG){
            out[i++] = '=';
            switch(meta&PROMOTION_MASK){
                case KNIGHT_PROMOTION:
                    out[i++] = 'N';
                    break;
                case BISHOP_PROMOTION:
                    out[i++] = 'B';
                    break;
                case ROOK_PROMOTION:
                    out[i++] = 'R';
                    break;
                case QUEEN_PROMOTION:
                    out[i++] = 'Q';
                    break;
                default:
                    assert(0);
            }
        }
    }
    if(isInCheckmate)
        out[i++] = '#';
    else if(isInCheck)
        out[i++] = '+';
    out[i] = '\0';
    (*outSize) = i;

    ChessMoveGenerator_delete(gen);
}