// Test if values persist accross transactions int test_general_2(Thread * Self) { int num_items=10; int res1; printf("Testing if values persist across transactions.\n"); TxStart (Self, 0) ; board_set(Self,num_items,15); if(!TXCOMMIT(Self)) { assert(0); } TxStart (Self, 0) ; res1=board_check(Self,num_items,15); if(!TXCOMMIT(Self)) { assert(0); } assert(res1); TxStart (Self, 0) ; board_set(Self,num_items,16); board_set(Self,num_items,17); if(!TXCOMMIT(Self)) { assert(0); } TxStart (Self, 0) ; res1=board_check(Self,num_items,17); if(!TXCOMMIT(Self)) { assert(0); } assert(res1); return 0; }
void board_move_tile(BoardPtr b, int index_origin, int index_destinazione) { if (board_get(b, index_origin) != NULL && board_get(b, index_destinazione) == NULL) { board_set(b, board_get(b, index_origin), index_destinazione); board_set(b, NULL, index_origin); board_update_freepos(b); } }
int board_solve(board_t *board) { if(board->count == 0) { return 0; } else { uint8_t u, l, offset = 0, lx = 0, ly = 0, u_max = 0, o_min = 9; board_t current; // Identify the maximum number of indentified squares per // unit (except those completely identified). for (u = 0; u < 9; u++) { if(board->unit_count[u] > u_max && board->unit_count[u] < 9) { u_max = board->unit_count[u]; } } // Find the square with the minimum number of possible options // within a unit with the maximum number of identified // squares. for (u = 0; u < 9; u++) { if(board->unit_count[u] != u_max) { continue; } uint8_t x, y, ui = (u % 3) * 3, uj = (u / 3) * 3; for (y = uj; y < (uj + 3); y++) { for (x = ui; x < (ui + 3); x++) { uint8_t o = board_offset(x, y); if(board->values[o] == 0 && board->options_count[o] < o_min ) { o_min = board->options_count[o]; lx = x; ly = y; offset = o; } } } } // Use this square to explore recursively for (l = 1; l < 10; l++) { uint16_t m = value_to_option(l); // We iterate on the valid options for the square if(!(m & board->options[offset])) { continue; } board_copy(¤t, board); // Work on a copy of the board if(board_set(¤t, lx, ly, l) == 0 && board_check_single(¤t) == 0 && board_solve(¤t) == 0) { // The value we tried was a success copy back the result board_copy(board, ¤t); return 0; } } } return 1; }
VALUE board_set_coord( VALUE self, VALUE c, VALUE p ) { if( c == Qnil ) { return Qnil; } return board_set( self, rb_funcall( c, id_x, 0 ), rb_funcall( c, id_y, 0 ), p ); }
//loads the saved game from a slot static void load_game(gui_control* window, int slot) { char fileName[100]; char gameName[50]; int player_map[] = { 2, 0, 1 }; gui_control* players_menu; int player; board* game_board; linked_list* games; linked_list_node* game_node; game* g; int i, j, val; FILE* f; sprintf(fileName, "saveload%d.data", slot); f = fopen(fileName, "r"); if (f == NULL) { printf("no game found for saved game %d\n", slot); return; } fscanf(f, "%s", gameName); fscanf(f, "%d", &player); games = games_get(); game_node = games->head; while (game_node != NULL) { g = (game*)game_node->item; if (strcmp(g->name, gameName) == 0) break; game_node = game_node->next; } if (game_node == NULL) { printf("no game found for saved game %d\n", slot); return; } game_board = g->create_initial_state(); for (i = 0; i < game_board->rows; i++) { for (j = 0; j < game_board->cols; j++) { fscanf(f, "%d", &val); val = player_map[val + 1]; // -1 => 2; 0 => 0; 1=>1 board_set(game_board, i, j ,val); } } fclose(f); game_set_next_game(g); game_set_game_state(game_board, player); players_menu = menu_players_create(); gui_child_push(window, players_menu); }
// Test abort - without retry (global variables) int test_abort_1(Thread * Self) { intptr_t num_items=10; TxStart (Self, 0) ; board_set(Self,num_items,52); board_check(Self,num_items,52); TXCOMMIT(Self); TxStart (Self, 0) ; board_set(Self,num_items,53); board_check(Self,num_items,53); TxAbort(Self, 0); TxStart (Self, 0) ; board_check(Self,num_items,52); TXCOMMIT(Self); return 0; }
/** * @brief ui_ggs_update * * Update a game. * * @param ui User Interface. */ static void ui_ggs_update(UI *ui) { char buffer[256], s_move[4]; Play *play; int edax_turn, turn; Board board[1]; printf("[received GGS_BOARD_UPDATE]\n"); // set correct played game if (strcmp(ui->ggs->board->player[0].name, ui->ggs->me) == 0) { play = ui->play; edax_turn = BLACK; } else if (strcmp(ui->ggs->board->player[1].name, ui->ggs->me) == 0) { play = ui->play + 1; edax_turn = WHITE; } else { return ; } if (!ui->ggs->board->match_type->is_synchro) play = ui->play; // set board as an edax's board sprintf(buffer, "%s %c", ui->ggs->board->board, ui->ggs->board->turn); turn = board_set(board, buffer); // update the board... if possible if (!play_move(play, ui->ggs->board->move)) { info("<Updating with bad move %s>\n", move_to_string(ui->ggs->board->move, play->player, s_move)); } if (!board_equal(board, play->board)) { // may happens when game diverges info("<Resynchronize boards: diverging games>\n"); *play->board = *board; play->player = turn; } if (turn != play->player) { // should never happen: TODO fatal error? printf("[WARNING: updating player's turn]\n"); play->player = turn; } printf("[%s's turn in game %s]\n", ui->ggs->board->player[play->player].name, ui->ggs->board->id); // playing same game... ? ui->is_same_play = (!ui->ggs->board->match_type->is_synchro || board_equal(ui->play[0].board, ui->play[1].board)); if (ui->is_same_play) printf("<Playing same game...>\n"); // set time & start thinking if (play->player == edax_turn) { printf("<My turn>\n"); ui_ggs_play(ui, edax_turn); } else { printf("<Opponent turn>\n"); ui_ggs_ponder(ui, edax_turn); } }
int moveUp(struct game * input ) { //forward columns int size = input->size; int col = 0, cell = 0, localScore = 0 , offset; bool hasMoved = false; for(col = 0; col < size ; col++){ offset = 0; //pack the cols to the top for(int i = 0 ; i < size; i++){ cell = board_get(input,col,i); if(cell != 0){ board_set(input,col,offset,cell); if(offset != i){ board_set(input,col,i,0); hasMoved = true; } offset++; } } //compact the row if possible for(int i = 0 ; i < size; i++){ cell = board_get(input,col,i); if (cell == board_get(input,col,i+1)) { if (cell != 0) { hasMoved = true; } board_set(input,col,i,cell*2); localScore += cell*2; //shift for(int j = i+1 ; j < size; j++) { board_set(input,col,j,board_get(input,col,j+1)); } } } } if (hasMoved == false) { localScore = -1; } return localScore; return -1; }
// Test if values persist within the same transaction int test_general_1(Thread * Self) { int num_items=10; int res1,res2; printf("Testing if values persist within same Transaction\n"); // test 1 TxStart (Self, 0) ; board_set(Self,num_items,12); res1=board_check(Self,num_items,12); board_set(Self,num_items,13); res2=board_check(Self,num_items,13); if(!TXCOMMIT(Self)) { assert(0); } assert(res1); assert(res2); return 0; }
int moveRight(struct game * input ) { //backwards rows int size = input->size; int row = 0, cell = 0, localScore = 0 , offset; bool hasMoved = false; for(row = 0; row < size ; row++){ offset = size-1; //pack the row to the right for(int i = size-1 ; i >= 0 ; i--){ cell = board_get(input,i,row); if(cell != 0){ board_set(input,offset,row,cell); if(offset != i){ board_set(input,i,row,0); hasMoved = true; } offset--; } } //compact the row if possible for(int i = size-1 ; i >= 0; i--){ cell = board_get(input,i,row); if (cell == board_get(input,i-1,row)) { if (cell != 0) { hasMoved = true; } board_set(input,i,row,cell*2); localScore += cell*2; //shift for(int j = i-1 ; j >= 0; j--) { board_set(input,j,row,board_get(input,j-1,row)); } } } } if (hasMoved == false) { localScore = -1; } return localScore; }
int moveDown(struct game * input ) { //backwards columns int size = input->size; int col = 0, cell = 0, localScore = 0 , offset; bool hasMoved = false; for(col = 0; col < size ; col++){ offset = size-1; //pack the cols to the bottom for(int i = size-1 ; i >= 0 ; i--){ cell = board_get(input,col,i); if(cell != 0){ board_set(input,col,offset,cell); if(offset != i){ board_set(input,col,i,0); hasMoved = true; } offset--; } } //compact the row if possible for(int i = size-1 ; i >= 0; i--){ cell = board_get(input,col,i); if (cell == board_get(input,col,i-1)) { if(cell != 0) { hasMoved = true; } board_set(input,col,i,cell*2); localScore += cell*2; //shift for(int j = i-1 ; j >= 0; j--) { board_set(input,col,j,board_get(input,col,j-1)); } } } } if (hasMoved == false) { localScore = -1; } return localScore; }
int moveLeft(struct game * input ) { //forward rows int size = input->size; int row = 0, cell = 0, localScore = 0 , offset; bool hasMoved = false; for(row = 0; row < size ; row++){ offset = 0; //pack the row to the left for(int i = 0 ; i < size; i++){ cell = board_get(input,i,row); if(cell != 0){ board_set(input,offset,row,cell); if(offset != i){ board_set(input,i,row,0); hasMoved = true; } offset++; } } //compact row if possible for(int i = 0 ; i < size; i++){ cell = board_get(input,i,row); if (cell == board_get(input,i+1,row)) { if(cell != 0) { hasMoved = true; } board_set(input,i,row,cell*2); localScore += cell*2; //shift for(int j = i+1 ; j < size; j++) { board_set(input,j,row,board_get(input,j+1,row)); } } } } if (hasMoved == false) { localScore = -1; } return localScore; }
void insertNewNumber(struct game * input) { int row = 0, column = 0; int index, availableSquares = 0; int size = input->size; int value = 0; // count vacant squares for (row = 0; row < size; row = row + 1) { for (column = 0; column < size; column = column + 1) { value = board_get(input,row,column); if (value == 0) { availableSquares = availableSquares + 1; } } } if (availableSquares == 0) { //printf("Internal error no available square\n"); return; } // randomly pick a vacant square index = rand() % availableSquares; for (row = 0; row < size; row = row + 1) { for (column = 0; column < size; column = column + 1) { if (board_get(input,row,column) == 0) { if (index == 0) { if (rand() % 10 == 0) { board_set(input,row,column,4); } else { board_set(input,row,column,2); } return; } index = index - 1; } } } }
void board_load(board_t *board, char *line) { int i, j; for(j = 0; j < 9; j++) { for(i = 0; i < 9; i++) { uint8_t offset = board_offset(i, j); char c = line[offset]; if(c >= '1' && c <= '9') { board_set(board, i, j, c - '0'); } } } }
// RO transaction int test_general_4(Thread * Self) { int num_items=10; printf("Writing and reading. two different transactions."); TxStart (Self, 0) ; board_set(Self,num_items,52); TXCOMMIT(Self); TxStart (Self, 1) ; board_check(Self,num_items,52); TXCOMMIT(Self); // TxStart (Self, 1) ; // board_set(Self,num_items,52); // TXCOMMIT(Self); return 0; }
VALUE board_subscript_assign( int argc, VALUE *argv, VALUE self ) { if( argc == 3 && FIXNUM_P(argv[0]) && FIXNUM_P(argv[1]) ) { return board_set( self, argv[0], argv[1], argv[2] ); } else if( argc == 2 ) { return board_set_coord( self, argv[0], argv[1] ); } else { VALUE ary = rb_ary_new2( argc ); int i; for( i = 0; i < argc-1; i++ ) { rb_ary_push( ary, board_set_coord( self, argv[i], argv[argc-1] ) ); } return argv[argc-1]; } return Qnil; }
inline int test_cell(board_t *board, uint8_t x, uint8_t y, uint8_t v, uint16_t opt) { int rv = 0; uint8_t offset = board_offset(x, y); if(board->values[offset] == v) { rv = 1; } else if(board->values[offset] == 0) { if((board->options[offset] & opt)) { board->options[offset] &= (o_mask ^ opt); board->options_count[offset]--; if(board->options_count[offset] == 1) { uint8_t val = option_to_value(board->options[offset]); if(board_set(board, x, y, val)) { rv = 1; } } } } return rv; }
void board_add_tile(BoardPtr b) { int index, len, value_tile; len = intlist_len(&(b->pos_free)); index = random_between(0, len); Tile *tile; tile = malloc(sizeof(Tile)); value_tile = random_between(0, 11); if (value_tile == 0) { *tile = tile_make(4); } else *tile = tile_make(2); board_set(b, tile, index); board_update_freepos(b); }
// The function will check if there a single cell for a given value in // all units, horizontal and vertical lines. This function breaks on // finding a solution. int board_check_single_step(board_t *board) { uint8_t x, y, u, l; //////////////////////////////////////////////////////////////////// // Check all units to see if one cell value can be determined // because it's the only one left with a given option. for(u = 0; u < 9; u++) { // Checks if the unit is already full if(board->unit_count[u] == 9) { continue; } uint8_t ui = (u % 3) * 3, uj = (u / 3) * 3; for (l = 1; l < 10; l++) { // Iterate on possible values uint8_t lx = 0, ly = 0, lc = 0; uint16_t m = value_to_option(l); // Skip if the value is already used in the unit if ((m & board->unit_options[u]) == 0) { continue; } // Find if there's only one possible cell for (y = uj; y < (uj + 3) && lc < 2; y++) { for (x = ui; x < (ui + 3) && lc < 2; x++) { uint8_t o = board_offset(x, y); if((board->values[o] == 0) && (board->options[o] & m)) { lc += 1; lx = x; ly = y; } } } /* If only one possible cell, set its value. */ if(lc == 1) { return board_set(board, lx, ly, l) ? 1 : 0; } } } //////////////////////////////////////////////////////////////////// // Now do the same for horizontal lines for(y = 0; y < 9; y++) { // Checks if the hline is already full if(board->hline_count[y] == 9) { continue; } for (l = 1; l < 10; l++) { // Iterate on possible values uint8_t lx = 0, ly = 0, lc = 0; uint16_t m = value_to_option(l); // Skip if the value is already used in the hline if ((m & board->hline_options[y]) == 0) { continue; } // Find if there's only one possible cell for(x = 0; x < 9 && lc < 2; x++) { uint8_t o = board_offset(x, y); if((board->values[o] == 0) && (board->options[o] & m)) { lc += 1; lx = x; ly = y; } } if(lc == 1) { // If only one possible cell, set its value. return board_set(board, lx, ly, l) ? 1 : 0; } } } //////////////////////////////////////////////////////////////////// // Now do the same for vertical lines for(x = 0; x < 9; x++) { // Checks if the vline is already full if(board->vline_count[x] == 9) { continue; } for (l = 1; l < 10; l++) { // Iterate on possible values uint8_t lx = 0, ly = 0, lc = 0; uint16_t m = value_to_option(l); // Skip if the value is already used in the vline if ((m & board->vline_options[x]) == 0) { continue; } // Find if there's only one possible cell for(y = 0; y < 9 && lc < 2; y++) { uint8_t o = board_offset(x, y); if((board->values[o] == 0) && (board->options[o] & m)) { lc += 1; lx = x; ly = y; } } if(lc == 1) { // If only one possible cell, set its value. return board_set(board, lx, ly, l) ? 1 : 0; } } } return 0; }
/** * @brief Loop event. * @param ui user interface. */ void ui_loop_edax(UI *ui) { char *cmd = NULL, *param = NULL; Play *play = ui->play; char book_file[FILENAME_MAX]; unsigned long long histogram[129][65]; int repeat = options.repeat; histogram_init(histogram); // loop forever for (;;) { errno = 0; if (options.verbosity) { putchar('\n'); play_print(play, stdout); if (play_is_game_over(play)) printf("\n*** Game Over ***\n"); putchar('\n'); } if (log_is_open(edax_log)) { putc('\n', edax_log->f); play_print(play, edax_log->f); if (play_is_game_over(play)) fputs("\n*** Game Over ***\n", edax_log->f); putc('\n', edax_log->f); } // edax turn ? (automatic play mode) if (!ui_event_exist(ui) && !play_is_game_over(play) && (ui->mode == !play->player || ui->mode == 2)) { putchar('\n'); play_go(play, true); printf("\nEdax plays "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); if (ui->mode != 2) play_ponder(play); // proceed by reading a command } else { /* automatic rules after a game over*/ if (play_is_game_over(play)) { if (options.auto_store) play_store(play); if (options.auto_swap && ui->mode < 2) ui->mode = !ui->mode; if (options.repeat && repeat > 1) { --repeat; play_new(play); continue; } if (options.auto_quit) { return; } if (options.auto_start) { play_new(play); continue; } } putchar('>'); fflush(stdout); ui_event_wait(ui, &cmd, ¶m); log_print(edax_log, "cmd=\"%s\" ; param=\"%s\"\n", cmd, param); putchar('\n'); if (cmd == NULL) { warn("unexpected null command?\n"); continue; } // skip empty lines or commented lines if (*cmd == '\0' || *cmd == '#') { // help } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "?") == 0) { if (*param == '\0' || strcmp(param, "options") == 0) help_options(); if (*param == '\0' || strcmp(param, "commands") == 0) help_commands(); if (*param == '\0' || strcmp(param, "book") == 0) help_book(); if (*param == '\0' || strcmp(param, "base") == 0) help_base(); if (*param == '\0' || strcmp(param, "test") == 0) help_test(); // new game from standard position } else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "init") == 0) { board_init(play->initial_board); play_new(play); // new game from personnalized position } else if ((strcmp(cmd, "n") == 0 || strcmp(cmd, "new") == 0) && *param == '\0') { play_new(play); // open a saved game } else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "open") == 0 || strcmp(cmd, "load") == 0) { play_load(play, param); // save a game } else if (strcmp(cmd, "s") == 0 || strcmp(cmd, "save") == 0) { play_save(play, param); // quit } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0 || strcmp(cmd, "exit") == 0) { free(cmd); free(param); return; } else if (!options.auto_quit && (strcmp(cmd, "eof") == 0 && (ui->mode != 2 || play_is_game_over(play)))){ free(cmd); free(param); return; // undo last move } else if (strcmp(cmd, "u") == 0 || strcmp(cmd, "undo") == 0) { play_undo(play); if (ui->mode == 0 || ui->mode == 1) play_undo(play); // redo last move } else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "redo") == 0) { play_redo(play); if (ui->mode == 0 || ui->mode == 1) play_undo(play); // mode } else if (strcmp(cmd, "m") == 0 || strcmp(cmd, "mode") == 0) { ui->mode = string_to_int(param, 3); // analyze a game } else if (strcmp(cmd, "a") == 0 || strcmp(cmd, "analyze") == 0 || strcmp(cmd, "analyse") == 0) { play_analyze(play, string_to_int(param, play->n_game)); // set a new initial position } else if (strcmp(cmd, "setboard") == 0) { play_set_board(play, param); // vertical mirror } else if (strcmp(cmd, "vmirror") == 0) { play_symetry(play, 2); // horizontal mirror } else if (strcmp(cmd, "hmirror") == 0) { play_symetry(play, 1); // rotate } else if (strcmp(cmd, "rotate") == 0) { int angle = string_to_int(param, 90) % 360; if (angle < 0) angle += 360; switch (angle) { case 90: play_symetry(play, 5); break; case 180: play_symetry(play, 3); break; case 270: play_symetry(play, 6); break; default: warn("Rotate angle should be 90°, 180° or 270°"); break; } // direct symetry... } else if (strcmp(cmd, "symetry") == 0) { int sym = string_to_int(param, 1); if (sym < 0 || sym >= 16) warn("symetry parameter should be a number between 0 and 15\n"); else { if (sym & 8) play->player ^= 1; play_symetry(play, sym & 7); } // play a serie of moves } else if (strcmp(cmd, "play") == 0) { string_to_lowercase(param); play_game(play, param); // force edax to play an opening } else if (strcmp(cmd, "force") == 0) { string_to_lowercase(param); play_force_init(play, param); // solve a set of problems } else if (strcmp(cmd, "solve") == 0) { char problem_file[FILENAME_MAX + 1], *hard_file; hard_file = parse_word(param, problem_file, FILENAME_MAX); parse_word(hard_file, hard_file, FILENAME_MAX); obf_test(play->search, problem_file, hard_file); search_set_observer(play->search, edax_observer); // convert a set of problems in a .script file to a .obf file } else if (strcmp(cmd, "script-to-obf") == 0) { char script_file[FILENAME_MAX + 1], *obf_file; obf_file = parse_word(param, script_file, FILENAME_MAX); parse_word(obf_file, obf_file, FILENAME_MAX); script_to_obf(play->search, script_file, obf_file); search_set_observer(play->search, edax_observer); } else if (strcmp(cmd, "select-hard") == 0) { char full_file[FILENAME_MAX + 1], *hard_file; hard_file = parse_word(param, full_file, FILENAME_MAX); parse_word(hard_file, hard_file, FILENAME_MAX); obf_filter(full_file, hard_file); // game/position enumeration } else if (strcmp(cmd, "count") == 0) { char count_cmd[16], *count_param; int depth = 10, size = 8; count_param = parse_word(param, count_cmd, 15); count_param = parse_int(count_param, &depth); BOUND(depth, 1, 90, "max-ply"); if (count_param) parse_int(count_param, &size); BOUND(size, 6, 8, "board-size"); if (strcmp(count_cmd, "games") == 0) { // game enumeration quick_count_games(play->board, depth, size); } else if (strcmp(count_cmd, "positions") == 0) { // position enumeration count_positions(play->board, depth, size); } else if (strcmp(count_cmd, "shapes") == 0) { // shape enumeration count_shapes(play->board, depth, size); } else { warn("Unknown count command: \"%s %s\"\n", cmd, param); } } else if (strcmp(cmd, "perft") == 0) { int depth = 14; depth = string_to_int(param, 10); BOUND(depth, 1, 90, "max-ply"); count_games(play->board, depth); // game/position enumeration } else if (strcmp(cmd, "estimate") == 0) { int n = 1000; n = string_to_int(param, 10); BOUND(n, 1, 2000000000, "max-trials"); estimate_games(play->board, n); // seek highest mobility } else if (strcmp(cmd, "mobility") == 0) { int t = 3600; // 1 hour t = string_to_int(param, 10); BOUND(t, 1, 3600*24*365*10, "max time"); seek_highest_mobility(play->board, t); // seek a position } else if (strcmp(cmd, "seek") == 0) { Board target; Line solution; board_set(&target, param); line_init(&solution, play->player); if (seek_position(&target, play->board, &solution)) { printf("Solution found:\n"); line_print(&solution, 200, " ", stdout); putchar('\n'); } // bench (a serie of low level tests). } else if (strcmp(cmd, "bench") == 0) { bench(); // wtest test the engine against wthor theoretical scores } else if (strcmp(cmd, "wtest") == 0) { wthor_test(param, play->search); // make wthor games played by "Edax (Delorme)" as "Etudes" tournament. } else if (strcmp(cmd, "edaxify") == 0) { wthor_edaxify(param); // wtest test the engine against wthor theoretical scores } else if (strcmp(cmd, "weval") == 0) { wthor_eval(param, play->search, histogram); histogram_print(histogram); histogram_stats(histogram); histogram_to_ppm("weval.ppm", histogram); // go think! } else if (strcmp(cmd, "go") == 0) { if (play_is_game_over(play)) printf("\n*** Game Over ***\n"); else { play_go(play, true); printf("\nEdax plays "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); } // hint for [n] moves } else if (strcmp(cmd, "hint") == 0) { int n = string_to_int(param, 1); BOUND(n, 1, 60, "n_moves"); play_hint(play, n); // stop thinking } else if (strcmp(cmd, "stop") == 0) { ui->mode = 3; // user move } else if (play_user_move(play, cmd)) { printf("\nYou play "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); // debug pv } else if (strcmp(cmd, "debug-pv") == 0) { Move move[1]; if (parse_move(param, play->board, move) != param) { search_set_board(play->search, play->board, play->player); pv_debug(play->search, move, stdout); } } else if (strcmp(cmd, "options") == 0) { options_dump(stdout); #ifdef __unix__ } else if (strcmp(cmd, "resources") == 0) { struct rusage u; long long t; getrusage(RUSAGE_SELF, &u); t = 1000 * u.ru_utime.tv_sec + u.ru_utime.tv_usec / 1000; printf("user cpu time: "); time_print(t, false, stdout); printf("\n"); t = 1000 * u.ru_stime.tv_sec + u.ru_stime.tv_usec / 1000; printf("system cpu time: "); time_print(t, false, stdout); printf("\n"); printf("max resident memory: %ld\n", u.ru_maxrss); printf("page fault without I/O: %ld\n", u.ru_minflt); printf("page fault with I/O: %ld\n", u.ru_majflt); printf("number of input: %ld\n", u.ru_inblock); printf("number of output: %ld\n", u.ru_oublock); printf("number of voluntary context switch: %ld\n", u.ru_nvcsw); printf("number of unvoluntary context switch: %ld\n\n", u.ru_nivcsw); #endif // opening name } else if (strcmp(cmd, "opening") == 0) { const char *name; name = play_show_opening_name(play, opening_get_english_name); if (name == NULL) name = "?"; puts(name); // opening name in french } else if (strcmp(cmd, "ouverture") == 0) { const char *name; name = play_show_opening_name(play, opening_get_french_name); if (name == NULL) name = "?"; puts(name); // opening book commands } else if (strcmp(cmd, "book") == 0 || strcmp(cmd, "b") == 0) { char book_cmd[FILENAME_MAX + 1], *book_param; int val_1, val_2; Book *book = play->book; book->search = play->search; book->search->options.verbosity = book->options.verbosity; book_param = parse_word(param, book_cmd, FILENAME_MAX); // store the last played game if (strcmp(book_cmd, "store") == 0) { play_store(play); // turn book usage on } else if (strcmp(book_cmd, "on") == 0) { // learn options.book_allowed = true; // turn book usage off } else if (strcmp(book_cmd, "off") == 0) { // learn options.book_allowed = false; // set book randomness } else if (strcmp(book_cmd, "randomness") == 0) { // learn val_1 = 0; book_param = parse_int(book_param, &val_1); options.book_randomness = val_1; // set book depth (until which to learn) } else if (strcmp(book_cmd, "depth") == 0) { // learn val_1 = 36; book_param = parse_int(book_param, &val_1); book->options.n_empties = 61 - val_1; // create a new empty book } else if (strcmp(book_cmd, "new") == 0) { val_1 = 21; book_param = parse_int(book_param, &val_1); val_2 = 36; book_param = parse_int(book_param, &val_2); book_free(book) ; book_new(book, val_1, 61 - val_2); // load an opening book (binary format) from the disc } else if (strcmp(book_cmd, "load") == 0 || strcmp(book_cmd, "open") == 0) { book_free(book) ; parse_word(book_param, book_file, FILENAME_MAX); book_load(book, book_file); // save an opening book (binary format) to the disc } else if (strcmp(book_cmd, "save") == 0) { parse_word(book_param, book_file, FILENAME_MAX); book_save(book, book_file); // import an opening book (text format) } else if (strcmp(book_cmd, "import") == 0) { book_free(book); parse_word(book_param, book_file, FILENAME_MAX); book_import(book, book_file); book_link(book); book_fix(book); book_negamax(book); book_sort(book); // export an opening book (text format) } else if (strcmp(book_cmd, "export") == 0) { parse_word(book_param, book_file, FILENAME_MAX); book_export(book, book_file); // merge an opening book to the current one } else if (strcmp(book_cmd, "merge") == 0) { Book src[1]; parse_word(book_param, book_file, FILENAME_MAX); src->search = play->search; book_load(src, book_file); book_merge(book, src); book_free(src); warn("Book needs to be fixed before usage\n"); // fix an opening book } else if (strcmp(book_cmd, "fix") == 0) { book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // negamax an opening book } else if (strcmp(book_cmd, "negamax") == 0) { book_negamax(book); // negamax nodes book_sort(book); // sort moves // check and correct solved positions of the book } else if (strcmp(book_cmd, "correct") == 0) { book_correct_solved(book); // do nothing (or edax is buggy) book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // prune an opening book } else if (strcmp(book_cmd, "prune") == 0) { book_prune(book); // remove unreachable lines. book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // show the current position as stored in the book } else if (strcmp(book_cmd, "show") == 0) { book_show(book, play->board); // show book general information } else if (strcmp(book_cmd, "info") == 0) { book_info(book); // show book general information } else if (strcmp(book_cmd, "stats") == 0) { book_stats(book); // set book verbosity } else if (strcmp(book_cmd, "verbose") == 0) { parse_int(book_param, &book->options.verbosity); book->search->options.verbosity = book->options.verbosity; // analyze a game from the opening book point of view } else if (strcmp(book_cmd, "a") == 0 || strcmp(book_cmd, "analyze") == 0 || strcmp(book_cmd, "analyse") == 0) { val_1 = string_to_int(book_param, play->n_game); BOUND(val_1, 1, play->n_game, "depth"); play_book_analyze(play, val_1); // add positions from a game database } else if (strcmp(book_cmd, "add") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); base_load(base, book_file); book_add_base(book, base); base_free(base); // check positions from a game database } else if (strcmp(book_cmd, "check") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); base_load(base, book_file); book_check_base(book, base); base_free(base); // extract positions } else if (strcmp(book_cmd, "problem") == 0) { val_1 = 24; book_param = parse_int(book_param, &val_1); BOUND(val_1, 0, 60, "number of empties"); val_2 = 10; book_param = parse_int(book_param, &val_2); BOUND(val_2, 1, 1000000, "number of positions"); book_extract_positions(book, val_1, val_2); // extract pv to a game database } else if (strcmp(book_cmd, "extract") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); book_extract_skeleton(book, base); base_save(base, book_file); base_free(base); // add position using the "deviate algorithm" } else if (strcmp(book_cmd, "deviate") == 0) { val_1 = 2; book_param = parse_int(book_param, &val_1); BOUND(val_1, -129, 129, "relative error"); val_2 = 4; book_param = parse_int(book_param, &val_2); BOUND(val_2, 0, 65, "absolute error"); book_deviate(book, play->board, val_1, val_2); // add position using the "enhance algorithm" } else if (strcmp(book_cmd, "enhance") == 0) { val_1 = 2; book_param = parse_int(book_param, &val_1); BOUND(val_1, 0, 129, "midgame error"); val_2 = 4; book_param = parse_int(book_param, &val_2); BOUND(val_2, 0, 129, "endcut error"); book_enhance(book, play->board, val_1, val_2); // add position by filling hole in the book } else if (strcmp(book_cmd, "fill") == 0) { val_1 = 1; book_param = parse_int(book_param, &val_1); BOUND(val_1, 1, 61, "fill depth"); book_fill(book, val_1); // add positions by expanding positions with no-link } else if (strcmp(book_cmd, "play") == 0) { book_play(book); // add positions by expanding positions with no-link } else if (strcmp(book_cmd, "deepen") == 0) { book_deepen(book); // add book positions to the hash table } else if (strcmp(book_cmd, "feed-hash") == 0) { book_feed_hash(book, play->board, play->search); // wrong command ? } else { warn("Unknown book command: \"%s %s\"\n", cmd, param); } book->options.verbosity = book->search->options.verbosity; book->search->options.verbosity = options.verbosity; /* base TODO: add more actions... */ } else if (strcmp(cmd, "base") == 0) { char base_file[FILENAME_MAX + 1]; char base_cmd[512], *base_param; Base base[1]; base_init(base); base_param = parse_word(param, base_cmd, 511); base_param = parse_word(base_param, base_file, FILENAME_MAX); // extract problem from a game base if (strcmp(base_cmd, "problem") == 0) { char problem_file[FILENAME_MAX + 1]; int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_param = parse_word(base_param, problem_file, FILENAME_MAX); base_load(base, base_file); base_to_problem(base, n_empties, problem_file); // extract FEN } else if (strcmp(base_cmd, "tofen") == 0) { char problem_file[FILENAME_MAX + 1]; int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_param = parse_word(base_param, problem_file, FILENAME_MAX); base_load(base, base_file); base_to_FEN(base, n_empties, problem_file); // correct erroneous games } else if (strcmp(base_cmd, "correct") == 0) { int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_load(base, base_file); base_analyze(base, play->search, n_empties, true); remove(base_file); base_save(base, base_file); // check erroneous games } else if (strcmp(base_cmd, "check") == 0) { int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_load(base, base_file); base_analyze(base, play->search, n_empties, false); // terminate unfinished base } else if (strcmp(base_cmd, "complete") == 0) { base_load(base, base_file); base_complete(base, play->search); remove(base_file); base_save(base, base_file); // convert a base to another format } else if (strcmp(base_cmd, "convert") == 0) { base_load(base, base_file); base_param = parse_word(base_param, base_file, FILENAME_MAX); base_save(base, base_file); // make a base unique by removing identical games } else if (strcmp(base_cmd, "unique") == 0) { base_load(base, base_file); base_param = parse_word(base_param, base_file, FILENAME_MAX); base_unique(base); base_save(base, base_file); // compare two game bases } else if (strcmp(base_cmd, "compare") == 0) { char base_file_2[FILENAME_MAX + 1]; base_param = parse_word(base_param, base_file_2, FILENAME_MAX); base_compare(base_file, base_file_2); } else { warn("Unknown base command: \"%s %s\"\n", cmd, param); } base_free(base); /* edax options */ } else if (options_read(cmd, param)) { options_bound(); // parallel search changes: if (search_count_tasks(play->search) != options.n_task) { play_stop_pondering(play); search_set_task_number(play->search, options.n_task); } /* switch to another protocol */ } else if (strcmp(cmd, "nboard") == 0 && strcmp(param, "1") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "nboard"); ui->init(ui); ui->loop(ui); return; } else if (strcmp(cmd, "xboard") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "xboard"); ui->init(ui); ui->loop(ui); return; } else if (strcmp(cmd, "engine-protocol") == 0 && strcmp(param, "init") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "cassio"); engine_loop(); return; } else if (strcmp(cmd, "protocol_version") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "gtp"); ui->init(ui); puts("= 2\n"); fflush(stdout); ui->loop(ui); return; #ifdef TUNE_EDAX /* edax tuning */ } else if (strcmp(cmd, "tune") == 0) { char problem[FILENAME_MAX]; char *w_name; play_stop_pondering(play); w_name = parse_word(param, problem, FILENAME_MAX); tune_move_evaluate(play->search, problem, parse_skip_spaces(w_name)); search_set_observer(play->search, edax_observer); #endif /* illegal cmd/move */ } else { warn("Unknown command/Illegal move: \"%s %s\"\n", cmd, param); } } } }
void do_move(Board *board, Move *move, Undo *undo) { TOGGLE_HASH(board); undo->piece = board->squares[move->src]; undo->capture = board->squares[move->dst]; undo->castle = board->castle; undo->ep = board->ep; board_set(board, move->src, EMPTY); if (move->promotion) { board_set(board, move->dst, move->promotion | board->color); } else { board_set(board, move->dst, undo->piece); } board->ep = 0L; if (undo->piece == WHITE_PAWN) { bb src = BIT(move->src); bb dst = BIT(move->dst); if ((src & 0x000000000000ff00L) && (dst & 0x00000000ff000000L)) { board->ep = BIT(move->src + 8); } if (dst == undo->ep) { board_set(board, move->dst - 8, EMPTY); } } else if (undo->piece == BLACK_PAWN) { bb src = BIT(move->src); bb dst = BIT(move->dst); if ((src & 0x00ff000000000000L) && (dst & 0x000000ff00000000L)) { board->ep = BIT(move->src - 8); } if (dst == undo->ep) { board_set(board, move->dst + 8, EMPTY); } } else if (undo->piece == WHITE_KING) { board->castle &= ~CASTLE_WHITE; if (move->src == 4 && move->dst == 6) { board_set(board, 7, EMPTY); board_set(board, 5, WHITE_ROOK); } else if (move->src == 4 && move->dst == 2) { board_set(board, 0, EMPTY); board_set(board, 3, WHITE_ROOK); } } else if (undo->piece == BLACK_KING) { board->castle &= ~CASTLE_BLACK; if (move->src == 60 && move->dst == 62) { board_set(board, 63, EMPTY); board_set(board, 61, BLACK_ROOK); } else if (move->src == 60 && move->dst == 58) { board_set(board, 56, EMPTY); board_set(board, 59, BLACK_ROOK); } } if (move->src == 0 || move->dst == 0) { board->castle &= ~CASTLE_WHITE_QUEEN; } if (move->src == 7 || move->dst == 7) { board->castle &= ~CASTLE_WHITE_KING; } if (move->src == 56 || move->dst == 56) { board->castle &= ~CASTLE_BLACK_QUEEN; } if (move->src == 63 || move->dst == 63) { board->castle &= ~CASTLE_BLACK_KING; } board->color ^= BLACK; board->hash ^= HASH_COLOR; board->pawn_hash ^= HASH_COLOR; TOGGLE_HASH(board); }
void undo_move(Board *board, Move *move, Undo *undo) { TOGGLE_HASH(board); board_set(board, move->src, undo->piece); board_set(board, move->dst, undo->capture); board->castle = undo->castle; board->ep = undo->ep; if (undo->piece == WHITE_PAWN) { if (BIT(move->dst) == undo->ep) { board_set(board, move->dst - 8, BLACK_PAWN); } } else if (undo->piece == BLACK_PAWN) { if (BIT(move->dst) == undo->ep) { board_set(board, move->dst + 8, WHITE_PAWN); } } else if (undo->piece == WHITE_KING) { if (move->src == 4 && move->dst == 6) { board_set(board, 7, WHITE_ROOK); board_set(board, 5, EMPTY); } else if (move->src == 4 && move->dst == 2) { board_set(board, 0, WHITE_ROOK); board_set(board, 3, EMPTY); } } else if (undo->piece == BLACK_KING) { if (move->src == 60 && move->dst == 62) { board_set(board, 63, BLACK_ROOK); board_set(board, 61, EMPTY); } else if (move->src == 60 && move->dst == 58) { board_set(board, 56, BLACK_ROOK); board_set(board, 59, EMPTY); } } board->color ^= BLACK; board->hash ^= HASH_COLOR; board->pawn_hash ^= HASH_COLOR; TOGGLE_HASH(board); }