📄 main.cpp
字号:
if (g) break; } if (g) break; } t1 = t1->next; } /* Convert new move into normal */ if (g) { newmove.from = SymmetricConvert(t1->line[k], sk); newmove.dest = SymmetricConvert(t1->line[k+1], sk); } return g;}void CChessAI::DelBook(void){ if (!book) return; t1 = book; t2 = book->next; while (t1 != NULL) { free(t1); t1 = t2; if (t2) t2 = t2->next; } book =NULL;}short CChessAI::Readbook(void){ short i, j, len; char s[255], line[52], ch; FILE *f; if ((f = fopen("BOOK.DAT", "rt"))== NULL) return 0; while(1) { /* Read a book line */ for (j=0, ch=0; ch!='\n'; j++) { ch = fgetc(f); s[j] = ch; if (feof(f)) break; } if (feof(f)) break; /* Convert string into position */ for (i=0, len=0; i<j && s[i] !=';'; i++) if (s[i] >= 'A') { line[len] = s[i]-65 + (SIZE_X-s[i+1]+48)*SIZE_X; i++; len++; } if (len) { /* save in single linked list */ t1 = (struct node *) malloc(sizeof(struct node)); t1->next = NULL; t1->len = len; for (i=0; i<len; i++) t1->line[i] = line[i]; if (book==NULL) book = t1; else t2->next = t1; t2 = t1; } } fclose(f); t1 = book; while (t1) { t1=t1->next; } return 1;}int CChessAI::InitGame(bool AiRed){ nm=0; InitGen(); if (AiRed){ side = REDSIDE; xside = BLACKSIDE; computerside = side; ReadingBook=true; if (!Readbook()) { ReadingBook=false; } NextStep(); /* if (ReadingBook){ if (!GetBook()) { ReadingBook=false; DelBook(); ComputerThink(); } else{ for (int i=0; i<4; i++) { ss[i][nm] = SymmetricConvert(newmove.from, i); ss[i][nm+1] = SymmetricConvert(newmove.dest, i); } nm += 2; } } else{ ComputerThink(); }*/ } else { side = BLACKSIDE; xside = REDSIDE; computerside = xside; Gen(); } return 0;}void CChessAI::InitGen(void){ gen_begin[0] = 0; ply = 0; hdp = 0;}void CChessAI::Quicksort(short q, short r){ short i, j, x; gen_rec g; i = q; j = r; x = gen_dat[(q+r)/2].prior; do { while (gen_dat[i].prior > x) i++; while (gen_dat[j].prior < x) j--; if (i <= j) { g = gen_dat[i]; gen_dat[i] = gen_dat[j]; gen_dat[j] = g; i++; j--; } } while (i<=j); if (q < j) Quicksort(q, j); if (i < r) Quicksort(i, r);}void CChessAI::Sort(void){ Quicksort(gen_begin[ply], gen_end[ply]-1);}void CChessAI::Check_pv (void){ short i; for (follow_pv=0, i=gen_begin[ply]; i<gen_end[ply]; i++) if (gen_dat[i].m.from==pv[ply].from && gen_dat[i].m.dest==pv[ply].dest) { follow_pv = 1; gen_dat[i].prior += 1000; return; }}void CChessAI::UnMakeMove(void){ short from, dest; hdp--; ply--; side = xside; xside = 1-xside; from = hist_dat[hdp].m.from; dest = hist_dat[hdp].m.dest; piece[from] = piece[dest]; color[from] = color[dest]; piece[dest] = hist_dat[hdp].capture; if (piece[dest] == EMPTY) color[dest] = EMPTY; else color[dest] = xside; if (piece[dest] != EMPTY) materialnumber[xside][piece[dest]]++;}#define MAXREP 30int CChessAI::CheckMoveLoop(void){ short hdmap[MAXREP]; short c, f, i, j, k, m, p, b; move cm; /* if (one side has not any attack pieces, it can make any move */ if ((hdp<3) || (materialnumber[xside][ROOK]+materialnumber[xside][CANNON]+ materialnumber[xside][KNIGHT]+materialnumber[xside][PAWN]==0)) return 0; for (i=0; i<MAXREP; i++) hdmap[i] = 0; if (hdp>MAXREP) m = MAXREP; else m = hdp; c = 0; i = 0; k = 0; while (i<m) { if (hist_dat[hdp-1-i].capture!=EMPTY) return 0; if (hdmap[MAXREP-i]==0) { c++; hdmap[MAXREP-i] = c; p = hist_dat[hdp-1-i].m.dest; f = hist_dat[hdp-1-i].m.from; j = i+1; while (j<m) { if (f==hist_dat[hdp-1-j].m.dest) { f = hist_dat[hdp-1-j].m.from; hdmap[MAXREP-j] = c; if (p==f) { if (k<j) k = j; break; } } /* if (f */ j++; } /* while (j<m) */ if (j>m) break; } /* if (hdmap */ i++; if (i>2 && i==k) { b = Attack (hist_dat[hdp-1].m.dest, xside); if (!b) { cm = hist_dat[hdp-1].m; UnMakeMove(); b = Attack (cm.from, side); MakeMove (cm); if (b) return 0; } return 1; } } /* while (i<m) */ return 0;}short knightcheck2 [8] = {-8,-10,-8,-10,8,10,8,10};short CChessAI::Attack (int pos, int side){ short j, k, x, y, fcannon; char sd, xsd; sd = side; xsd = 1 - sd; for (j=0; j<4; j++) { // ROOK, CANNON, PAWN, KING x = mailbox90[pos]; fcannon = 0; for (k=0; k<9; k++) { x = x + offset[ROOK][j]; y = mailbox182[x]; if (y==-1) break; if (!fcannon) { if (color[y]==xsd) switch (piece[y]) { case ROOK: return 1; case KING: if (piece[pos]==KING) return 1; case PAWN: if (k==0 && ((sd==REDSIDE && j!=2) || (sd==BLACKSIDE && j!=3))) return 1; } if (color[y]!=EMPTY) fcannon = 1; } else // CANNON case if (color[y] != EMPTY) { if (color[y]==xsd && piece[y]==CANNON) return 1; break; } } // for k } // for j for (j = 0; j < 8; j++) { // Knight Check y = mailbox182[mailbox90[pos]+offset[KNIGHT][j]]; if (y==-1) continue; if (color[y]==xsd && piece[y]==KNIGHT && color[pos+knightcheck2[j]]==EMPTY) return 1; } return 0;}short CChessAI::IsInCheck (int side){ int i, pos; i = 0; do { pos = kingpalace[side][i]; i++; } while (piece[pos]!=KING); return Attack(pos, side);}short CChessAI::MakeMove(move m){ short from, dest, p; from = m.from; dest = m.dest; p = piece[dest]; if (p != EMPTY) materialnumber[xside][p]--; hist_dat[hdp].m = m; hist_dat[hdp].capture = p; piece[dest] = piece[from]; piece[from] = EMPTY; color[dest] = color[from]; color[from] = EMPTY; hdp++; ply++; side = xside; xside = 1-xside; return p == KING;}short CChessAI::MoveSave (int from, int dest){ move ms; short k; if (piece[dest]==KING) return 1; ms.from = from; ms.dest = dest; MakeMove (ms); k = IsInCheck (xside); if (!k) k = CheckMoveLoop(); UnMakeMove(); return !k;}void CChessAI::Gen_push(short from, short dest){ if (MoveSave(from, dest)) { gen_dat[gen_end[ply]].m.from = from; gen_dat[gen_end[ply]].m.dest = dest; if (piece[dest]!=EMPTY) gen_dat[gen_end[ply]].prior = (piece[dest]+1)*100 - piece[from]; else gen_dat[gen_end[ply]].prior = history[from][dest]; gen_end[ply]++; }}short CChessAI::GenCapture(void){ short i, j, k, n, p, x, y, t, fcannon; gen_end[ply] = gen_begin[ply]; for (i=0; i<BOARD_SIZE; i++) if (color[i]==side) { p = piece[i]; for (j=0; j<8; j++) { if (offset[p][j]==0) break; x = mailbox90[i]; fcannon = 0; if (p==ROOK || p==CANNON) n = 9; else n = 1; for (k=0; k<n; k++) { if (p==PAWN && side==BLACKSIDE) x -= offset[p][j]; else x += offset[p][j]; y = mailbox182[x]; if (side == REDSIDE) t = y; else t = 89-y; if (y==-1 || (legalposition[t] & maskpiece[p])==0) break; if (!fcannon) { if (color[y] != side) { switch (p) { case KNIGHT: if (color[i+knightcheck[j]]==EMPTY && color[y]==xside) Gen_push(i, y); break; case ELEPHAN:if (color[i+elephancheck[j]]==EMPTY && color[y]==xside) Gen_push(i, y); break; case CANNON: break; default: if (color[y]==xside) Gen_push(i, y); } } if (color[y]!=EMPTY) { if (p==CANNON) fcannon = 1; else break; } } else { /* CANNON switch */ if (color[y]!=EMPTY) { if (color[y]==xside) Gen_push(i, y); break; } } } /* for k */ } /* for j */ } gen_end[ply+1] = gen_end[ply]; gen_begin[ply+1] = gen_end[ply]; capbrandtotal += (unsigned long)gen_end[ply] - gen_begin[ply]; if (gen_end[ply] > gen_begin[ply]) capgencount++; return (gen_begin[ply] < gen_end[ply]);}short CChessAI::Eval(void){ short i, s = 0; nodecount++; for(i=0; i<BOARD_SIZE; i++) { if (color[i]==REDSIDE) s += pointtable[piece[i]][REDSIDE][i]; else if (color[i]==BLACKSIDE) s -= pointtable[piece[i]][BLACKSIDE][i]; } if (side==BLACKSIDE) s = -s; return s; // + Bonous();}short CChessAI::Gen(void){ short i, j, k, n, p, x, y, t, fcannon; gen_end[ply] = gen_begin[ply]; for(i=0; i < BOARD_SIZE; i++) if (color[i]==side) { p = piece[i]; for(j=0; j<8; j++) { if (!offset[p][j]) break; x = mailbox90[i]; fcannon = 0; if (p==ROOK || p==CANNON) n = 9; else n = 1; for (k=0; k<n; k++) { if (p==PAWN && side==BLACKSIDE) x -= offset[p][j]; else x += offset[p][j]; y = mailbox182[x]; if (side == REDSIDE) t = y; else t = 89-y; if (y==-1 || (legalposition[t] & maskpiece[p])==0) break; if (!fcannon) { if (color[y]!=side) switch (p) { case KNIGHT: if (color[i+knightcheck[j]]==EMPTY) Gen_push(i, y); break; case ELEPHAN:if (color[i+elephancheck[j]]==EMPTY) Gen_push(i, y); break; case CANNON: if (color[y]==EMPTY) Gen_push(i, y); break; default: Gen_push(i, y); } if (color[y]!=EMPTY) { if (p==CANNON) fcannon++; else break; } } else { /* CANNON switch */ if (color[y] != EMPTY) { if (color[y]==xside) Gen_push(i, y); break; } } } /* for k */ } /* for j */ } gen_end[ply+1] = gen_end[ply]; gen_begin[ply+1] = gen_end[ply]; brandtotal += gen_end[ply] - gen_begin[ply]; gencount++; return (gen_end[ply]>gen_begin[ply]);}short CChessAI::Quiescence(short alpha, short beta){ short i, value, best; if (mply < ply) { mply = ply; //gotoxy(50,13); printf("Quiescen depth : %d ", mply);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -