int OnValidObjective (Unit e, int role, F4PFList nearlist) { VuListIterator vuit(nearlist); Objective bo = GetFirstObjective(&vuit); while (bo && bo->Id() != e->GetUnitObjectiveID()) bo = GetNextObjective(&vuit); if (bo) { GridIndex x,y; e->GetLocation(&x,&y); if (ScorePosition (e, role, 100, bo, x, y, (bo->GetTeam() == e->GetTeam())? 1:0) < -30000) bo = NULL; } if (bo) return 1; return 0; }
void SelectMove(short side, SelectMove_mode iop) { static short i, tempb, tempc, tempsf, tempst, xside, rpt; static short alpha, beta, score; static struct GameRec *g; short sqking, in_check, blockable; #ifdef BOOKTEST printf("hashbd = %ld (hashkey >> 16)|side = %d\n", hashbd, (hashkey >> 16)|side); #endif flag.timeout = false; flag.back = false; flag.musttimeout = false; xside = side ^ 1; #if ttblsz recycle = (GameCnt % rehash) - rehash; #endif ExaminePosition(side); /* if background mode set to infinite */ if (iop == BACKGROUND_MODE) { background = true; /* if background mode set response time to infinite */ ResponseTime = 9999999; } else { player = side; SetResponseTime(side); } #ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ ShowResponseTime(); ExtraTime = 0; score = ScorePosition(side); #ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ ShowSidetoMove(); #ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ SearchStartStuff(side); #ifdef HISTORY array_zero(history, sizeof_history); #endif FROMsquare = TOsquare = -1; PV = 0; if (iop == FOREGROUND_MODE) hint = 0; /* * If the last move was the hint, select the computed answer to the * hint as first move to examine. */ #if MAXDEPTH > 3 if (GameCnt > 0) { SwagHt = (GameList[GameCnt].gmove == PrVar[2]) ? PrVar[3] : 0; } else #endif SwagHt = 0; for (i = 0; i < MAXDEPTH; i++) PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0; /* set initial window for search */ if (flag.tsume) { alpha = -(SCORE_LIMIT + 999); beta = SCORE_LIMIT + 999; } else { alpha = score - ((computer == white) ? BAwindow : WAwindow); beta = score + ((computer == white) ? BBwindow : WBwindow); } rpt = 0; TrPnt[1] = 0; root = &Tree[0]; sqking = PieceList[side][0]; in_check = (board[sqking] == king) ? SqAttacked(sqking, side^1, &blockable) : false; MoveList(side, 1, in_check, blockable); for (i = TrPnt[1]; i < TrPnt[2]; i++) { if (!pick(i, TrPnt[2] - 1)) break; } /* Can I get a book move? */ if (flag.regularstart && Book) { flag.timeout = bookflag = OpeningBook(&hint, side); if (TCflag) ResponseTime += ResponseTime; } /* Zero stats for hash table. */ reminus = replus = 0; GenCnt = NodeCnt = ETnodes = EvalNodes = HashCnt = FHashAdd = HashAdd = FHashCnt = THashCol = HashCol = 0; globalscore = plyscore = score; Jscore = 0; zwndw = 20; /********************* main loop ********************************/ Sdepth = (MaxSearchDepth < (MINDEPTH - 1)) ? MaxSearchDepth : (MINDEPTH - 1); while (!flag.timeout) { /* go down a level at a time */ Sdepth++; #ifdef NULLMOVE null = 0; PVari = 1; #endif /* terminate search at DepthBeyond ply past goal depth */ if (flag.tsume) DepthBeyond = Sdepth; else #if defined SLOW_CPU DepthBeyond = Sdepth + ((Sdepth == 1) ? 3 : 5); #else DepthBeyond = Sdepth + ((Sdepth == 1) ? 7 : 11); #endif # ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ ShowDepth(' '); /* search at this level returns score of PV */ score = search(side, 1, Sdepth, alpha, beta, PrVar, &rpt); /* save PV as killer */ for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i]; /* low search failure re-search with (-inf, score) limits */ if (score < alpha) { reminus++; #ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ ShowDepth('-'); if (TCflag && TCcount < MAXTCCOUNTR) { if (hard_time_limit) ExtraTime += (MAXTCCOUNTR - TCcount) * TCleft; else ExtraTime += (8 * TCleft); TCcount = MAXTCCOUNTR - 1; } score = search(side, 1, Sdepth, -(SCORE_LIMIT + 999), (SCORE_LIMIT + 999), PrVar, &rpt); } /* high search failure re-search with (score, +inf) limits */ else if (score > beta && !(root->flags & exact)) { replus++; #ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ ShowDepth('+'); score = search(side, 1, Sdepth, -(SCORE_LIMIT + 999), (SCORE_LIMIT + 999), PrVar, &rpt); } /**************** out of search ***********************************/ CheckForTimeout(score, globalscore, Jscore, zwndw); /************************ time control ****************************/ /* save PV as killer */ for (i = 1; i <= Sdepth + 1; i++) killr0[i] = PrVar[i]; if (!flag.timeout) Tscore[0] = score; /* if (!flag.timeout) */ /* for (i = TrPnt[1] + 1; i < TrPnt[2]; i++) if (!pick (i, TrPnt[2] - 1)) break; */ /* if done or nothing good to look at quit */ if ((root->flags & exact) || (score < -SCORE_LIMIT)) flag.timeout = true; /* find the next best move put below root */ if (!flag.timeout) { #if !defined NODYNALPHA Jscore = (plyscore + score) >> 1; #endif zwndw = 20 + abs(Jscore / 12); plyscore = score; /* recompute search window */ beta = score + ((computer == white) ? BBwindow : WBwindow); #if !defined NODYNALPHA alpha = ((Jscore < score) ? Jscore : score) - ((computer == white) ? BAwindow : WAwindow) - zwndw; #else alpha = score - ((computer == white) ? BAwindow : WAwindow); #endif } #ifdef QUIETBACKGROUND if (!background) #endif /* QUIETBACKGROUND */ ShowResults(score, PrVar, '.'); }
static int quies(struct SearchData *sd, int alpha, int beta, int depth) { struct Position *p = sd->position; int best; int move; int talpha; int tmp; QNodes++; EnterNode(sd); /* max search depth reached */ if (sd->ply >= MaxDepth || Repeated(p, FALSE)) { best = 0; goto EXIT; } /* * Probe recognizers. If the probe is successful, use the * recognizer score as evaluation score. * * Otherwise, use ScorePosition() */ switch (ProbeRecognizer(p, &tmp)) { case ExactScore: best = tmp; goto EXIT; case LowerBound: best = tmp; if (best >= beta) { goto EXIT; } break; case UpperBound: best = tmp; if (best <= alpha) { goto EXIT; } break; default: best = ScorePosition(p, alpha, beta); break; } if (best >= beta) { goto EXIT; } talpha = MAX(alpha, best); while ((move = NextMoveQ(sd, alpha) ) != M_NONE) { DoMove(p, move); if (InCheck(p, OPP(p->turn))) UndoMove(p, move); else { tmp = -quies(sd, -beta, -talpha, depth-1); UndoMove(p, move); if (tmp >= beta) { best = tmp; goto EXIT; } if (tmp > best) { best = tmp; if (best > talpha) { talpha = best; } } } } EXIT: LeaveNode(sd); return best; }