void game_make_move(move_t *move, int ui_update) { if (do_move(move, ui_update)) { comm_send("%s\n", fullalg_list.move[fullalg_list.entries - 1]); } else { char *move_str = move_to_fullalg(history->last->board, move); DBG_WARN("Ignoring illegal move %s", move_str); free(move_str); } }
char *move_to_san(board_t *board, move_t *move) { san_move_t san_move; switch (move->state) { case MOVE_CHECK: san_move.state = SAN_STATE_CHECK; break; case MOVE_CHECKMATE: san_move.state = SAN_STATE_CHECKMATE; break; default: san_move.state = SAN_STATE_NORMAL; } switch (move->type) { case QUEENSIDE_CASTLE: san_move.type = SAN_QUEENSIDE_CASTLE; return san_string(&san_move); case KINGSIDE_CASTLE: san_move.type = SAN_KINGSIDE_CASTLE; return san_string(&san_move); case CAPTURE: san_move.type = SAN_CAPTURE; break; default: san_move.type = SAN_NORMAL; } san_move.piece = san_piece(board->square[move->source]); san_move.source_file = SAN_NOT_SPECIFIED; san_move.source_rank = SAN_NOT_SPECIFIED; san_move.destination = move->destination; if (move->promotion_piece != NONE) san_move.promotion_piece = san_piece(move->promotion_piece); else san_move.promotion_piece = SAN_NOT_SPECIFIED; if (san_move.piece == SAN_PAWN) { if (move->source % 8 != move->destination % 8) san_move.source_file = move->source % 8; } else { move_t *u_move; u_move = find_unique_move(board, &san_move); if (!u_move) { san_move.source_file = move->source % 8; u_move = find_unique_move(board, &san_move); if (!u_move) { san_move.source_file = SAN_NOT_SPECIFIED; san_move.source_rank = move->source / 8; u_move = find_unique_move(board, &san_move); if (!u_move) { san_move.source_file = move->source % 8; u_move = find_unique_move(board, &san_move); if (!u_move) { char *move_s = move_to_fullalg(board, move); DBG_ERROR("failed to convert move %s to SAN notation", move_s); free(move_s); return NULL; } } else free(u_move); } else free(u_move); } else free(u_move); } return san_string(&san_move); }
static int do_move(move_t *move, int ui_update) { char *move_s, *move_f, *move_san; board_t new_board; if (!move_is_valid(history->last->board, move)) { DBG_WARN("Move is illegal"); return 0; } move_set_attr(history->last->board, move); new_board = *history->last->board; move_s = move_to_fullalg(&new_board, move); move_list_play(&fullalg_list, move_s); move_san = move_to_san(&new_board, move); move_f = san_to_fan(&new_board, move_san); DBG_LOG("Processing move %s (%s)", move_s, move_san); move_list_play(&san_list, move_san); move_list_play(&fan_list, move_f); free(move_san); free(move_f); free(move_s); make_move(&new_board, move); if (move->state == MOVE_CHECK) new_board.state = BOARD_CHECK; else if (move->state == MOVE_CHECKMATE) new_board.state = BOARD_CHECKMATE; else new_board.state = BOARD_NORMAL; history_play(history, move, &new_board); if (ui_update) ui->update(history->view->board, move); if (new_board.state == MOVE_CHECKMATE) { history->result = malloc(sizeof(result_t)); if (new_board.turn == WHITE) { history->result->code = RESULT_BLACK_WINS; history->result->reason = strdup("Black mates"); } else { history->result->code = RESULT_WHITE_WINS; history->result->reason = strdup("White mates"); } if (ui_update) ui->show_result(history->result); } else if (new_board.state == MOVE_STALEMATE) { history->result = malloc(sizeof(result_t)); history->result->code = RESULT_DRAW; history->result->reason = strdup("Stalemate"); if (ui_update) ui->show_result(history->result); } return 1; }