void perf_t(char dep) { unsigned int i; /*char dummy; gen_all_captures();*/ gen_all(); check_condition(); dep--; for (i = tree.first_move[Ply];i < tree.first_move[Ply + 1];i++) { if (verify_move(tree.move_list[i].move)==0) continue; if (makemove(tree.move_list[i].move,0)) { /*print_board(); printf("Press any key to continue:"); while (!kbhit()); dummy=getch();*/ Nodes++; if (dep) perf_t(dep); unmakemove(); } } }
/*Genera le mosse della Root e le ordina*/ void root(){ int d,next; RMOVEL m; unsigned int c; /*siamo sotto scacco?*/ check_condition(); /*generiamo le mosse della root*/ gen_all(); /*validiamo, inseriamo nella lista e attribuiamo un valore*/ tree.last_root_move=0; for (c=0;c<tree.first_move[1];c++) { if(!makemove(tree.move_list[c].move,0))continue; tree.root_move_list[tree.last_root_move].move=tree.move_list[c].move; tree.root_move_list[c].scorec=-quiesce(-INF,+INF,0); tree.root_move_list[c].scoren=0; tree.last_root_move++; unmakemove(); } /*ordiniamo*/ d=1; do { next=0; for (c=0;c<((tree.last_root_move)-d);c++) { if (tree.root_move_list[c].scorec<tree.root_move_list[c+1].scorec) { m=tree.root_move_list[c]; tree.root_move_list[c]=tree.root_move_list[c+1]; tree.root_move_list[c+1]=m; next=1; } } d++; } while (next); }
/*Equivalente alla search() ma alcune cose non vengono effettuate*/ int search_root(int alpha,int beta,int depth){ int i,c,score,legal,old_depth; unsigned int start_nodes,nws; MOVE m; start_nodes=Nodes; /*questo e' un nuovo nodo da cercare*/ Nodes++; /*controlla se è tempo di abortire la ricerca*/ if(stop_search()) { tree.abort_search=1; return 0; } /*aggiorna la lunghezza della pv corrente*/ tree.pv_lenght[Ply]=Ply; /*estensioni*/ old_depth=depth; /*1-se sotto scacco: estendi la ricerca!*/ if(tree.check[Side][Ply]) depth++; legal=0; nws=0; /*negascout fail-soft alpha beta*/ for (i=0;i<tree.last_root_move;i++) { m=tree.root_move_list[i].move; if(!makemove(m,0)) continue; legal = 1; if (nws) { score = -search( -alpha-1, -alpha, (depth - 1)); if (tree.abort_search) { unmakemove(); return 0; } if (score > alpha && score < beta ) { score = -search( -beta, -alpha, (depth - 1)); } } else score = -search( -beta, -alpha, (depth - 1)); unmakemove(); tree.root_move_list[i].scoren=Nodes-start_nodes; start_nodes=Nodes; if(tree.abort_search) return 0; if(score>alpha) { if(score>=beta) { heuristic(m,old_depth); return (score); } alpha=score; nws=1; /*aggiorna la pv*/ tree.pv[Ply][Ply]=m; heuristic(tree.pv[Ply][Ply],old_depth); for(c=Ply+1;c<tree.pv_lenght[Ply+1];c++) tree.pv[Ply][c]=tree.pv[Ply+1][c]; tree.pv_lenght[Ply]=tree.pv_lenght[Ply+1]; } }/*ciclo mosse*/ /*Se non ci sono mosse legali*/ if(legal==0) { if(tree.check[Side][Ply]) return -INF+Ply; else return DRAW; } return alpha; }
char *move2san(struct board_t *brd,DWORD move,char buf[128]) { short c,idx,from,to,pcs,cnt,i,row,mcheck,mlm; short mlegal[MAXMOVES]; char pcschar[]={'X','N','B','R','Q','K'}; DWORD mvs[MAXMOVES]; from=move&0x3F; to=(move>>6)&0x3F; pcs=(move>>12)&0x7; buf[0]='\0'; cnt=idx=i=0; generate_moves(brd,mvs,&idx); for(c=0;c<idx;c++) { makemove(brd,mvs[c]); mlegal[c]=FALSE; if(is_in_check(brd,brd->color^1)==FALSE) { mlegal[c]=TRUE; if(mvs[c]==move) cnt++; } unmakemove(brd); } if(cnt!=1) return buf; makemove(brd,move); mcheck=is_in_check(brd,brd->color); mlm=legal_moves(brd,NULL); unmakemove(brd); /* primo passaggio: ci occupiamo subito del "caso particolare" dell'arrocco */ if((move>>18)&CASTLING) { if((to==G1)||(to==G8)) snprintf(buf+i,128-i,"O-O"); else if((to==C1)||(to==C8)) snprintf(buf+i,128-i,"O-O-O"); if(mcheck==TRUE) i+=snprintf(buf+i,128-i,"%c",((mlm==0)?('#'):('+'))); return buf; } /* secondo passaggio: proviamo a generare una mossa del tipo Nc3 o Bxf6+ controllando che non ci siano ambiguita' */ for(c=cnt=0;c<idx;c++) { if(((mvs[c]>>12)&0x7)!=pcs) mlegal[c]=FALSE; if(((mvs[c]>>6)&0x3F)!=to) mlegal[c]=FALSE; if((move>>18)&PROMOTION) if(((mvs[c]>>18)&0xFF)!=((move>>18)&0xFF)) mlegal[c]=FALSE; if(mlegal[c]==TRUE) cnt++; } if(cnt==1) { if(pcs!=PAWN) i+=snprintf(buf+i,128-i,"%c",pcschar[pcs]); if((brd->board[to]!=EMPTY)||(brd->ep==to)) { if(pcs==PAWN) i+=snprintf(buf+i,128-i,"%cx",'a'+(from&0x7)); else i+=snprintf(buf+i,128-i,"x"); } i+=snprintf(buf+i,128-i,"%s",coords[to]); if((move>>18)&PROMOTION) i+=snprintf(buf+i,128-i,"=%c",promchar(move)); if(mcheck==TRUE) i+=snprintf(buf+i,128-i,"%c",((mlm==0)?('#'):('+'))); return buf; } /* terzo passaggio: proviamo anche ad indicare la colonna o la riga, come ad esempio in Rad1 o N2xc3+ */ for(c=cnt=row=0;c<idx;c++) { if((mlegal[c]==FALSE)||(mvs[c]==move)) continue; if((mvs[c]&0x7)==(from&0x7)) cnt++; if(((mvs[c]&0x3F)>>3)==(from>>3)) row++; } if((cnt==0)||(row==0)) { if(pcs!=PAWN) i+=snprintf(buf+i,128-i,"%c",pcschar[pcs]); if(cnt==0) i+=snprintf(buf+i,128-i,"%c",'a'+(from&0x7)); else if(row==0) i+=snprintf(buf+i,128-i,"%c",'1'+7-(from>>3)); if((brd->board[to]!=EMPTY)||(brd->ep==to)) i+=snprintf(buf+i,128-i,"x"); i+=snprintf(buf+i,128-i,"%s",coords[to]); if((move>>18)&PROMOTION) i+=snprintf(buf+i,128-i,"=%c",promchar(move)); if(mcheck==TRUE) i+=snprintf(buf+i,128-i,"%c",((mlm==0)?('#'):('+'))); return buf; } /* quarto passaggio: se la mossa resta ancora ambigua dobbiamo scrivere sia la casa di partenza che quella di destinazione */ i+=snprintf(buf+i,128-i,"%c%s",pcschar[pcs],coords[from]); if(brd->board[to]!=EMPTY) i+=snprintf(buf+i,128-i,"x"); i+=snprintf(buf+i,128-i,"%s",coords[to]); if(mcheck==TRUE) i+=snprintf(buf+i,128-i,"%c",((mlm==0)?('#'):('+'))); return buf; }