void TestCaptureGenSpeed (void) /************************************************************************** * * This routine benchmarks the speed of the bitmap move generation * for captures. * The test case is BK.epd, the 24 positions from the Brat-Kopec test * suite. * **************************************************************************/ { unsigned long i; struct timeval t1, t2; double et; GenCnt = 0; et = 0; while (ReadEPDFile ("../test/wac.epd", 0)) { gettimeofday (&t1, NULL); for (i = 0; i < 200000; i++) { TreePtr[2] = TreePtr[1]; GenCaptures (1); } gettimeofday (&t2, NULL); et += (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) / 1e6; printf ("Time = %f\n", et); } printf ("No. of moves generated = %lu\n", GenCnt); printf ("Time taken = %f\n", et); if (et > 0) printf ("Rate = %f\n", GenCnt / et); }
void TestCaptureList (void) /**************************************************************************** * * This routine reads in a *.epd file (EPD notation) and prints the capture * moves for that position. * ****************************************************************************/ { while (ReadEPDFile ("TEST/GMG1.epd", 0)) { ShowBoard (); GenCnt = 0; TreePtr[2] = TreePtr[1]; GenCaptures (1); FilterIllegalMoves (1); ShowMoveList (1); printf ("No. of moves generated = %lu\n\n", GenCnt); } }
int PhasePick (leaf **p1, int ply) /*************************************************************************** * * A phase style routine which returns the next move to the search. * Hash move is first returned. If it doesn't fail high, captures are * generated, sorted and tried. If no fail high still occur, the rest of * the moves are generated and tried. * The idea behind all this is to save time generating moves which might * not be needed. * CAVEAT: To implement this, the way that genmoves & friends are called * have to be modified. In particular, TreePtr[ply+1] = TreePtr[ply] must * be set before the calls can be made. * If the board ever gets corrupted during the search, then there is a bug * in IsLegalMove() which has to be fixed. * ***************************************************************************/ { static leaf* p[MAXPLYDEPTH]; leaf *p2; int mv; int side; side = board.side; switch (pickphase[ply]) { case PICKHASH: TreePtr[ply+1] = TreePtr[ply]; pickphase[ply] = PICKGEN1; if (Hashmv[ply] && IsLegalMove (Hashmv[ply])) { TreePtr[ply+1]->move = Hashmv[ply]; *p1 = TreePtr[ply+1]++; return (true); } case PICKGEN1: pickphase[ply] = PICKCAPT; p[ply] = TreePtr[ply+1]; GenCaptures (ply); for (p2 = p[ply]; p2 < TreePtr[ply+1]; p2++) p2->score = SwapOff(p2->move) * WEIGHT + Value[cboard[TOSQ(p2->move)]]; case PICKCAPT: while (p[ply] < TreePtr[ply+1]) { pick (p[ply], ply); if ((p[ply]->move & MOVEMASK) == Hashmv[ply]) { p[ply]++; continue; } *p1 = p[ply]++; return (true); } case PICKKILL1: pickphase[ply] = PICKKILL2; if (killer1[ply] && killer1[ply] != Hashmv[ply] && IsLegalMove (killer1[ply])) { TreePtr[ply+1]->move = killer1[ply]; *p1 = TreePtr[ply+1]; TreePtr[ply+1]++; return (true); } case PICKKILL2: pickphase[ply] = PICKGEN2; if (killer2[ply] && killer2[ply] != Hashmv[ply] && IsLegalMove (killer2[ply])) { TreePtr[ply+1]->move = killer2[ply]; *p1 = TreePtr[ply+1]; TreePtr[ply+1]++; return (true); } case PICKGEN2: pickphase[ply] = PICKREST; p[ply] = TreePtr[ply+1]; GenNonCaptures (ply); for (p2 = p[ply]; p2 < TreePtr[ply+1]; p2++) { p2->score = history[side][(p2->move & 0x0FFF)] + taxicab[FROMSQ(p2->move)][D5] - taxicab[TOSQ(p2->move)][E4]; if (p2->move & CASTLING) p2->score += CASTLINGSCORE; } case PICKREST: while (p[ply] < TreePtr[ply+1]) { pick (p[ply], ply); mv = p[ply]->move & MOVEMASK; if (mv == Hashmv[ply] || mv == killer1[ply] || mv == killer2[ply]) { p[ply]++; continue; } *p1 = p[ply]++; return (true); } } return (false); }
int Quiesce (uint8_t ply, int alpha, int beta) /************************************************************************** * * Our quiescent search. This quiescent search is able to recognize * mates. * **************************************************************************/ { uint8_t side, xside; int best, delta, score, savealpha; leaf *p, *pbest; if (EvaluateDraw ()) return (DRAWSCORE); side = board.side; xside = 1^side; InChk[ply] = SqAtakd (board.king[side], xside); best = Evaluate (alpha, beta); if (best >= beta && !InChk[ply]) return (best); TreePtr[ply+1] = TreePtr[ply]; if (InChk[ply]) { GenCheckEscapes (ply); if (TreePtr[ply] == TreePtr[ply+1]) return (-MATE+ply-2); if (best >= beta) return (best); SortMoves (ply); } else { GenCaptures (ply); if (TreePtr[ply] == TreePtr[ply+1]) return (best); SortCaptures (ply); } savealpha = alpha; pbest = NULL; alpha = MAX(best, alpha); delta = MAX (alpha - 150 - best, 0); for (p = TreePtr[ply]; p < TreePtr[ply+1]; p++) { pick (p, ply); /* We are in check or capture cannot bring score near alpha, give up */ if (!InChk[ply] && SwapOff (p->move) < delta) continue; /* If capture cannot bring score near alpha, give up */ if (p->score == -INFINITY) continue; #ifdef THREATEXT /* See search.c for an explanation of the code below */ if (threatply+1 == ply) { if ((TOSQ(p->move) == FROMSQ(threatmv)) || (FROMSQ(p->move) == TOSQ(threatmv))) continue; } if (threatply && threatply+3 == ply && FROMSQ(p->move) == TOSQ(threatmv)) continue; #endif MakeMove (side, &p->move); QuiesCnt++; if (SqAtakd (board.king[side], xside)) { UnmakeMove (xside, &p->move); continue; } score = -Quiesce (ply+1, -beta, -alpha); UnmakeMove (xside, &p->move); if (score > best) { best = score; pbest = p; if (best >= beta) goto done; alpha = MAX (alpha, best); } } done: if (flags & USEHASH && pbest != NULL) TTPut (side, 0, ply, savealpha, beta, best, pbest->move); return (best); }