inline void swap(CDLList& p) { swap_pointers(p._next, _next); swap_pointers(p._prev, _prev); p._next->_prev = &p; p._prev->_next = &p; _next->_prev = this; _prev->_next = this; };
static int partition(DList *list, int left, int right) { void *x = dlist_data(get_element(list, right)); int i = left - 1; int j; for (j = left; j != right; j++){ if (list->compare(dlist_data(get_element(list, j)), x) <= 0){ i++; swap_pointers(get_element(list, i), get_element(list, j)); } } swap_pointers(get_element(list, i+1), get_element(list, right)); return(i+1); }
int main() { int i = 2, j = 45; int *ip = &i, *jp = &j; swap_pointers(ip, jp); std::cout << "i = " << i << "\nj = " << j << "\n*ip = " << *ip << "\n*jp = " << *jp << std::endl; }
/** * [Jonathan::shoot Shoot the darn monkey.] * @return [The chosen tree (that sounds like Avatar..). If Chuck is stuck, dial -1.] */ int Jonathan::shoot() { // Remember current shot const unsigned tree = next_shot; // Trick to avoid testing for the tree being shot swap_pointers(); pi_old[ tree ] = 0.0; // Find new max probability register double pi_max = 0.0; // Iterator on neighbors const unsigned *neighbor = &neighbors[0]; // Compute new probability distribution for ( unsigned t = 0; t < n_nodes; ++t ) { // Reset probability pi_new[t] = 0.0; // Update probability for ( unsigned d = 0; d++ < degrees[t]; ++neighbor ) pi_new[t] += pi_old[ *neighbor ] / degrees[ *neighbor ]; // Select tree with max probability for the next shot if ( pi_new[t] > pi_max ) { next_shot = t; pi_max = pi_new[t]; } } // If max has become too small, scale tables if ( pi_max <= CHUCK_EPSILON ) { array_a /= CHUCK_EPSILON; array_b /= CHUCK_EPSILON; } // Return current shot return (int) tree; }
/* Remove the node with key name from the tree if it is there. See inline * comments for algorithmic details. Return true if something was deleted. */ int xremove(char *name) { node_t *parent; /* Parent of the node to delete */ node_t *dnode; /* Node to delete */ node_t *next; /* used to find leftmost child of right subtree */ node_t **pnext; /* A pointer in the tree that points to next so we can change that nodes children (see below). */ // Lock the mutex! pthread_mutex_lock(&g_coarse_mutex); /* first, find the node to be removed */ if (!(dnode = search(name, &head, &parent))) { /* it's not there */ pthread_mutex_unlock(&g_coarse_mutex); return 0; } /* we found it. Now check out the easy cases. If the node has no * right child, then we can merely replace its parent's pointer to * it with the node's left child. */ if (dnode->rchild == 0) { if (strcmp(dnode->name, parent->name) < 0) parent->lchild = dnode->lchild; else parent->rchild = dnode->lchild; /* done with dnode */ node_destroy(dnode); } else if (dnode->lchild == 0) { /* ditto if the node had no left child */ if (strcmp(dnode->name, parent->name) < 0) parent->lchild = dnode->rchild; else parent->rchild = dnode->rchild; /* done with dnode */ node_destroy(dnode); } else { /* So much for the easy cases ... * We know that all nodes in a node's right subtree have * lexicographically greater names than the node does, and all * nodes in a node's left subtree have lexicographically smaller * names than the node does. So, we find the lexicographically * smallest node in the right subtree and replace the node to be * deleted with that node. This new node thus is lexicographically * smaller than all nodes in its right subtree, and greater than * all nodes in its left subtree. Thus the modified tree is well * formed. */ /* pnext is the address of the pointer which points to next (either * parent's lchild or rchild) */ pnext = &dnode->rchild; next = *pnext; while (next->lchild != 0) { /* work our way down the lchild chain, finding the smallest * node in the subtree. */ pnext = &next->lchild; next = *pnext; } swap_pointers(&dnode->name, &next->name); swap_pointers(&dnode->value, &next->value); *pnext = next->rchild; node_destroy(next); } pthread_mutex_unlock(&g_coarse_mutex); return 1; }
internal void Triangle(v3i *p, v2i *uv, r32 intensity, TGAImage *texture, int *z_buffer) { v3i *p0 = &p[0]; v3i *p1 = &p[1]; v3i *p2 = &p[2]; v2i *uv0 = &uv[0]; v2i *uv1 = &uv[1]; v2i *uv2 = &uv[2]; // Sort points by y if (p0->y > p1->y) swap_pointers(&p0, &p1); if (p1->y > p2->y) swap_pointers(&p1, &p2); if (p0->y > p1->y) swap_pointers(&p0, &p1); if (uv0->y > uv1->y) swap_pointers(&uv0, &uv1); if (uv1->y > uv2->y) swap_pointers(&uv1, &uv2); if (uv0->y > uv1->y) swap_pointers(&uv0, &uv1); v3i long_side = *p2 - *p0; int total_height = long_side.y; int segment_height = 0; for (int y = p0->y; y <= p2->y; ++y) { bool32 top_half = (y > p1->y) || (p0->y == p1->y); v3i short_side = top_half ? (*p2 - *p1) : (*p1 - *p0); int y0 = (top_half ? p1->y : p0->y); r32 segment_share = static_cast<r32>(y - y0) / short_side.y; r32 total_share = static_cast<r32>(y - p0->y) / total_height; // Model vectors v3i a = short_side * segment_share + (top_half ? *p1 : *p0); v3i b = long_side * total_share + *p0; // Texture vectors v2i uv_a = top_half ? *uv1 + (*uv2 - *uv1) * segment_share : *uv0 + (*uv1 - *uv0) * segment_share; v2i uv_b = *uv0 + (*uv2 - *uv0) * total_share; // Draw horizontal line { if (a.x > b.x) { swap_pointers(&a, &b); swap_pointers(&uv_a, &uv_b); } int x0 = a.x; int x1 = b.x; if (x0 < 0) x0 = 0; if (x1 >= g_game_backbuffer.width) x1 = g_game_backbuffer.width - 1; if (y < 0 || y >= g_game_backbuffer.height) continue; int pitch = g_game_backbuffer.width * g_game_backbuffer.bytes_per_pixel; u8 *row = (u8 *)g_game_backbuffer.memory + (g_game_backbuffer.height - 1) * pitch - pitch * y + x0 * g_game_backbuffer.bytes_per_pixel; u32 *Pixel = (u32 *)row; for (int x = x0; x <= x1; ++x) { r32 share = (b.x == a.x) ? 1.0f : static_cast<r32>(x - a.x) / (b.x - a.x); v3i result = a + share * (b - a); v2i uv_result = uv_a + share * (uv_b - uv_a); int index = result.y * g_game_backbuffer.width + result.x; if (z_buffer[index] < result.z) { z_buffer[index] = result.z; TGAColor color = texture->get(uv_result.x, uv_result.y); *Pixel = (u32)(color.r * intensity) << 16 | (u32)(color.g * intensity) << 8 | (u32)(color.b * intensity); } Pixel++; } } } }
int main(int argc, char *argv[]) { const char *const Help = "fens2pgn - converts multiple FENs into single PGN file\n" "Syntax: fens2pgn [arguments] [output file] [input file]\n" "Arguments:\n" " -f force validity of every chess move\n" " -o take next argument as output file\n" " -q quiet - doesn't print informations to stderr\n" " -v verbose - notify of every skipped FEN\n" " -h, --help print this help text\n" " -u, --usage short usage information\n" " -V, --version display program version"; if (argc < 2) { puts(Help); return 0; } struct { bool validate; bool quiet; bool verbose; char *read_from_file; char *write_to_file; } parameters = {0, 0, 0, NULL, NULL}; const struct option long_options[] = { {"help", 0, NULL, 'h'}, {"usage", 0, NULL, 'u'}, {"version", 0, NULL, 'V'}, {NULL, 0, NULL, 0} }; for (int option, long_option_index; (option = getopt_long(argc, argv, "fho:quvV", long_options, &long_option_index)) != -1;) switch (option) { case 'f': parameters.validate = 1; break; case 'h': puts(Help); return 0; case 'o': parameters.write_to_file = optarg; break; case 'q': parameters.quiet = 1; parameters.verbose = 0; break; case 'u': puts("Syntax: fens2pgn [-fqv] [-o OUTPUT_FILE] [INPUT_FILE]\n" " [-h|--help] [-u|--usage] [-V|--version]"); return 0; case 'v': parameters.quiet = 0; parameters.verbose = 1; break; case 'V': puts("fens2pgn " VERSION "\n" "Copyright (C) 2015 Paweł Zacharek"); return 0; default: return EINVAL; } if (optind == argc - 1) // 1 unknown parameter (input file name) parameters.read_from_file = argv[optind]; else if (optind != argc) { // more unknown parameters fputs("Invalid argument(s) found.\n", stderr); return EINVAL; } FILE *input = (parameters.read_from_file == NULL ? stdin : fopen(parameters.read_from_file, "r")); FILE *output = (parameters.write_to_file == NULL ? stdout : fopen(parameters.write_to_file, "w")); if (input == NULL) { fprintf(stderr, "Can't open file \"%.255s\" for reading.\n", parameters.read_from_file); return ENOENT; } if (output == NULL) { fprintf(stderr, "Can't open file \"%.255s\" for writing.\n", parameters.read_from_file); return EACCES; } char fen_buffer[MAX_FEN_LENGHT + 1], fen_placement_buffer[MAX_PLACEMENT_LENGHT + 1]; char store_space[STORE_SPACE_SIZE], store_move[STORE_MOVE_SIZE]; char board_buffer_1[8][8], board_buffer_2[8][8]; char (*board_1)[8] = board_buffer_1, (*board_2)[8] = board_buffer_2; int fen_number = 0, move_number = 1, number_of_characters_in_line = 0; struct field distinctions[4], *field, *previous_field; struct piece king_placement; signed char number_of_differences; char control_character, whose_move = 'w', castling_prospects[4 + 1] = "KQkq", en_passant_field[2 + 1] = "-"; char control_string[8 + 1], result[7 + 1]; // to store respectively "Result \"" and "1/2-1/2" result[0] = '\0'; bool metadata_included = 0, fens_are_incomplete = 0, first_move_number_already_written = 0, move_is_invalid = 0; // beginning of METADATA section fscanf(input, " %c", &control_character); while (control_character == '[') { metadata_included = 1; putc('[', output); if (fscanf(input, "%8[^\n]", control_string) == 1) { if (strncmp(control_string, "Result \"", 8) == 0 && fscanf(input, "%7[-01/2*]", result) == 1) fprintf(output, "%s%s", control_string, result); else fputs(control_string, output); } for (int character; (character = getc(input)) != EOF;) { putc(character, output); if (character == '\n') break; } fscanf(input, " %c", &control_character); } ungetc(control_character, input); // beginning of GAME section if (fscanf(input, "%" STR(MAX_FEN_LENGHT) "[-0-9a-h/rnqkpRNBQKP w]", fen_buffer) != 1) { // reading the first FEN fputs("No valid FEN found.\n", stderr); return EILSEQ; } ++fen_number; sscanf(fen_buffer, "%" STR(MAX_PLACEMENT_LENGHT) "[1-8/rnbqkpRNBQKP]", fen_placement_buffer); if (strncmp(fen_buffer, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 56) != 0) { // it isn't classical complete FEN if (sscanf(fen_buffer, "%*[1-8/rnbqkpRNBQKP] %c %4s %2s %*d %d", &whose_move, castling_prospects, en_passant_field, &move_number) != 4) { // FENs are incomplete fens_are_incomplete = 1; if (parameters.quiet != 1) fputs("FENs considered incomplete.\n", stderr); // not corrupts redirected output whose_move = 'w'; strcpy(castling_prospects, "KQkq"); strcpy(en_passant_field, "-"); move_number = 1; } if (fens_are_incomplete == 0 || strncmp(fen_buffer, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR", 43) != 0) // starting position isn't classical fprintf(output, "[SetUp \"1\"]\n[FEN \"%s\"]\n", fen_buffer); } if (metadata_included == 1) putc('\n', output); if (fen2board(fen_placement_buffer, board_1, parameters.validate) == 0) { fputs("There are more than 2 kings or invalid pieces on the first board. Terminating.\n", stderr); return 0; } for (;;) { if (fscanf(input, " %" STR(MAX_FEN_LENGHT) "[-0-9a-h/rnqkpRNBQKP w]", fen_buffer) != 1) break; ++fen_number; sscanf(fen_buffer, "%" STR(MAX_PLACEMENT_LENGHT) "[1-8/rnbqkpRNBQKP]", fen_placement_buffer); if (fen2board(fen_placement_buffer, board_2, parameters.validate) == 0) { fprintf(stderr, "There are more than 2 kings or invalid pieces on board nr %d. Terminating.\n", fen_number); return 0; } number_of_differences = compare_boards((const char (*)[8])board_1, (const char (*)[8])board_2, distinctions); if (number_of_differences < 2) { if (parameters.verbose == 1) fprintf(stderr, "Skipped \"%s\" (%d%s FEN).\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number)); continue; } if (number_of_differences > 4) { fprintf(stderr, "Can't compare \"%s\" (%d%s FEN) with the previous one.\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number)); return EILSEQ; } switch (number_of_differences) { case 2: // ordinary move or capture if (distinctions[0].piece_after != ' ') { field = &distinctions[0]; previous_field = &distinctions[1]; } else { // it means that (distinctions[1].piece_after != ' ') field = &distinctions[1]; previous_field = &distinctions[0]; } switch (what_to_write((const char (*)[8])board_2, (const struct field *)field, (const struct field *)previous_field, en_passant_field, parameters.validate, whose_move, castling_prospects)) { case PAWN_MOVE: snprintf(store_move, STORE_MOVE_SIZE, "%c%hhd", field->alphabetical, field->numerical); break; case PAWN_CAPTURE: snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", previous_field->alphabetical, field->alphabetical, field->numerical); break; case PAWN_PROMOTION: snprintf(store_move, STORE_MOVE_SIZE, "%c%hhd=%c", field->alphabetical, field->numerical, toupper(field->piece_after)); break; case PAWN_CAPTURE_PROMOTION: snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd=%c", previous_field->alphabetical, field->alphabetical, field->numerical, toupper(field->piece_after)); break; case PIECE_MOVE: snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%cx%c%hhd" : "%c%c%hhd", toupper(field->piece_after), field->alphabetical, field->numerical); break; case DIS_LINE: case DIS_WHICHEVER: snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%c%cx%c%hhd" : "%c%c%c%hhd", toupper(field->piece_after), previous_field->alphabetical, field->alphabetical, field->numerical); break; case DIS_COLUMN: snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%c%hhdx%c%hhd" : "%c%hhd%c%hhd", toupper(field->piece_after), previous_field->numerical, field->alphabetical, field->numerical); break; case DIS_BOTH: snprintf(store_move, STORE_MOVE_SIZE, field->piece_before != ' ' ? "%c%c%hhdx%c%hhd" : "%c%c%hhd%c%hhd", toupper(field->piece_after), previous_field->alphabetical, previous_field->numerical, field->alphabetical, field->numerical); break; case INVALID_MOVE: move_is_invalid = 1; break; } break; case 3: // en passant capture if (parameters.validate != 1) { if (whose_move == 'w') snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[2].alphabetical, distinctions[0].alphabetical, distinctions[0].numerical); else snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[0].alphabetical, distinctions[2].alphabetical, distinctions[2].numerical); } else { char all_fields[6 + 1]; snprintf(all_fields, sizeof all_fields, "%c%c%c%c%c%c", distinctions[0].piece_before, distinctions[0].piece_after, distinctions[1].piece_before, distinctions[1].piece_after, distinctions[2].piece_before, distinctions[2].piece_after); if (whose_move == 'w' && en_passant_field[0] == distinctions[0].alphabetical && en_passant_field[1] - '0' == distinctions[0].numerical && distinctions[0].numerical == distinctions[2].numerical + 1 && distinctions[1].alphabetical == distinctions[2].alphabetical - 1 && ( distinctions[0].alphabetical == distinctions[2].alphabetical && memcmp(all_fields, " PP p ", 6) == 0 || distinctions[0].alphabetical != distinctions[2].alphabetical && memcmp(all_fields, " Pp P ", 6) == 0 )) snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[2].alphabetical, distinctions[0].alphabetical, distinctions[0].numerical); else if (whose_move == 'b' && en_passant_field[0] == distinctions[2].alphabetical && en_passant_field[1] - '0' == distinctions[2].numerical && distinctions[0].numerical == distinctions[2].numerical + 1 && distinctions[0].alphabetical == distinctions[1].alphabetical - 1 && ( distinctions[0].alphabetical == distinctions[2].alphabetical && memcmp(all_fields, "P p p", 6) == 0 || distinctions[0].alphabetical != distinctions[2].alphabetical && memcmp(all_fields, "p P p", 6) == 0 )) snprintf(store_move, STORE_MOVE_SIZE, "%cx%c%hhd", distinctions[0].alphabetical == distinctions[2].alphabetical ? distinctions[1].alphabetical : distinctions[0].alphabetical, distinctions[2].alphabetical, distinctions[2].numerical); else move_is_invalid = 1; } break; case 4: // castling if (parameters.validate != 1) snprintf(store_move, STORE_MOVE_SIZE, distinctions[0].alphabetical == 'a' ? "O-O-O" : "O-O"); else { if (distinctions[0].alphabetical == 'a' && is_king_checked_while_castling(distinctions[3].piece_before, distinctions[3].alphabetical, distinctions[3].numerical, (const char (*)[8])board_1, (const char (*)[8])board_2, -1) == 0 && ( whose_move == 'w' && strchr(castling_prospects, 'Q') != NULL && memcmp(&board_1[8 - 1][0], "R K", 5) == 0 && memcmp(&board_2[8 - 1][0], " KR ", 5) == 0 || whose_move == 'b' && strchr(castling_prospects, 'q') != NULL && memcmp(&board_1[8 - 8][0], "r k", 5) == 0 && memcmp(&board_2[8 - 8][0], " kr ", 5) == 0 )) snprintf(store_move, STORE_MOVE_SIZE, "O-O-O"); else if (distinctions[3].alphabetical == 'h' && is_king_checked_while_castling(distinctions[0].piece_before, distinctions[0].alphabetical, distinctions[0].numerical, (const char (*)[8])board_1, (const char (*)[8])board_2, 1) == 0 && ( whose_move == 'w' && strchr(castling_prospects, 'K') != NULL && memcmp(&board_1[8 - 1][4], "K R", 4) == 0 && memcmp(&board_2[8 - 1][0], " RK ", 4) == 0 || whose_move == 'b' && strchr(castling_prospects, 'k') != NULL && memcmp(&board_1[8 - 8][4], "k r", 4) == 0 && memcmp(&board_2[8 - 8][0], " rk ", 4) == 0 )) snprintf(store_move, STORE_MOVE_SIZE, "O-O"); else move_is_invalid = 1; } break; } if (parameters.validate == 1 && move_is_invalid == 1) { move_is_invalid = 0; if (parameters.quiet != 1) fprintf(stderr, "Skipped \"%s\" (%d%s FEN) because the calculated move is invalid.\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number)); continue; } if (parameters.validate == 1 && find_piece(whose_move == 'w' ? 'K' : 'k', &king_placement, (const char (*)[8])board_2)) if (is_piece_attacked(king_placement.type, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, 1)) { if (parameters.quiet != 1) fprintf(stderr, "Skipped \"%s\" (%d%s FEN) because we're still in check.\n", fen_buffer, fen_number, Ordinal_Number_Suffix(fen_number)); continue; } if (find_piece(whose_move == 'w' ? 'k' : 'K', &king_placement, (const char (*)[8])board_2)) if (is_piece_attacked(king_placement.type, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, 1)) { // king is checked if (does_king_cannot_move((const struct piece *)&king_placement, board_2) && ( is_piece_attacked(king_placement.type, king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, 2) // double check || is_it_checkmate(king_placement.alphabetical, king_placement.numerical, (const char (*)[8])board_2, (const char *)en_passant_field) )) snprintf(store_move + strlen(store_move), STORE_MOVE_SIZE - strlen(store_move), "#"); else snprintf(store_move + strlen(store_move), STORE_MOVE_SIZE - strlen(store_move), "+"); } if (first_move_number_already_written == 1) strcpy(store_space, " "); if (whose_move == 'w' || first_move_number_already_written == 0) snprintf(store_space + (first_move_number_already_written ? 1 : 0), STORE_SPACE_SIZE - (first_move_number_already_written ? 1 : 0), "%d. ", move_number); number_of_characters_in_line += strlen(store_space) - 1; // we can omit trailing space if (number_of_characters_in_line >= 80) { store_space[0] = '\n'; number_of_characters_in_line = strlen(store_space) - 2; // the first space is also not included } number_of_characters_in_line += strlen(store_move) + 1; // add previously disregarded trailing space if (number_of_characters_in_line >= 80) { store_space[strlen(store_space) - 1] = '\n'; number_of_characters_in_line = strlen(store_move); // doesn't count trailing space of 'store_space' array } fprintf(output, "%s%s", store_space, store_move); first_move_number_already_written = 1; if (whose_move == 'b') ++move_number; whose_move = (whose_move == 'b' ? 'w' : 'b'); swap_pointers((void **)&board_1, (void **)&board_2); } if (result[0] != '\0') fprintf(output, "%c%s\n", number_of_characters_in_line + 1 + strlen(result) >= 80 ? '\n' : ' ', result); else fprintf(output, "%c*\n", number_of_characters_in_line + 2 >= 80 ? '\n' : ' '); fclose(input); fclose(output); return 0; }
// Crop a new circular list from 'this' to 'p' (not included) inline void join(CDLList& p) { swap_pointers(p._prev, _prev); p._prev->_next = &p; _prev->_next = this; };