opening.c (2054B)
1 /* opening.c - nombre de la apertura y jugadas de libro. */ 2 #include <string.h> 3 #include "chess.h" 4 #include "book.h" 5 6 static bool is_start(const Pos *p) 7 { 8 Pos s; 9 pos_start(&s); 10 return p->hash == s.hash && !memcmp(p->sq, s.sq, sizeof s.sq); 11 } 12 13 /* Cuantas jugadas de la linea coinciden con las jugadas hechas; -1 si difiere 14 * antes de terminarse alguna de las dos. *next: siguiente jugada de la linea. */ 15 static int match(const char *line, const Move *mv, int n, const char **next) 16 { 17 const char *q = line; 18 int i = 0; 19 *next = 0; 20 while (*q) { 21 while (*q == ' ') q++; 22 if (!*q) break; 23 if (i == n) { *next = q; return i; } 24 char u[8]; 25 move_uci(mv[i], u, sizeof u); 26 size_t l = strlen(u); 27 if (strncmp(q, u, l) || (q[l] && q[l] != ' ')) return -1; 28 q += l; 29 i++; 30 } 31 return i; 32 } 33 34 const char *opening_name(const Move *mv, int n, const Pos *start, const char **eco) 35 { 36 if (!is_start(start)) return 0; 37 int best = 0; 38 const BookLine *bl = 0; 39 for (int k = 0; k < BOOK_N; k++) { 40 const char *next; 41 int m = match(BOOK[k].moves, mv, n, &next); 42 if (m > best && !next) { best = m; bl = &BOOK[k]; } /* la linea entera ya se jugo */ 43 } 44 if (!bl) return 0; 45 if (eco) *eco = bl->eco; 46 return bl->name; 47 } 48 49 Move book_move(const Move *mv, int n, const Pos *start, Rng *rng) 50 { 51 if (!is_start(start)) return MOVE_NONE; 52 const char *cand[64]; 53 int nc = 0; 54 for (int k = 0; k < BOOK_N && nc < 64; k++) { 55 const char *next; 56 if (match(BOOK[k].moves, mv, n, &next) == n && next) cand[nc++] = next; 57 } 58 if (!nc) return MOVE_NONE; 59 const char *pick = cand[rng_below(rng, (uint32_t)nc)]; 60 /* reproducir hasta aca para validar la jugada contra la posicion */ 61 Pos p = *start; 62 for (int i = 0; i < n; i++) { Undo u; pos_make(&p, mv[i], &u); } 63 char u[8]; 64 int l = 0; 65 while (pick[l] && pick[l] != ' ' && l < 6) { u[l] = pick[l]; l++; } 66 u[l] = 0; 67 return move_from_uci(&p, u); 68 }