⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 book.c

📁 一款运行在linux上的象棋游戏。用GTK/GNOME环境下用GLADE开发。
💻 C
📖 第 1 页 / 共 2 页
字号:
      return BOOK_EIO;    }    digest_bits = MAX_DIGEST_BITS;    /* We use read_book() here only to allocate memory */    if (read_book(wfp) == BOOK_ENOMEM) {      return BOOK_ENOMEM;    }  }  return BOOK_SUCCESS;}/* * Store the position and results of last search * if and only if in the first 10 moves of the game. * This routine is called after the computer makes its * most recent move. Lastly, after the 10th move, on  * the 11th move, store the data out to the running file. *//* * NOTE: Before you build a book, you have to call * BookBuilderOpen() now, after building it BookBuilderClose() * in order to actually write the book to disk. */int BookBuilder(short result, uint8_t side){  uint32_t i;    /* Only first BOOKDEPTH moves */  if (GameCnt > BOOKDEPTH)     return BOOK_EMIDGAME;  CalcHashKey();  for (DIGEST_START(i, HashKey);       ;        DIGEST_NEXT(i, HashKey)) {    if (DIGEST_MATCH(i, HashKey)) {      existpos++;      break;    } else if (DIGEST_EMPTY(i)) {      if (bookcnt > DIGEST_LIMIT)	return BOOK_EFULL;      bookpos[i].key = HashKey;      newpos++;      bookcnt++;      break;    } else {      bookhashcollisions++;    }  }  if (side == white) {    if (result == R_WHITE_WINS)      bookpos[i].wins++;    else if (result == R_BLACK_WINS)      bookpos[i].losses++;    else if (result == R_DRAW)      bookpos[i].draws++;  } else {    if (result == R_WHITE_WINS)      bookpos[i].losses++;    else if (result == R_BLACK_WINS)      bookpos[i].wins++;    else if (result == R_DRAW)      bookpos[i].draws++;  }  return BOOK_SUCCESS;}int BookBuilderClose(void){  /*   * IMHO the following part needs no temporary file.   * If two gnuchess invocations try to write the same   * file at the same time, this goes wrong anyway.   * Please correct me if I am wrong. If you generate   * a temporary file, try to generate it in some writable   * directory.   */  FILE *wfp;  unsigned int i;  int errcode = BOOK_SUCCESS;  wfp = fopen(BOOKRUN, "wb");  if (wfp == NULL) {    errcode = BOOK_EIO;    goto bailout_noclose;  }  if (write_magic(wfp) != BOOK_SUCCESS) {    errcode = BOOK_EIO;    goto bailout;  }  if (write_size(wfp, bookcnt) != BOOK_SUCCESS) {    errcode = BOOK_EIO;    goto bailout;  }  for (i = 0; i < DIGEST_SIZE; i++) {    if (!is_empty(i)) {      book_to_buf(i);      if (1 != fwrite(&buf, sizeof(buf), 1, wfp)) {	errcode = BOOK_EIO;	goto bailout;      }    }  }  printf("Got %d hash collisions\n", bookhashcollisions); bailout:  if (fclose(wfp) != 0) {    errcode = BOOK_EIO;  } bailout_noclose:  free(bookpos);  book_allocated = 0;  /* Let BookQuery allocate again */  bookloaded = 0;  return errcode;}/* * Return values are defined in common.h * NOTE: This function now returns BOOK_SUCCESS on * success, which is 0. So all the possible callers * should adjust to this. (At present it is only called * in iterate.c.) It used to return 1 on success before. */int BookQuery(int BKquery){  /*   * BKquery denotes format; 0 text, 1 engine    * In general out put is engine compliant, lines start with a blank   * and end with emtpy line   */  int i,j,k,icnt = 0, mcnt, found, tot, maxdistribution;  int matches[MAXMATCH] ;  leaf m[MAXMOVES];  leaf pref[MAXMOVES];  struct {    uint16_t wins;    uint16_t losses;    uint16_t draws;  } r[MAXMOVES];  FILE *rfp = NULL;  leaf *p;  short side,xside,temp;  uint32_t booksize;  int res;  if (bookloaded && !book_allocated) {    /* Something failed during loading the book */    return BOOK_ENOBOOK;  }  if (!bookloaded) {    char const * const *booktry;    bookloaded = 1;    for (booktry = bookbin; *booktry ; booktry++) {      if (!(flags & XBOARD)) {	fprintf(ofp, "Looking for opening book in %s...\n", *booktry);      }      rfp = fopen(*booktry, "rb");      /* XXX: Any further error analysis here?  -- Lukas */      if (rfp == NULL) continue;      if (!(flags & XBOARD))	fprintf(ofp,"Read opening book (%s)...\n", *booktry);      if (!check_magic(rfp)) {	fprintf(stderr, 		" File %s does not conform to the current format.\n"		" Consider rebuilding it.\n\n",		*booktry);	fclose(rfp);	rfp = NULL;      } else break; /* Success, stop search */    }    if (rfp == NULL) {      /* If appropriate print error */      if (!(flags & XBOARD) || BKquery == 1)        fprintf(ofp," No book found.\n\n");      return BOOK_ENOBOOK;    }    if (!(flags & XBOARD)) {      fprintf(ofp, "Loading book from %s.\n", *booktry);    }    /*     * The factor 1.06 is the minimum additional amount of     * free space in the hash     */    booksize = read_size(rfp) * 1.06;    for (digest_bits = 1; booksize; booksize >>= 1) {      digest_bits++;    }    res = read_book(rfp);    if (res != BOOK_SUCCESS) {      return res;    }    if (!(flags & XBOARD))      fprintf(ofp,"%d hash collisions... ", bookhashcollisions);  }        mcnt = -1;  side = board.side;  xside = 1^side;  TreePtr[2] = TreePtr[1];  GenMoves(1);  FilterIllegalMoves (1);  for (p = TreePtr[1]; p < TreePtr[2]; p++) {    MakeMove(side, &p->move);    m[icnt].move = p->move;    posshash[icnt] = HashKey;    icnt++;    UnmakeMove(xside,&p->move);  }  for (i = 0; i < icnt; i++) {    for (DIGEST_START(j,posshash[i]);	 !DIGEST_EMPTY(j);	 DIGEST_NEXT(j, posshash[i])) {      if (DIGEST_MATCH(j, posshash[i])) {	found = 0;	for (k = 0; k < mcnt; k++) 	  if (matches[k] == i) {	    found = 1;	    break;	  }	/* Position must have at least some wins to be played by book */	if (!found) {	  matches[++mcnt] = i;	  pref[mcnt].move = m[matches[mcnt]].move;	  r[i].losses = bookpos[j].losses;	  r[i].wins = bookpos[j].wins;	  r[i].draws = bookpos[j].draws;		  /* by percent score starting from this book position */	  	  pref[mcnt].score = m[i].score = 	    100*(r[i].wins+(r[i].draws/2))/	    (MAX(r[i].wins+r[i].losses+r[i].draws,1)) + r[i].wins/2;	  	}	if (mcnt >= MAXMATCH) {	  fprintf(ofp," Too many matches in book.\n\n");	  goto fini;	}	break; /* If we found a match, the following positions can not match */      }    }  }fini:    if (!(flags & XBOARD) || BKquery == 1)  {    fprintf(ofp," Opening database: %d book positions.\n",bookcnt);    if (mcnt+1 == 0) {      fprintf(ofp," In this position, there is no book move.\n\n");    } else if (mcnt+1 == 1) {      fprintf(ofp," In this position, there is one book move:\n");    } else {      fprintf(ofp," In this position, there are %d book moves:\n", mcnt+1);    }  }  /* No book moves */  if (mcnt == -1) {    return BOOK_ENOMOVES;  }  k = 0;  if (mcnt+1) {    if ( !(flags & XBOARD) || BKquery == 1 ) {      for (i = 0; i <= mcnt; i++) {	if (!(flags & XBOARD) || BKquery == 1 ) {	  SANMove(m[matches[i]].move,1);          tot = r[matches[i]].wins+r[matches[i]].draws+r[matches[i]].losses;	  fprintf(ofp," %s(%2.0f/%d/%d/%d) ",SANmv,		100.0*(r[matches[i]].wins+(r[matches[i]].draws/2.0))/tot,		r[matches[i]].wins,		r[matches[i]].losses,		r[matches[i]].draws);          if ((i+1) % 4 == 0) fputc('\n',ofp);	}      }      if (!(flags & XBOARD) || BKquery == 1 )        if (i % 4 != 0) fprintf(ofp," \n \n");    }    if (bookmode == BOOKRAND) {      k = rand();      k = k % (mcnt+1);      RootPV = m[matches[k]].move;      if (!(flags & XBOARD)) {        printf("\n(Random picked move #%d %s%s from above list)\n",k,	  algbr[FROMSQ(RootPV)],algbr[TOSQ(RootPV)]);        tot = r[matches[k]].wins+r[matches[k]].draws+r[matches[k]].losses;        if (tot != 0)          printf("B p=%2.0f\n",	   100.0*(r[matches[k]].wins+r[matches[k]].draws)/tot);        else          printf("p=NO EXPERIENCES\n");      }    } else if (bookmode == BOOKBEST) {      qsort(&pref,mcnt+1,sizeof(leaf),compare);      RootPV = pref[0].move;    } else if (bookmode == BOOKWORST) {      qsort(&pref,mcnt+1,sizeof(leaf),compare);      RootPV = pref[mcnt].move;    } else if (bookmode == BOOKPREFER) {      qsort(&pref,mcnt+1,sizeof(leaf),compare);      for (i = 0; i <= mcnt; i++) {	if (!(flags & XBOARD) || BKquery == 1) {	  SANMove(pref[i].move,1);          printf(" %s(%d) ",SANmv,pref[i].score);	}	m[i].move = pref[i].move;	if (!(flags & XBOARD) || BKquery == 1)           if ((i+1) % 8 == 0) fputc('\n',ofp);      }      if (!(flags & XBOARD) || BKquery == 1)	if (i % 8 != 0) fprintf(ofp," \n \n");        temp = (bookfirstlast > mcnt+1 ? mcnt+1 : bookfirstlast);      /* Choose from the top preferred moves based on distribution */      maxdistribution = 0;      for (i = 0; i < temp; i++)        maxdistribution += pref[i].score;      /* Do not play moves that have only losses! */      if (maxdistribution == 0) 	return BOOK_ENOMOVES;      k = rand() % maxdistribution;      maxdistribution = 0;      for (i = 0; i < temp; i++) {	maxdistribution += pref[i].score;	if (k >= maxdistribution - pref[i].score &&	    k < maxdistribution)	{	  k = i;	  RootPV = m[k].move;	  break;	}      }    }  }  return BOOK_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -