void Zoltan_Free (void **ptr, char *filename, int lineno) { struct malloc_debug_data *dbptr; /* loops through debug list */ struct malloc_debug_data **prev; /* holds previous pointer */ int proc; /* processor ID */ #ifdef REALLOC_BUG double *p=NULL; #endif /* * This version of free calls the system's free function. It doesn't call * free if ptr is the NULL pointer. */ if (ptr == NULL || *ptr == NULL) return; nfree++; if (DEBUG_MEMORY > 1) { /* Remove allocation of list of active allocations */ prev = ⊤ for (dbptr = top; dbptr != NULL && (void *) (dbptr->ptr) != *ptr; dbptr = dbptr->next) { prev = &(dbptr->next); } if (dbptr == NULL) { GET_RANK(&proc); fprintf(stderr, "Proc %d: Memory error: In free, address (0x%lx) " "not found in debug list. File=%s, line=%d.\n", proc, (long) *ptr, filename, lineno); } else { *prev = dbptr->next; bytes_used -= dbptr->size; free((char *) dbptr); if (DEBUG_MEMORY > 2){ GET_RANK(&proc); fprintf(stderr, "Proc %d: free, address (0x%lx) " "File=%s, line=%d.\n", proc, (long) *ptr, filename, lineno); } } } #ifdef REALLOC_BUG p = (double *)*ptr; free(p-1); #else free(*ptr); #endif /* Set value of ptr to NULL, to flag further references to it. */ *ptr = NULL; } /* Zoltan_Free */
//Returns pawn evaluation score int Get_Pawn_Eval_Score(BOARD_STRUCT *board) { int sq64; int score = 0; int hash_score = 0; const U64 white_pawns = board->piece_bitboards[wP]; const U64 black_pawns = board->piece_bitboards[bP]; const U64 all_pawns = white_pawns | black_pawns; //White pawns U64 temp = white_pawns; while(temp) //loop through all white pawns { sq64 = pop_1st_bit(&temp); //pawn location in 64 square array //if no black pawns in passed mask area if ((black_pawns & white_passed_masks[sq64]) == 0) { score += passed_pawn_rank_bonus[GET_RANK(sq64)]; //If protected by king if (king_attack_masks[sq64] & board->piece_bitboards[wK]) score += PROTECTED_PASSER_SCORE; } //if no white pawns in isolated mask area if ((white_pawns & isolated_masks[sq64]) == 0) score += ISOLATED_PAWN_PENALTY; //If a white pawn is found in the same file if ((white_pawns & doubled_masks[sq64]) != 0) score += DOUBLED_PAWN_PENALTY; } //Black pawns temp = black_pawns; while (temp) //loop through all black pawns { sq64 = pop_1st_bit(&temp); //pawn location in 64 square array //if no white pawns in passed mask area if ((white_pawns & black_passed_masks[sq64]) == 0) { score -= passed_pawn_rank_bonus[RANK_8 - GET_RANK(sq64)]; //If protected by king if (king_attack_masks[sq64] & board->piece_bitboards[bK]) score -= PROTECTED_PASSER_SCORE; } //if no black pawns in isolated mask area if ((black_pawns & isolated_masks[sq64]) == 0) score -= ISOLATED_PAWN_PENALTY; //If a black pawn is found in the same file if ((black_pawns & doubled_masks[sq64]) != 0) score -= DOUBLED_PAWN_PENALTY; } return score; }
double *Zoltan_Realloc(void *ptr, int n, char *filename, int lineno) { char *yo = "Zoltan_Realloc"; struct malloc_debug_data *dbptr; /* loops through debug list */ int proc; /* processor ID */ double *p; /* returned pointer */ if (ptr == NULL) { /* Previous allocation not important */ if (n == 0) { p = NULL; } else { p = Zoltan_Malloc(n, filename, lineno); } } else { if (n == 0) { Zoltan_Free((void **) &ptr, filename, lineno); p = NULL; } else { p = (double *) realloc((char *) ptr, n); if (DEBUG_MEMORY > 1) { /* Need to replace item in allocation list */ for (dbptr = top; dbptr != NULL && (void *) (dbptr->ptr) != ptr; dbptr = dbptr->next); if (dbptr == NULL) { /* previous allocation not found in list. */ GET_RANK(&proc); fprintf(stderr, "Proc %d: Memory error: " "In realloc, address not found in debug list (%p)\n", proc, ptr); } else { /* Update entry in allocation list */ bytes_used += (n - dbptr->size); dbptr->size = n; dbptr->ptr = p; if (bytes_used > bytes_max) { bytes_max = bytes_used; } } } if (p == NULL) { GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) No space on proc %d - " "number of bytes requested = %d\n", yo, filename, lineno, proc, n); } } } return (p); } /* Zoltan_Realloc */
int __generateSimpleMove(ChessMoveGenerator* self, ChessPiece* piece, int dRank, int dFile, int validate){ //returns 1 if the move was succesfull, //0 if it failed because of check, //and -1 if it failed because it was out of bounds/blocked ChessPiece* capture; int rank, file; location_t to; move_t move; rank = GET_RANK(piece->location)+dRank; file = GET_FILE(piece->location)+dFile; //if the move is in the board (0<=rank<8)&&(0<=file<8) if(((rank&7)==rank) && ((file&7)==file)){ to = RANK_FILE(rank,file); move = NEW_MOVE(piece->location, to); capture = self->board->squares[to]; if((capture!=NULL) && ((capture->color) != (self->toPlay))) move|=CAPTURE_MOVE_FLAG; else if(capture!=NULL) return -1; //the same color ChessBoard_makeMove(self->board, move); if(__finalizeAndUndo(self, validate)) return 1; else return 0; } return -1; }
char __getChar(ChessBoard* self, location_t loc){ assert(self!=NULL); assert(0<=loc); assert(loc<64); ChessPiece* piece = self->squares[loc]; if(piece==NULL) return ((GET_RANK(loc)^GET_FILE(loc))%2)?' ':'+'; return __getPieceChar(piece); }
void __generatePawnMoves(ChessMoveGenerator* self){ int i, rank, file; assert(self!=NULL); assert(self->curSet!=NULL); int size = self->curSet->piecesCounts[PAWN_INDEX]; int pawnDirection = self->toPlay==WHITE?1:-1; int pawnHomeRank = self->toPlay==WHITE?1:6; int lastRank = self->toPlay==WHITE?6:1; ChessPiece* pawn; move_t move; location_t to; //since the order of the pawns might change in the set //durring operations, we must store a local copy ChessPiece** pawns = (ChessPiece**)malloc( sizeof(ChessPiece*)*size); memcpy(pawns, self->curSet->piecesByType[PAWN_INDEX], sizeof(ChessPiece*)*size); for(i=0;i<size;i++){ pawn = pawns[i]; rank = GET_RANK(pawn->location); file = GET_FILE(pawn->location); //try to move forward to = RANK_FILE(rank+pawnDirection, file); if(self->board->squares[to]==NULL){ move = NEW_MOVE(pawn->location,to); if(rank==lastRank){ //generate promotions __generatePawnPromotions(self, move); } else{ //generate regular forward push ChessBoard_makeMove(self->board, move); if((__finalizeAndUndo(self, 1)||self->inCheck) && pawnHomeRank==rank){ to = RANK_FILE(rank+pawnDirection*2, file); if(self->board->squares[to]==NULL){ move = NEW_MOVE(pawn->location,to); move|=DOUBLE_PAWN_PUSH_MOVE; ChessBoard_makeMove(self->board, move); __finalizeAndUndo(self, self->inCheck); } } } } if(file>0){//try to capture left __generatePawnCapture(self, rank, file, pawnDirection, -1, lastRank); } if(file<7){//try to capture right __generatePawnCapture(self, rank, file, pawnDirection, 1, lastRank); } }//end for free(pawns); }
//Initializes pawn eval masks void Init_Pawn_Masks(void) { int index,rank,file,rank_index,file_index; //Clear all masks; for (index = 0; index < 64; index++) { white_passed_masks[index] = 0; black_passed_masks[index] = 0; isolated_masks[index] = 0; doubled_masks[index] = 0; } //For each square on the board for (index = 0; index < 64; index++) { rank = GET_RANK(index); file = GET_FILE(index); for (rank_index = RANK_1; rank_index <= RANK_8; rank_index++) { for (file_index = FILE_A; file_index <= FILE_H; file_index++) { //white passed mask //If file is neighboring and space is above index if (abs(file - file_index) <= 1 && rank_index > rank) { SET_BIT(white_passed_masks[index], RANK_FILE_TO_SQUARE(rank_index, file_index)); } //black passed mask //If file is neighboring and space is below index if (abs(file - file_index) <= 1 && rank_index < rank) { SET_BIT(black_passed_masks[index], RANK_FILE_TO_SQUARE(rank_index, file_index)); } //isolated mask //If file is neighboring and space is not equal to index if (abs(file - file_index) <= 1 && (file != file_index || rank != rank_index)) { SET_BIT(isolated_masks[index], RANK_FILE_TO_SQUARE(rank_index, file_index)); } //Doubled mask //If file is the same and rank is different if (file == file_index && rank != rank_index) { SET_BIT(doubled_masks[index], RANK_FILE_TO_SQUARE(rank_index, file_index)); } } } } }
void Zoltan_Memory_Stats() { struct malloc_debug_data *dbptr; /* loops through debug list */ int proc; /* processor ID */ if (DEBUG_MEMORY == 1) { GET_RANK(&proc); fprintf(stderr, "Proc %d: Calls to malloc = %d, Calls to free = %d\n", proc, nmalloc, nfree); if (nmalloc > nfree) fprintf(stderr, "Proc %d: Possible memory error: " "# malloc > # free.\n", proc); else if (nfree > nmalloc) fprintf(stderr, "Proc %d: Possible memory error: " "# free > # malloc.\n", proc); } else if (DEBUG_MEMORY > 1) { GET_RANK(&proc); fprintf(stderr, "Proc %d: Calls to malloc = %d, Calls to free = %d, " "Max bytes = %lu, total bytes = %lu\n", proc, nmalloc, nfree, (unsigned long) bytes_max, (unsigned long) bytes_used); if (nmalloc > nfree) fprintf(stderr, "Proc %d: Possible memory error: " "# malloc > # free.\n", proc); else if (nfree > nmalloc) fprintf(stderr, "Proc %d: Possible memory error: " "# free > # malloc.\n", proc); if (top != NULL) { fprintf(stderr, "Proc %d: Remaining allocations:\n", proc); for (dbptr = top; dbptr != NULL; dbptr = dbptr->next) { fprintf(stderr, " order=%d, size=%lu, location=0x%lx, " "file=%s, line=%d\n", dbptr->order, (unsigned long) (dbptr->size), (long) dbptr->ptr, dbptr->file, dbptr->line); } } } } /* Zoltan_Memory_Stats */
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; }
void __generateDirectionalMoves(ChessMoveGenerator* self, ChessPiece* piece, int dRank, int dFile){ ChessPiece* capture; int rank, file; rank = GET_RANK(piece->location)+dRank; file = GET_FILE(piece->location)+dFile; int validated = 0; location_t to; move_t move; //while inside the board (0<=rank<8 && 0<=file<8) while(((rank&7)==rank) && ((file&7)==file)){ to = RANK_FILE(rank,file); capture = self->board->squares[to]; if(capture==NULL){ move = NEW_MOVE(piece->location, to); ChessBoard_makeMove(self->board, move); if(__finalizeAndUndo(self, (!validated)||self->inCheck)){ if(self->inCheck) break; //move blocks some directional check, //any further move in this direction //will not. validated = 1; } else if(!self->inCheck){ break; //move puts you in check, any move in //this direction will also put you in check } } else if(capture->color != self->toPlay){ move = NEW_MOVE(piece->location, to)|CAPTURE_MOVE_FLAG; ChessBoard_makeMove(self->board, move); __finalizeAndUndo(self, self->inCheck||(!validated)); break; } else break; //you hit your own piece rank+=dRank; file+=dFile; } }
void alltoall(int len) { int cc; int i, n; int m; fd_set wfds, rfds; struct request send_req; send_req.rank = comm_rank; send_req.len = len; for (i = 0; i < comm_size; i++) { if (i != comm_rank) { recv_req[i].count = 0; } else { recv_req[i].count = len; } } for (n = 0; n < comm_size - 1; n++) { /* send phase */ send_req.rank = GET_RANK(send_req.rank + 1); send_req.fd = hosts[send_req.rank].sock; send_req.count = 0; send_handler(&send_req); assert(send_req.rank != comm_rank); for (;;) { int nsel = 0; m = -1; FD_ZERO(&wfds); FD_ZERO(&rfds); if (send_req.count != send_req.len) { FD_SET(send_req.fd, &wfds); m = MAX(m, send_req.fd); nsel++; } else { if (n + 1 != comm_size - 1) break; /* We have another pending send requests. */ } for (i = 0; i < comm_size; i++) { if (recv_req[i].count == recv_req[i].len) continue; FD_SET(recv_req[i].fd, &rfds); m = MAX(m, recv_req[i].fd); nsel++; } if (nsel == 0) break; cc = select(m + 1, &rfds, &wfds, NULL, NULL); nr_select++; if (cc < 0) perror_exit("select", 1); for (i = 0; i < comm_size; i++) { if (recv_req[i].count == recv_req[i].len) continue; if (FD_ISSET(recv_req[i].fd, &rfds)) recv_handler(&recv_req[i]); } if (FD_ISSET(send_req.fd, &wfds)) send_handler(&send_req); } } }
double *Zoltan_Realloc(void *ptr, size_t n, char *filename, int lineno) { char *yo = "Zoltan_Realloc"; struct malloc_debug_data *dbptr; /* loops through debug list */ int proc; /* processor ID */ double *p; /* returned pointer */ #ifdef REALLOC_BUG int n_old; #endif if (ptr == NULL) { /* Previous allocation not important */ if (n == 0) { p = NULL; } else { p = Zoltan_Malloc(n, filename, lineno); } } else { if (n == 0) { Zoltan_Free((void **) &ptr, filename, lineno); p = NULL; } else { #ifdef REALLOC_BUG /* Feb 10, 2010: Several platforms show a realloc bug where realloc * either fails to allocate memory when there is sufficient memory * or it crashes. If realloc shows this failure, then build Zoltan * with REALLOC_BUG, and we will call malloc/memcpy/free instead. */ p = (double *)ptr; p--; n_old = p[0]; if ((n_old < 1) || (n_old > max_alloc)){ /* sanity check */ GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) Zoltan_Realloc called on a pointer " "that was not returned by Zoltan_Malloc (proc %d)\n", yo, filename, lineno, proc); return NULL; } p = (double *) Zoltan_Malloc(n, filename, lineno); if (p){ if (n > n_old){ memcpy(p, ptr, n_old); } else if (n <= n_old){ memcpy(p, ptr, n); } Zoltan_Free((void **) &ptr, filename, lineno); } #else p = (double *) realloc((char *) ptr, n); if (DEBUG_MEMORY > 1) { /* Need to replace item in allocation list */ for (dbptr = top; dbptr != NULL && (void *) (dbptr->ptr) != ptr; dbptr = dbptr->next); if (dbptr == NULL) { /* previous allocation not found in list. */ GET_RANK(&proc); fprintf(stderr, "Proc %d: Memory error: " "In realloc, address not found in debug list (0x%lx)\n", proc, (long) ptr); } else { /* Update entry in allocation list */ bytes_used += (n - dbptr->size); dbptr->size = n; dbptr->ptr = p; if (bytes_used > bytes_max) { bytes_max = bytes_used; } } } if (p == NULL) { GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) No space on proc %d - " "number of bytes requested = %lu\n", yo, filename, lineno, proc, (unsigned long) n); } #endif } } return (p); } /* Zoltan_Realloc */
double *Zoltan_Malloc(size_t n, char *filename, int lineno) { char *yo = "Zoltan_Malloc"; struct malloc_debug_data *new_ptr; /* data structure for malloc data */ int proc; /* processor ID for debugging msg */ double *pntr; /* return value */ char *basefile; if (n > 0) { #ifdef REALLOC_BUG if (n > max_alloc){ max_alloc = n; } n += sizeof(double); #endif pntr = (double *) malloc(n); if (pntr == NULL) { GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) No space on proc %d - number of bytes " "requested = %lu\n", yo, filename, lineno, proc, (unsigned long) n); return ((double *) NULL); } nmalloc++; #ifdef REALLOC_BUG pntr[0] = (double)(n - sizeof(double)); ++pntr; #endif } else if (n == 0) pntr = NULL; else { /* n < 0 */ GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) ERROR on proc %d: " "Negative malloc argument. (%lu)\n", yo, filename, lineno, proc, (unsigned long) n); return ((double *) NULL); } if (DEBUG_MEMORY > 1 && pntr != NULL) { /* Add allocation to linked list of active allocations. */ new_ptr = (struct malloc_debug_data *) malloc(sizeof(struct malloc_debug_data)); if (new_ptr == NULL) { GET_RANK(&proc); fprintf(stderr, "WARNING: No space on proc %d for malloc_debug %lu.\n", proc, (unsigned long) n); return (pntr); } new_ptr->order = nmalloc; new_ptr->size = n; new_ptr->ptr = pntr; #ifdef SHORT_FILE basefile = strrchr(filename, '/'); basefile = ((basefile != NULL)?basefile:filename-1)+1; #else basefile = filename; #endif /* SHORT_FILE */ strncpy(new_ptr->file, basefile, MAX_STRING_LEN); new_ptr->line = lineno; new_ptr->next = top; top = new_ptr; bytes_used += n; if (bytes_used > bytes_max) { bytes_max = bytes_used; } } if (DEBUG_MEMORY > 2) { /* Print out details of allocation. */ GET_RANK(&proc); fprintf(stderr, "Proc %d: order=%d, size=%lu, location=0x%lx, " "file=%s, line=%d\n", proc, nmalloc, (unsigned long) n, (long) pntr, filename, lineno); } return pntr; } /* Zoltan_Malloc */
int __testForCheck(ChessBoard* board, color_e color){ GameInfo* info = (GameInfo*)board->extra; ChessPieceSet* pieces = info->pieceSets[color]; ChessPieceSet* opPieces = info->pieceSets[OTHER_COLOR(color)]; ChessPiece* king = pieces->piecesByType[TYPE_TO_INT(KING)][0]; int kingRank, kingFile; kingRank = GET_RANK(king->location); kingFile = GET_FILE(king->location); //test for check by a pawn if((color==WHITE && kingRank<6) || (color==BLACK && kingRank>1)){ int opPawnDirection = color==WHITE?-1:1; int pawnRank = kingRank-opPawnDirection; ChessPiece* pawn; if(kingFile>0){ pawn = board->squares[RANK_FILE(pawnRank, kingFile-1)]; if((pawn!=NULL) && (pawn->type==PAWN) && (pawn->color!=color)){ return 1; } } if(kingFile<7){ pawn = board->squares[RANK_FILE(pawnRank, kingFile+1)]; if((pawn!=NULL) && (pawn->type==PAWN) && (pawn->color!=color)){ return 1; } } } //test for check by knight int i, rankDelta, fileDelta, rank, file; int size = opPieces->piecesCounts[KNIGHT_INDEX]; ChessPiece* knight; for(i=0; i<size; i++){ knight = opPieces->piecesByType[KNIGHT_INDEX][i]; rankDelta = kingRank-GET_RANK(knight->location); fileDelta = kingFile-GET_FILE(knight->location); if((rankDelta*rankDelta+fileDelta*fileDelta)==5) return 1; } //test for check by bishop size = opPieces->piecesCounts[BISHOP_INDEX]; ChessPiece* bishop; for(i=0; i<size; i++){ bishop = opPieces->piecesByType[BISHOP_INDEX][i]; rankDelta = kingRank-GET_RANK(bishop->location); fileDelta = kingFile-GET_FILE(bishop->location); if(rankDelta*rankDelta == fileDelta*fileDelta){ //the king is on a diagonal with this opposing bishop //check every square inbetween to see if the bishop //is blocked assert(rankDelta!=0); rankDelta = rankDelta>0?1:-1; fileDelta = fileDelta>0?1:-1; rank = GET_RANK(bishop->location)+rankDelta; file = GET_FILE(bishop->location)+fileDelta; while(rank!=kingRank){ if(board->squares[RANK_FILE(rank,file)]!=NULL) break; rank+=rankDelta; file+=fileDelta; } if(rank==kingRank) return 1; } } //test for check by rook size = opPieces->piecesCounts[TYPE_TO_INT(ROOK)]; ChessPiece* rook; for(i=0; i<size; i++){ rook = opPieces->piecesByType[TYPE_TO_INT(ROOK)][i]; rankDelta = kingRank-GET_RANK(rook->location); fileDelta = kingFile-GET_FILE(rook->location); if((rankDelta == 0)||(fileDelta == 0)){ //the king is on a rank or a file with this opposing rook //check every square inbetween to see if the rook //is blocked if(fileDelta!=0) fileDelta = fileDelta>0?1:-1; if(rankDelta!=0) rankDelta = rankDelta>0?1:-1; rank = GET_RANK(rook->location)+rankDelta; file = GET_FILE(rook->location)+fileDelta; while(rank!=kingRank || file!=kingFile){ if(board->squares[RANK_FILE(rank,file)]!=NULL) break; rank+=rankDelta; file+=fileDelta; } if(rank==kingRank && file==kingFile){ return 1; } } } //test for check by queen size = opPieces->piecesCounts[TYPE_TO_INT(QUEEN)]; ChessPiece* queen; for(i=0; i<size; i++){ queen = opPieces->piecesByType[TYPE_TO_INT(QUEEN)][i]; rankDelta = kingRank-GET_RANK(queen->location); fileDelta = kingFile-GET_FILE(queen->location); if((rankDelta*rankDelta == fileDelta*fileDelta)|| (rankDelta == 0)||(fileDelta == 0)){ //the king is on a diagonal, rank or file with //this opposing queen, check every square //inbetween to see if the queen is blocked if(fileDelta!=0) fileDelta = fileDelta>0?1:-1; if(rankDelta!=0) rankDelta = rankDelta>0?1:-1; rank = GET_RANK(queen->location)+rankDelta; file = GET_FILE(queen->location)+fileDelta; while(rank!=kingRank || file!=kingFile){ if(board->squares[RANK_FILE(rank,file)]!=NULL){ break; } rank+=rankDelta; file+=fileDelta; } if(rank==kingRank && file==kingFile){ return 1; } } } //test for check by other king //for hypothetical moves that are blocked //by the opposing king ChessPiece* opKing = opPieces->piecesByType[TYPE_TO_INT(KING)][0]; rankDelta = kingRank-GET_RANK(opKing->location); fileDelta = kingFile-GET_FILE(opKing->location); if((rankDelta*rankDelta+fileDelta*fileDelta)<=2){ return 1; } //Otherwise, the king is not in check return 0; }
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); }
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); }
//Looks at pawn shielding around each king and returns white - black score int Get_King_Safety_Score(BOARD_STRUCT *board) { int white_score = 0; int black_score = 0; U64 temp = board->piece_bitboards[wK]; int white_king_square = pop_1st_bit(&temp); temp = board->piece_bitboards[bK]; int black_king_square = pop_1st_bit(&temp); //White king on kingside if (GET_FILE(white_king_square) > FILE_E && GET_RANK(white_king_square) == RANK_1) { if (board->board_array[F2] == wP) white_score += PAWN_SHIELD_SCORE; else if (board->board_array[F3] == wP) white_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[G2] == wP) white_score += PAWN_SHIELD_SCORE; else if (board->board_array[G3] == wP) white_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[H2] == wP) white_score += PAWN_SHIELD_SCORE; else if (board->board_array[H3] == wP) white_score += PAWN_SHIELD_SCORE / 2; } else if (GET_FILE(white_king_square) < FILE_D && GET_RANK(white_king_square) == RANK_1) { if (board->board_array[A2] == wP) white_score += PAWN_SHIELD_SCORE; else if (board->board_array[A3] == wP) white_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[B2] == wP) white_score += PAWN_SHIELD_SCORE; else if (board->board_array[B3] == wP) white_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[C2] == wP) white_score += PAWN_SHIELD_SCORE; else if (board->board_array[C3] == wP) white_score += PAWN_SHIELD_SCORE / 2; } //Black king on kingside if (GET_FILE(black_king_square) > FILE_E && GET_RANK(black_king_square) == RANK_8) { if (board->board_array[F7] == bP) black_score += PAWN_SHIELD_SCORE; else if (board->board_array[F6] == bP) black_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[G7] == bP) black_score += PAWN_SHIELD_SCORE; else if (board->board_array[G6] == bP) black_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[H7] == bP) black_score += PAWN_SHIELD_SCORE; else if (board->board_array[H6] == bP) black_score += PAWN_SHIELD_SCORE / 2; } else if (GET_FILE(black_king_square) < FILE_D && GET_RANK(black_king_square) == RANK_8) { if (board->board_array[A7] == bP) black_score += PAWN_SHIELD_SCORE; else if (board->board_array[A6] == bP) black_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[B7] == bP) black_score += PAWN_SHIELD_SCORE; else if (board->board_array[B6] == bP) black_score += PAWN_SHIELD_SCORE / 2; if (board->board_array[C7] == bP) black_score += PAWN_SHIELD_SCORE; else if (board->board_array[C6] == bP) black_score += PAWN_SHIELD_SCORE / 2; } return white_score - black_score; }
double *Zoltan_Malloc(int n, char *filename, int lineno) { char *yo = "Zoltan_Malloc"; struct malloc_debug_data *new_ptr; /* data structure for malloc data */ int proc; /* processor ID for debugging msg */ double *pntr; /* return value */ if (n > 0) { pntr = (double *) malloc((unsigned) n); if (pntr == NULL) { GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) No space on proc %d - number of bytes " "requested = %d\n", yo, filename, lineno, proc, n); return ((double *) NULL); } nmalloc++; } else if (n == 0) pntr = NULL; else { /* n < 0 */ GET_RANK(&proc); fprintf(stderr, "%s (from %s,%d) ERROR on proc %d: " "Negative malloc argument. (%d)\n", yo, filename, lineno, proc, n); return ((double *) NULL); } if (DEBUG_MEMORY > 1 && pntr != NULL) { /* Add allocation to linked list of active allocations. */ new_ptr = (struct malloc_debug_data *) malloc(sizeof(struct malloc_debug_data)); if (new_ptr == NULL) { GET_RANK(&proc); fprintf(stderr, "WARNING: No space on proc %d for malloc_debug %d.\n", proc, n); return (pntr); } new_ptr->order = nmalloc; new_ptr->size = n; new_ptr->ptr = pntr; strncpy(new_ptr->file, filename, MAX_STRING_LEN); new_ptr->line = lineno; new_ptr->next = top; top = new_ptr; bytes_used += n; if (bytes_used > bytes_max) { bytes_max = bytes_used; } } if (DEBUG_MEMORY > 2) { /* Print out details of allocation. */ GET_RANK(&proc); fprintf(stderr, "Proc %d: order=%d, size=%d, location=%p, " "file=%s, line=%d\n", proc, nmalloc, n, pntr, filename, lineno); } return pntr; } /* Zoltan_Malloc */