void assert_row0(board_t *board, piece_t A, piece_t B, piece_t C, piece_t D) { assert(PIECE(board->b, 0, 0) == A); assert(PIECE(board->b, 1, 0) == B); assert(PIECE(board->b, 2, 0) == C); assert(PIECE(board->b, 3, 0) == D); }
static int square_attacked(board_t *b, int square, int side) { board_t board = *b; move_t move; int i; board.turn = side; /* We add a piece because we only want to take capture moves into consideration. */ board.square[square] = KING + OPPONENT(side); move.destination = square; for (i = 0; i < 64; i++) { if (COLOUR(board.square[i]) == side) { move.source = i; if ((PIECE(board.square[i]) == PAWN) && ((square < 8) || (square >= 56))) move.promotion_piece = QUEEN + side; else move.promotion_piece = NONE; if (move_is_semi_valid(&board, &move)) return 1; } } return 0; }
void move_set_attr(board_t *b, move_t *move) { int check, mated; board_t board = *b; if (move_is_capture(b, move)) move->type = CAPTURE; else move->type = NORMAL; if (PIECE(b->square[move->source]) == KING) { int hor = move->destination % 8 - move->source % 8; if (hor > 1) move->type = KINGSIDE_CASTLE; else if (hor < -1) move->type = QUEENSIDE_CASTLE; } make_move(&board, move); check = in_check(&board, board.turn); mated = is_mated(&board, board.turn); if (check && mated) move->state = MOVE_CHECKMATE; else if (check) move->state = MOVE_CHECK; else if (mated) move->state = MOVE_STALEMATE; else move->state = MOVE_NORMAL; }
int depth_btm (TFastNode * node, int ply, int depth, int move, bool check, int legals) { if (legals==1 && !_CAPTURE(move)) { return depth-1; } if (check) { return depth-1; } if (PIECE(move)==PAWN) { if (TARGETSQ (move) <= h2) { if (TARGETSQ(move)>=a2) { return depth-1; } if (SPECIALCASE(move)==_QUEEN_PROMOTION) { return depth-1; } } else if (TARGETSQ (move) <= h3 && node->wpieces<2 &&\ passed_bpawn (node, TARGETSQ (move))) { return depth-1; } } if (g.nullmate[ply-1]) { return depth-1; } if (_CAPTURE (move) && TARGETSQ(move)==TARGETSQ(g.path[ply-2]) &&\ piece_val[CAPTURED(move)]==piece_val[CAPTURED(g.path[ply-2])] &&\ profcap_b (node, move)) { return depth-1; } if (q_mates_K (node)) { return depth-1; } return depth-10; }
void test_player_make_move(void) { board_t *board, *eboard; char *bstr[] = { "1", "0", "3", "3", "2", "1", "3", "6", "0", "2", "0", "6", "0", "0", "0", "0" }; char *bstr_expected[] = { "3", "1", "6", "3", "0", "2", "0", "12", "0", "0", "0", "0", "0", "0", "0", "0" }; int x, y; board = create_board(bstr, NORTH, 4, 4, 4); eboard = create_board(bstr_expected, NORTH, 4, 4, 4); player_make_move(board, NORTH); for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { assert(PIECE(board->b, x, y) == PIECE(eboard->b, x, y)); } } free(board); char *bstr2[] = { "1", "6", "192", "2", "1", "6", "48", "12", "1", "12", "96", "0", "3", "3", "2", "3" }; char *bstr2_expected[] = { "1", "12", "192", "2", "1", "12", "48", "12", "1", "3", "96", "0", "3", "0", "2", "3" }; board = create_board(bstr, NORTH, 4, 4, 4); eboard = create_board(bstr_expected, NORTH, 4, 4, 4); dir_t best_move = alpha_beta_next_move(board, 10); printf("%d\n", best_move); free(board); }
GLvoid ChessGame::displayFPS(GLvoid) { static long lastTime = SDL_GetTicks(); //get timestamp static long frames = 0; static GLfloat fps = 0.0f; int newTime = SDL_GetTicks(); //timestamp if((newTime - lastTime) > 100) //delay { float newFPS = (float)frames / float(newTime - lastTime) * 1000.0f; fps = (fps + newFPS) /2.0f; lastTime = newTime; //reset last time char title[80]; sprintf_s(title,"Chess Game - %.2f", fps); // populate title SDL_WM_SetCaption(title, NULL); //print to window title frames = 0; } glColor3f(1.0f,1.0f,1.0f); iGLEngine->drawTextureFont(5 , 5, "TEST FPS = %.2f", fps); //print text at top left corner of screen if(!buffFull) { iGLEngine->drawTextureFont(5 ,15, Command); //grab command // ChessLocation t_chessLoc; t_chessLoc.setChessLocX(Command[0]); t_chessLoc.setChessLocY(Command[1]-0x30); char showBuffer[2]; showBuffer[0]= PIECE(t_chessLoc).getPieceName(); t_chessLoc.setChessLocX(Command[2]); t_chessLoc.setChessLocY(Command[3]-0x30); showBuffer[1]= PIECE(t_chessLoc).getPieceName(); //iGLEngine->drawTextureFont(5,25,"%c %c",showBuffer[0],showBuffer[1]); } frames++; if(whiteTurn == true) iGLEngine->drawTextureFont(5,25,"White Turn"); else if(blackTurn == true) iGLEngine->drawTextureFont(5,25,"Black Turn"); }
int mate_material(int c) { if (board->material[c]<weights[ROOK_VALUE]) { if (board->pieces[PIECE(c,pawn)] == 0) return 0; } return 1; }
static int move_is_capture(board_t *board, move_t *move) { if (board->square[move->destination] != NONE) return 1; if ((PIECE(board->square[move->source]) == PAWN) && ((move->destination - move->source) % 8 != 0)) return 1; return 0; }
int make_move(board_t *board, move_t *move) { /* Assume that move is valid. */ if ((PIECE(board->square[move->source]) == PAWN) && ((PIECE(board->square[move->destination]) == NONE)) && ((move->source % 8) != (move->destination % 8))) { /* En-passant move. */ int ep = move->destination - 8 * (move->destination > move->source ? 1 : -1); board->captured[board->square[ep]]++; board->square[ep] = NONE; } /* Update captured pieces. */ if (board->square[move->destination] != NONE) board->captured[board->square[move->destination]]++; if ((PIECE(board->square[move->source]) == KING) && (move->destination - move->source == 2)) { /* Kingside castle. */ board->square[move->destination - 1] = board->square[move->destination + 1]; board->square[move->destination + 1] = NONE; } if ((PIECE(board->square[move->source]) == KING) && (move->source - move->destination == 2)) { /* Queenside castle. */ board->square[move->destination + 1] = board->square[move->destination - 2]; board->square[move->destination - 2] = NONE; } if ((PIECE(board->square[move->source]) == PAWN) && (move->destination < 8 || move->destination >= 56)) /* Promotion. */ board->square[move->destination] = move->promotion_piece; else board->square[move->destination] = board->square[move->source]; board->square[move->source] = NONE; board->turn = OPPONENT(board->turn); return 0; }
char *hashtree_compute(HashTreeNode * tree) { unsigned int i = 0; char *hash; void *bhash; blk_SHA_CTX ctx; assert(tree != NULL); /* precomputed */ if (tree->hash != NULL) return (char *)tree->hash; /* space for binary hash */ bhash = smalloc(20 * sizeof(unsigned char)); /* get some memory to store the hex and bin representation */ hash = smalloc(41 * sizeof(char)); /* initialize */ blk_SHA1_Init(&ctx); for (i = 0; IS_VALID_CHILD(tree, i); i++) { if (!IS_LEAF(tree, i)) tree->children[i]->hash = hashtree_compute(tree->children[i]); blk_SHA1_Update(&ctx, tree->children[i]->hash, 40); } blk_SHA1_Final((unsigned char *)bhash, &ctx); /* generate hex representation. binary hash is *big endian* */ sprintf(hash, "%08x%08x%08x%08x%08x", PIECE(0), PIECE(1), PIECE(2), PIECE(3), PIECE(4)); free(bhash); tree->hash = hash; return hash; }
char *move_to_fullalg(board_t *board, move_t *move) { char *s = (char *) malloc(6); char prom[4] = "nbrq"; square_to_str(s, move->source); square_to_str(s + 2, move->destination); s[4] = '\0'; s[5] = '\0'; if ((PIECE(board->square[move->source]) == PAWN) && ((move->destination < 8) || (move->destination >= 56))) s[4] = prom[(move->promotion_piece - 2) / 2]; return s; }
void test_comp_make_move(void) { board_t *board; char *bstr[] = { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" }; board = create_board(bstr, NORTH, 4, 4, 4); comp_make_move(board, C2I(0, 3), P1); assert(PIECE(board->b, 0, 3) == P1); assert(board->n_ones == 3); free(board); board = create_board(bstr, NORTH, 0, 0, 1); comp_make_move(board, C2I(0, 3), P3); assert(PIECE(board->b, 0, 3) == P3); assert(board->n_ones == 4); free(board); }
void ChessGame::populateLegalMoves() { if( (Command[0]<'a'||Command[0]>'h') || (Command[2]<'a'||Command[2]>'h') ||(Command[1]<'1' ||Command[1]>'8' ) || (Command[3]<'1' ||Command[3]>'8' ) ) { std::cout<<"\nWrong Move!"<<std::endl; } else { sourceChessLoc.setChessLocX(Command[0]); sourceChessLoc.setChessLocY(Command[1]-0x30); //destination DestChessLoc.setChessLocX(Command[2]); DestChessLoc.setChessLocY(Command[3]-0x30); if(board->getPiece(sourceChessLoc).getPieceColor() == WHITE && whiteTurn == true) { board->addPossibleLegalMovesToStack(stack,&PIECE(sourceChessLoc)); attemptPieceMove(sourceChessLoc,DestChessLoc); } else if(board->getPiece(sourceChessLoc).getPieceColor() == BLACK && blackTurn == true) { board->addPossibleLegalMovesToStack(stack,&PIECE(sourceChessLoc)); attemptPieceMove(sourceChessLoc,DestChessLoc); } else { listNames->addItem("It's not your turn!"); } std::cout<<"\n"<<Command<<std::endl; } }
static int is_mated(board_t *board, int side) { int src, dest; move_t move; for (src = 0; src < 64; src++) if (COLOUR(board->square[src]) == side) for (dest = 0; dest < 64; dest++) { move.source = src; move.destination = dest; if ((PIECE(board->square[src]) == PAWN) && ((dest < 8) || (dest >= 56))) move.promotion_piece = QUEEN + side; else move.promotion_piece = NONE; if (move_is_valid(board, &move)) return 0; } return 1; }
static int san_piece(int piece) { switch (PIECE(piece)) { case KING: return SAN_KING; case QUEEN: return SAN_QUEEN; case ROOK: return SAN_ROOK; case BISHOP: return SAN_BISHOP; case KNIGHT: return SAN_KNIGHT; case PAWN: return SAN_PAWN; } DBG_ERROR("failed to convert user interface piece to SAN piece"); exit(1); }
char xmlsquaretofont( int square ) { switch(PIECE(square)) { case KING: return CHAR_KING; case QUEEN: return CHAR_QUEEN; case ROOK: return CHAR_ROOK; case KNIGHT: return CHAR_KNIGHT; case BISHOP: return CHAR_BISHOP; case PAWN: return CHAR_PAWN; } return ' '; }
void ENUMERATOR::init() { int n_pawns = 0,n_pieces = 0,order = 0, i,j,pic; /*name*/ for(i = 0;i < n_piece; i++) { name[i] = piece_name[piece[i]]; } name[i++] = '.'; name[i++] = (player == white) ? 'w':'b'; name[i++] = 0; /*determine streaming order*/ int vcount[2] = {0,0}, stronger; for(i = 0;i < n_piece; i++) vcount[COLOR(piece[i])] += piece_v[piece[i]]; if(vcount[white] > vcount[black]) stronger = white; else if(vcount[black] > vcount[white]) stronger = black; else stronger = white; /*ordered list*/ for(i = 0;i < n_piece;i++) res2[i] = piece[i]; for(i = 0;i < 12;i++) { pic = piece_order[stronger][i]; for(j = 0;j < n_piece; j++) { if(res2[j] == pic) { if(PIECE(pic) == king) { index[order] = 1; n_pieces++; } else if (PIECE(pic) == pawn) { if(!n_pawns) pawn_loc = order; #ifndef SIMPLE index[order] = 48 - n_pawns; #else index[order] = 48; #endif n_pawns++; } else { #ifndef SIMPLE index[order] = 64 - n_pieces - n_pawns; #else index[order] = 64; #endif n_pieces++; } piece[order] = pic; order++; } } } /*kings*/ for(i = 0;i < n_piece;i++) { if(PIECE(piece[i]) == king) { king_loc = i; if(n_pawns) index[i + 1] = 1806; else index[i + 1] = 462; break; } } #ifndef SIMPLE /*same pieces*/ for(i = 1;i < n_piece; i++) { for(j = i + 1;j < n_piece;j++) { if(piece[i] != piece[j]) break; } j--; /*for now limit to five similar pieces*/ if(j - i > 5) j = i + 5; /*calculate number of unique positions*/ if(i != j) { for(int k = i;k < j;k++) { index[j] *= index[k]; index[k] = 1; } switch(j - i) { case 1: index[j] /= (2 * 1); break; case 2: index[j] /= (3 * 2 * 1); break; case 3: index[j] /= (4 * 3 * 2 * 1); break; case 4: index[j] /= (5 * 4 * 3 * 2 * 1); break; case 5: index[j] /= (6 * 5 * 4 * 3 * 2 * 1); break; } } i = j; } #endif /*divisor*/ divisor[n_piece - 1] = 1; for(i = 0;i < n_piece; i++) { j = n_piece - 1 - i; size *= index[j]; if(j >= 1) divisor[j - 1] = size; } }
/* Checks whether a move is valid, except for whether this puts own king in check. */ static int move_is_semi_valid(board_t *board, move_t *move) { /* Bounds check. */ if ((move->source > 63) || (move->source < 0)) return 0; if ((move->destination > 63) || (move->destination < 0)) return 0; /* Test for moving to same square. */ if (move->source == move->destination) return 0; /* Test for empty source square. */ if (board->square[move->source] == NONE) return 0; /* Test for moving opponent's piece. */ if (COLOUR(board->square[move->source]) != board->turn) return 0; /* Check that a promotion piece is specified for promotion moves. */ if ((PIECE(board->square[move->source]) == PAWN) && ((move->destination < 8) || (move->destination >= 56))) { switch (PIECE(move->promotion_piece)) { case KNIGHT: case ROOK: case BISHOP: case QUEEN: break; default: return 0; } if (COLOUR(move->promotion_piece) != board->turn) return 0; } else if (move->promotion_piece != NONE) /* Promotion piece specified for non-promotion move. */ return 0; switch (PIECE(board->square[move->source])) { case KNIGHT: if ((HOR != 1) && (HOR != 2)) return 0; if ((HOR == 1) && (VERT != 2)) return 0; if ((HOR == 2) && (VERT != 1)) return 0; if (board->square[move->destination] == NONE) break; if (COLOUR(board->square[move->destination]) == COLOUR(board->square[move->source])) return 0; break; case BISHOP: if (HOR != VERT) return 0; if (!ray_ok(board, move)) return 0; break; case ROOK: if ((HOR != 0) && (VERT != 0)) return 0; if (!ray_ok(board, move)) return 0; break; case QUEEN: if ((HOR != 0) && (VERT != 0) && (HOR != VERT)) return 0; if (!ray_ok(board, move)) return 0; break; case PAWN: /* Catch moves in wrong direction. */ if ((move->destination > move->source) && (COLOUR(board->square[move->source]) == BLACK)) return 0; if ((move->destination < move->source) && (COLOUR(board->square[move->source]) == WHITE)) return 0; if (HOR > 1) return 0; if (HOR == 0) { /* Regular or double push. */ if (VERT > 2) return 0; if (VERT == 2) if (!(((move->source >= 8) && (move->source <= 15)) || ((move->source >= 48) && (move->source <= 55)))) return 0; /* Use ray checking code with added requirement that destination square is empty. */ if (!ray_ok(board, move) || (board->square[move->destination] != NONE)) return 0; } else { if (VERT != 1) return 0; if (!ray_ok(board, move)) return 0; /* En-passant move. */ if (board->square[move->destination] == NONE) { if ((COLOUR(board->square[move->source]) == WHITE) && !((move->source >= 32) && (move->source < 40))) return 0; if ((COLOUR(board->square[move->source]) == BLACK) && !((move->source >= 24) && (move->source < 32))) return 0; if (board->square[move->destination + (COLOUR(board->square[move->source]) == WHITE ? -8 : 8)] != PAWN + OPPONENT(COLOUR(board->square[move->source]))) return 0; } } break; case KING: if (HOR > 2) return 0; else if (HOR == 2) { int white = COLOUR(board->square[move->source]) == WHITE; int i, step = (move->destination > move->source ? 1 : -1); int rook = (step == 1 ? (white ? 7 : 63) : (white ? 0 : 56)); /* Castling. */ if (VERT != 0) return 0; if (move->source != (white ? 4 : 60)) return 0; if (board->square[rook] != ROOK + COLOUR(board->square[move->source])) return 0; i = move->source + step; while (i != rook) { if (board->square[i] != NONE) return 0; i += step; } /* Check whether any of the squares the king moves over is under ** attack. Note that destination square is checked later. */ if (square_attacked(board, move->source, (white ? BLACK : WHITE))) return 0; if (square_attacked(board, move->source + step, (white ? BLACK : WHITE))) return 0; } else { if (VERT > 1) return 0; if (!ray_ok(board, move)) return 0; } } return 1; }
/* * Get index of position */ bool ENUMERATOR::get_index(MYINT& pindex,bool special) { MYINT temp; int i,k,rot,sq,ispawn,N; #ifdef SIMPLE for(i = 0;i < n_piece;i++) { for(k = 0;k < i;k++) { if(square[i] == square[k]) return false; } } #else /*illegal pawn placement on kings' square*/ if(n_pawn) { for(i = pawn_loc;i < pawn_loc + n_pawn; i++) { if(square[i] == square[king_loc] || square[i] == square[king_loc + 1]) { return false; } } } #endif /*save*/ memcpy(res2,square,n_piece * sizeof(int)); /*rotate*/ if(n_pawn) rot = KK_WP_rotation[square[king_loc] * 64 + square[king_loc + 1]]; else rot = KK_rotation[square[king_loc] * 64 + square[king_loc + 1]]; if(rot || special) { for(i = 0;i < n_piece;i++) { sq = square[i]; if(rot & rotF) sq = MIRRORF64(sq); if(rot & rotR) sq = MIRRORR64(sq); if(rot & rotD) sq = MIRRORD64(sq); if(special) sq = MIRRORD64(sq); square[i] = sq; } } /*legal placement based on other piece location*/ for(i = n_piece - 1;i >= 0; --i) { /*skip kings*/ if(i == king_loc + 1) { --i; continue; } /*adjust pawn squares here*/ if(i == pawn_loc + n_pawn - 1) { for(k = pawn_loc;k < pawn_loc + n_pawn; k++) { square[k] = SQSL64(square[k]); } } #ifndef SIMPLE /*start and finish*/ int k,l,temp,start,finish; ispawn = (PIECE(piece[i]) == pawn); start = (ispawn ? pawn_loc : 0); finish = i; if(i > 1 && index[i - 1] == 1) { finish = i - 1; if(i > 2 && index[i - 2] == 1) { finish = i - 2; if(i > 3 && index[i - 3] == 1) { finish = i - 3; if(i > 4 && index[i - 4] == 1) { finish = i - 4; } } } } /*legal placement of pieces/pawns*/ for(k = start; k < finish;k++) res1[k] = square[k]; for(k = start; k < finish;k++) { for(l = k + 1; l < finish;l++) { if(res1[k] > res1[l]) { temp = res1[k]; res1[k] = res1[l]; res1[l] = temp; } } } for(k = finish - 1; k >= start ; k--) { if(square[i] >= res1[k]) square[i]--; } #endif /*end*/ } /*primary locations*/ pindex = 0; for(i = n_piece - 1;i >= 0; --i) { /*king squares*/ if(i == king_loc + 1) { if(n_pawn) temp = KK_WP_index[square[i - 1] * 64 + square[i]]; else temp = KK_index[square[i - 1] * 64 + square[i]]; pindex += temp * divisor[i]; --i; continue; } /*others*/ ispawn = (PIECE(piece[i]) == pawn); N = 0; #ifndef SIMPLE for(;i >= 2;i--) { if(index[i - 1] == 1) N++; else break; } if(N) { if(ispawn) { for(k = 0;k <= N;k++) square[i + k] = SQ6448(square[i + k]); } temp = get_index_like(&square[i],N + 1); } else #endif { if(ispawn) temp = SQ6448(square[i]); else temp = square[i]; } pindex += temp * divisor[i + N]; } /*restore*/ memcpy(square,res2,n_piece * sizeof(int)); return true; }
bool checkcheck_b (TFastNode* node, int move) { //check if black move checked white king char offset, offset_ssq_tsq; unsigned char piece, csq, sq; if (!SPECIAL (move)) { piece = PIECE (move); sq = TARGETSQ (move); if (!t.pieceattacks [piece] [node->wkpos] [sq]) { goto AFTREKSCHAAK; } if (piece < BISHOP) { return true; } // check if no piece in between offset = t.direction [sq] [node->wkpos]; sq += offset; while (sq != node -> wkpos) { if (node->matrix [sq]) { goto AFTREKSCHAAK; } sq += offset; } return true; } else { switch (SPECIALCASE (move)) { case _EN_PASSANT: sq = TARGETSQ (move); if (t.pieceattacks [PAWN] [node->wkpos] [sq]) { return true; } csq = sq + 8; offset = t.direction [node -> wkpos] [csq]; if (offset) { sq = node -> wkpos + offset; if (node -> matrix [sq]) { break; } sq = t.sqonline [node->wkpos] [sq]; while (sq != node -> wkpos) { BOOST_ASSERT (sq >= 0 && sq <= 63); piece = node -> matrix [sq]; if (piece) { if (piece > BKNIGHT && t.pieceattacks [piece - KING] [sq] [node->wkpos]) { return true; } goto AFTREKSCHAAK; } sq = t.sqonline [node -> wkpos] [sq]; } } break; case _QUEEN_PROMOTION: sq = TARGETSQ (move); if (!t.pieceattacks [QUEEN] [sq] [node->wkpos]) { goto AFTREKSCHAAK; } offset = t.direction [sq] [node->wkpos]; sq += offset; while (sq != node->wkpos) { piece = node -> matrix [sq]; if (piece) { goto AFTREKSCHAAK; } sq += offset; } return true; case _SHORT_CASTLE: if (!t.pieceattacks [ROOK] [f8] [node->wkpos]) { return false; } offset = t.direction [f8] [node->wkpos]; sq = f8 + offset; do { if (node->matrix [sq]) { return false; } sq += offset; } while (sq != node->wkpos); return true; case _LONG_CASTLE: if (!t.pieceattacks [ROOK] [d8] [node->wkpos]) { return false; } offset = t.direction [d8] [node->wkpos]; sq = d8 + offset; do { if (node->matrix [sq]) { return false; } sq += offset; } while (sq != node->wkpos); return true; case _ROOK_PROMOTION: sq = TARGETSQ (move); if (!t.pieceattacks [ROOK] [sq] [node->wkpos]) { goto AFTREKSCHAAK; } offset = t.direction [sq] [node->wkpos]; sq += offset; while (sq != node->wkpos) { piece = node -> matrix [sq]; if (piece) { goto AFTREKSCHAAK; } sq += offset; } return true; case _BISHOP_PROMOTION: sq = TARGETSQ (move); if (!t.pieceattacks [BISHOP] [sq] [node->wkpos]) { goto AFTREKSCHAAK; } offset = t.direction [sq] [node->wkpos]; sq += offset; while (sq != node->wkpos) { piece = node -> matrix [sq]; if (piece) { goto AFTREKSCHAAK; } sq += offset; } return true; case _KNIGHT_PROMOTION: sq = TARGETSQ (move); if (!t.pieceattacks [KNIGHT] [sq] [node->wkpos]) { goto AFTREKSCHAAK; } return true; case _PLUNKMOVE: piece = PIECE (move); sq = TARGETSQ (move); if (!t.pieceattacks [piece] [node->wkpos] [sq]) { return false; } if (piece < BISHOP) { return true; } // check if no piece in between offset = t.direction [sq] [node->wkpos]; sq += offset; while (sq != node -> wkpos) { if (node->matrix [sq]) { return false; } sq += offset; } return true; } } AFTREKSCHAAK: sq = SOURCESQ (move); offset = t.direction [node->wkpos] [sq]; if (!offset) { return false; } offset_ssq_tsq = t.direction [sq] [TARGETSQ (move)]; if ((offset_ssq_tsq == offset) || (offset_ssq_tsq == (- offset))) { return false; } sq = node -> wkpos + offset; if (node -> matrix [sq]) { return false; } sq = t.sqonline [node -> wkpos] [sq]; while (sq != node -> wkpos) { piece = node->matrix [sq]; if (piece) { return piece > BKNIGHT && t.pieceattacks [piece - KING] [sq] [node->wkpos]; } sq = t.sqonline [node -> wkpos] [sq]; } return false; }
int score_move(Board *board, Move *move) { int result = 0; int src = move->src; int dst = move->dst; int piece = board->squares[src]; int capture = board->squares[dst]; int piece_material = 0; int capture_material = 0; if (COLOR(piece)) { switch (PIECE(piece)) { case PAWN: piece_material = MATERIAL_PAWN; result -= POSITION_BLACK_PAWN[src]; result += POSITION_BLACK_PAWN[dst]; break; case KNIGHT: piece_material = MATERIAL_KNIGHT; result -= POSITION_BLACK_KNIGHT[src]; result += POSITION_BLACK_KNIGHT[dst]; break; case BISHOP: piece_material = MATERIAL_BISHOP; result -= POSITION_BLACK_BISHOP[src]; result += POSITION_BLACK_BISHOP[dst]; break; case ROOK: piece_material = MATERIAL_ROOK; result -= POSITION_BLACK_ROOK[src]; result += POSITION_BLACK_ROOK[dst]; break; case QUEEN: piece_material = MATERIAL_QUEEN; result -= POSITION_BLACK_QUEEN[src]; result += POSITION_BLACK_QUEEN[dst]; break; case KING: piece_material = MATERIAL_KING; result -= POSITION_BLACK_KING[src]; result += POSITION_BLACK_KING[dst]; break; } } else { switch (PIECE(piece)) { case PAWN: piece_material = MATERIAL_PAWN; result -= POSITION_WHITE_PAWN[src]; result += POSITION_WHITE_PAWN[dst]; break; case KNIGHT: piece_material = MATERIAL_KNIGHT; result -= POSITION_WHITE_KNIGHT[src]; result += POSITION_WHITE_KNIGHT[dst]; break; case BISHOP: piece_material = MATERIAL_BISHOP; result -= POSITION_WHITE_BISHOP[src]; result += POSITION_WHITE_BISHOP[dst]; break; case ROOK: piece_material = MATERIAL_ROOK; result -= POSITION_WHITE_ROOK[src]; result += POSITION_WHITE_ROOK[dst]; break; case QUEEN: piece_material = MATERIAL_QUEEN; result -= POSITION_WHITE_QUEEN[src]; result += POSITION_WHITE_QUEEN[dst]; break; case KING: piece_material = MATERIAL_KING; result -= POSITION_WHITE_KING[src]; result += POSITION_WHITE_KING[dst]; break; } } if (capture) { if (COLOR(capture)) { switch (PIECE(capture)) { case PAWN: capture_material = MATERIAL_PAWN; result += POSITION_BLACK_PAWN[dst]; break; case KNIGHT: capture_material = MATERIAL_KNIGHT; result += POSITION_BLACK_KNIGHT[dst]; break; case BISHOP: capture_material = MATERIAL_BISHOP; result += POSITION_BLACK_BISHOP[dst]; break; case ROOK: capture_material = MATERIAL_ROOK; result += POSITION_BLACK_ROOK[dst]; break; case QUEEN: capture_material = MATERIAL_QUEEN; result += POSITION_BLACK_QUEEN[dst]; break; case KING: capture_material = MATERIAL_KING; result += POSITION_BLACK_KING[dst]; break; } } else { switch (PIECE(capture)) { case PAWN: capture_material = MATERIAL_PAWN; result += POSITION_WHITE_PAWN[dst]; break; case KNIGHT: capture_material = MATERIAL_KNIGHT; result += POSITION_WHITE_KNIGHT[dst]; break; case BISHOP: capture_material = MATERIAL_BISHOP; result += POSITION_WHITE_BISHOP[dst]; break; case ROOK: capture_material = MATERIAL_ROOK; result += POSITION_WHITE_ROOK[dst]; break; case QUEEN: capture_material = MATERIAL_QUEEN; result += POSITION_WHITE_QUEEN[dst]; break; case KING: capture_material = MATERIAL_KING; result += POSITION_WHITE_KING[dst]; break; } } result += capture_material; } return result; }
void notate_move(Board *board, Move *move, char *result) { Move moves[MAX_MOVES]; int count = gen_legal_moves(board, moves); int piece = board->squares[move->src]; int capture = board->squares[move->dst]; char rank1 = '1' + move->src / 8; char file1 = 'a' + move->src % 8; char rank2 = '1' + move->dst / 8; char file2 = 'a' + move->dst % 8; int show_rank1 = 0; int show_file1 = 0; if (PIECE(piece) == PAWN) { if (file1 != file2) { capture = 1; } if (capture) { show_file1 = 1; } } // ambiguity int ambiguous = 0; int unique_rank = 1; int unique_file = 1; for (int i = 0; i < count; i++) { Move *other = moves + i; if (move->dst != other->dst) { continue; // different target } if (move->src == other->src) { continue; // same move } if (piece != board->squares[other->src]) { continue; // different piece } ambiguous = 1; if (move->src % 8 == other->src % 8) { unique_file = 0; } if (move->src / 8 == other->src / 8) { unique_rank = 0; } } if (ambiguous) { if (unique_rank && unique_file) { show_file1 = 1; } else if (unique_rank) { show_rank1 = 1; } else if (unique_file) { show_file1 = 1; } else { show_rank1 = 1; show_file1 = 1; } } // castle int castle = 0; if (PIECE(piece) == KING) { castle = 1; if (move->src == 4 && move->dst == 6) { strcpy(result, "O-O"); result += 3; } else if (move->src == 4 && move->dst == 2) { strcpy(result, "O-O-O"); result += 5; } else if (move->src == 60 && move->dst == 62) { strcpy(result, "O-O"); result += 3; } else if (move->src == 60 && move->dst == 58) { strcpy(result, "O-O-O"); result += 5; } else { castle = 0; } } if (!castle) { // piece switch (PIECE(piece)) { case KNIGHT: *result++ = 'N'; break; case BISHOP: *result++ = 'B'; break; case ROOK: *result++ = 'R'; break; case QUEEN: *result++ = 'Q'; break; case KING: *result++ = 'K'; break; } // source if (show_file1) { *result++ = file1; } if (show_rank1) { *result++ = rank1; } // capture if (capture) { *result++ = 'x'; } // target *result++ = file2; *result++ = rank2; // promotion if (move->promotion) { *result++ = '='; switch (move->promotion) { case KNIGHT: *result++ = 'N'; break; case BISHOP: *result++ = 'B'; break; case ROOK: *result++ = 'R'; break; case QUEEN: *result++ = 'Q'; break; } } } // check Undo undo; do_move(board, move, &undo); if (is_check(board)) { if (has_legal_moves(board)) { *result++ = '+'; } else { *result++ = '#'; } } undo_move(board, move, &undo); // null terminator *result++ = 0; }