void cmd_load(char *s) { FILE *in; move m; char *filename; filename = (s[1] == 0) ? "bce.saved" : ++s; in = fopen(filename, "r"); if (!in) { printf("error opening saved game: %s\n", filename); return; } initialize(); computer[0] = 0; computer[1] = 0; while(!feof(in)) { fscanf(in, "%u", &m); if (feof(in)) break; domove(m); /* printf("Move: %s\n", movestring(m)); */ } printf("- Board Loaded -\n"); printboard(); countmaterial(); fclose(in); }
/* returns the gradient with respect to weight w in board *b using the formulat (f(x+h)-f(x)) / h */ double gradient(int w, chessboard *b, int index) { int v1, v2; chessboard *temp_board = board; board = b; if (gamemode != actualmode()) change_gamemode(actualmode(), 0); countmaterial(); v1 = eval_for_white(); base_weights[w] += EPSILON; countmaterial(); v2 = eval_for_white(); base_weights[w] -= EPSILON; /* restore weight */ board = temp_board; /* restore board */ return (double)(v2-v1)/(double)EPSILON; }
void cmd_edit(char *s) { #if 0 char str[80]; int color = WHITE; board->flags = 0; for(;;) { fgets(str, 80, stdin); if (!strcmp(str,"#\n")) clearboard(); else if (!strcmp(str, ".\n")) break; else if (!strcmp(str, "c\n")) color=opp(color); else if (!strcmp(str, "C\n")) color=opp(color); else { int f, r; chesspiece p; f = str[1]-'a'; r = str[2]-'1'; p = lookup(str[0]); if (color==WHITE) p &= ~(1); else p |= 1; setpiece(f,r,p); } } countmaterial(); /* set up castling rights */ if ((board->kings[WHITE]==E1)&&(getpiece__(H1)==WROOK)) board->flags |= wkc; if ((board->kings[WHITE]==E1)&&(getpiece__(A1)==WROOK)) board->flags |= wqc; if ((board->kings[BLACK]==E8)&&(getpiece__(H8)==BROOK)) board->flags |= bkc; if ((board->kings[BLACK]==E8)&&(getpiece__(A8)==BROOK)) board->flags |= bqc; compute_hash(); #endif }
void save_leaf(move *pv, int n, int value, int hashed) { #ifndef LEARNING return; #else int s_ply = ply; int searched_value = -1; int stored_board_value = -1; if (tomove() != WHITE) value = -value; stored.search_results[stored.index] = value; /* first check our stored position */ if (stored.boards[stored.index]->piececount[0]>0) { chessboard *temp_board = board; board = stored.boards[stored.index]; countmaterial(); stored_board_value = eval_for_white(); board = temp_board; countmaterial(); if (((stored_board_value > (value - EVAL_INTERVAL)) && (stored_board_value < (value + EVAL_INTERVAL))) || (value > WIN - 50) || (value < LOSE + 50)) { stored.usable[stored.index] = 1; stored.actual[stored.index] = stored_board_value; printf("STORING: qsearch board = %d\n", stored_board_value); } } /* then check to see if our value is the same as our last search */ if (!stored.usable[stored.index]) { if ((stored.search_results[stored.index] == stored.search_results[stored.index-1])) { memcpy(stored.boards[stored.index], stored.boards[stored.index-1], sizeof(chessboard)); stored.usable[stored.index] = 1; stored.actual[stored.index] = stored.actual[stored.index]-1; printf("STORING: previous board = %d\n", stored.search_results[stored.index-1]); } } /* lastly check to see if our pv leads to a correct board eval */ if (!stored.usable[stored.index]) { int i; printf("pv: "); for (i=0;i<n;i++) { if (pv[i] == dummymove) break; domove(pv[i]); printf("%s ", movestring(pv[i])); } printf("\n"); searched_value = eval_for_white(); if ((searched_value > value - EVAL_INTERVAL)&& (searched_value < value + EVAL_INTERVAL)) { memcpy(stored.boards[stored.index], board, sizeof(chessboard)); stored.usable[stored.index] = 1; stored.actual[stored.index] = searched_value; printf("STORING: pv board = %d\n", searched_value); } else { printf("!usable: stored_position %d, " "searched %d, previous %d, stored %d\n", stored_board_value, searched_value, stored.search_results[stored.index-1], value); } while (ply>s_ply) undomove(); } #endif }
void update_weights(int winner) { #ifdef LEARNING int unusable = 0; #ifndef USE_POW double lambdas[MAX_PLIES]; double temp_lambda; #endif double max, min; int weight_max = 0, weight_min = 0; double **gradients; int w, p, n = stored.index; if (n < 2) return; tellics("set open 0\n"); memset(d,0,sizeof(d)); /* pre calculate lambda powers */ #ifndef USE_POW temp_lambda = 1.0; for (p=0;p<MAX_PLIES;p++) { lambdas[p] = temp_lambda; temp_lambda *= TD_LAMBDA; } #endif #define SMOOTH_EVAL #ifdef SMOOTH_EVAL tanhvector[1] = tanh(EVAL_SCALE*stored.search_results[1]); for (p=2;p<n;p++) { double tmp; double normalized = stored.search_results[p]; tanhvector[p] = tanh(EVAL_SCALE*normalized); if (stored.search_results[p] > WIN - 50) tmp = 1.0; else if (stored.search_results[p] < LOSE + 50) tmp = -1.0; else tmp = tanhvector[p]; d[p-1] = (tmp-tanhvector[p-1]); } #else for (p=2;p<n-1;p++) { if (stored.search_results[p] > WIN - 50) d[p-1] = stored.search_results[p] - stored.search_results[p-1]; else if (stored.search_results[p] < LOSE + 50) d[p-1] = stored.search_results[p] - stored.search_results[p-1]; else d[p-1] = stored.search_results[p] - stored.search_results[p-1]; } #endif max = 0.0; min = 100000.0; gradients = gradientvector(LAST_WEIGHT, n); printf("Adjusting weights\n"); printf("Number of weights: %d\n", LAST_WEIGHT); printf("Number of plies: %d\n", n); for (w = PAWN_VALUE; w < LAST_WEIGHT; w ++) { if (!xboard_mode && !robo_mode) if (w % 20 == 0) printf("."); delta[w] = 0.0; for (p=1;p<n;p++) { int j; double S2 = 0.0; unusable = 0; printf("p: %d\t", p); for (j=1;j<p-1;j++) { if (stored.usable[j]) { double grad = /* = sech^2 * EVAL_SCALE * grad (chain rule) */ (1.0 - tanhvector[j] * tanhvector[j]) * EVAL_SCALE * gradients[w][j]; #ifdef USE_POW S2 += pow(TD_LAMBDA, p-j) * grad; #else S2 += lambdas[p-j] * grad; #endif } else { unusable ++; } } delta[w] += d[p] * S2 / EVAL_SCALE; } /* update weight accordingly */ base_weights[w] += TD_ALPHA * delta[w]; if (delta[w] > max) { max = delta[w]; weight_max=base_weights[w]; } else if (delta[w] < min) { min = delta[w]; weight_min=base_weights[w]; } } if (!xboard_mode && !robo_mode) printf("\n"); printf("weights adjusted\n"); countmaterial(); if (!xboard_mode && !robo_mode) { printf("unusable states = %d\n", unusable); printf("min = %f (%d), max = %f (%d)\n", min, weight_min, max, weight_max); } release_gradients(gradients, LAST_WEIGHT, n); store_weight_history(); #endif free_learning(); tellics("set open 1\n"); }
void cmd_fen(char *s) { char pos[80]; char color; char castling[4]; char enpassante[2]; int halfmove, fullmove; int f, r, i; FILE *in = fopen(s+1, "r"); if (!in) { printf("cmd_fen(): error opening %s\n", s+1); return; } change_gamemode(MIDGAME, 1); fscanf(in, "%s %c %s %s %d %d", pos, &color, castling, enpassante, &halfmove, &fullmove); printf("pos: %s\ncolor: %c\ncastling: %s\nenpassante: %s\n", pos, color, castling, enpassante); for (i=0;i<64;i++) setpiece__(i,empty); f = 0; r = 7; for (i=0;i<strlen(pos);i++) { chesspiece p; if (pos[i]=='/') { r--; f=0; printf("new rank: %d\n", r); } else if ((pos[i]>='1')&&(pos[i]<='9')) { f += pos[i]-'0'; } else if ((p=lookup(pos[i]))) { setpiece(f,r,p); printf("%c @ %c%d\n", rep(p), f+'a',r); f++; } else { printf("unknown character in fen position string: %s[%d]\n", pos, i); exit(EXIT_FAILURE); } } countmaterial(); board->flags = 0; ply = 0; if (!strcmp(enpassante, "-")) { gamestack[ply]=dummymove; } else { int file = enpassante[0]-'a'; int rank = enpassante[1]-'1'; board->flags |= enp; if (rank == 4) gamestack[ply] = MV(SQ(file,6), SQ(file,4)); else if (rank==3) gamestack[ply] = MV(SQ(file,1), SQ(file,3)); else printf("cmd_fen(): error parsing enpassante square\n"); } ply++; if (strchr(castling, 'Q')) board->flags |= wqc; if (strchr(castling, 'K')) board->flags |= wkc; if (strchr(castling, 'q')) board->flags |= bqc; if (strchr(castling, 'k')) board->flags |= bkc; if (color=='w') board->flags &= ~turn_flag; else if (color=='b') board->flags |= turn_flag; else printf("cmd_fen(): error parsing color\n"); }
void cmd_set(char *s) { struct v_struct var_structs[]= { { "searchdepth", &searchdepth }, { "searchtime", &searchtime }, { "highlight", &highlight }, { "wclock", &chessclock[WHITE] }, { "bclock", &chessclock[BLACK] }, { "inc", &clockinc }, { "promopiece", &promopiece}, { "pawn", &weights[PAWN_VALUE] }, { "knight", &weights[KNIGHT_VALUE] }, { "bishop", &weights[BISHOP_VALUE] }, { "rook", &weights[ROOK_VALUE] }, { "queen", &weights[QUEEN_VALUE] }, { "search", &search }, { "explain", &explain_mode }, { NULL, NULL } }; if (s) { int found = 0; int i; char *v = malloc(strlen(s)+1); char *valuestr = malloc(strlen(s)+1); memset(v, 0, strlen(s)); sscanf(s, "%s %s", v, valuestr); for (i=0; var_structs[i].name; i++) { if (!strcasecmp(var_structs[i].name, v)) { if (strcmp(v,"search")) { int value; sscanf(valuestr, "%d", &value); *((int *)var_structs[i].value) = value; printf("\tSetting %s to %d\n", v, value); } else { /* if (!strcmp(valuestr,"ab")) */ /* search=alphabeta_search; */ /* else if (!strcmp(valuestr,"abt")) */ /* search=alphabeta_tables; */ /* else if (!strcmp(valuestr,"ns")) */ /* search=negascout_search; */ /* else if (!strcmp(valuestr,"nst")) */ /* search=negascout_tables; */ /* else if (!strcmp(valuestr,"nm")) */ /* search=negamax_search; */ /* else */ /* printf("invalid value for search\n"); */ } found = 1; } } if (!found) { if (strcmp(v,"")) printf("\tVariable not recognized\n"); printf("\t- Available variables -\n"); for (i=0; var_structs[i].name; i++) { if (strcmp(var_structs[i].name,"search")) { output("\t%-12s = %10d\n", var_structs[i].name, *((int*)var_structs[i].value)); } else { /* if (search==alphabeta_search) */ /* output("\t%-12s = %10s\n", var_structs[i].name, "ab"); */ /* if (search==alphabeta_tables) */ /* output("\t%-12s = %10s\n", var_structs[i].name, "abt"); */ /* else if (search==negascout_search) */ /* output("\t%-12s = %10s\n", var_structs[i].name, "ns"); */ /* else if (search==negascout_tables) */ /* output("\t%-12s = %10s\n", var_structs[i].name, "nst"); */ /* else if (search==negamax_search) */ /* output("\t%-12s = %10s\n", var_structs[i].name, "nm"); */ } } } free(v); free(valuestr); } countmaterial(); }