TreeNode *BStar::GetBestOptPrb(TreeNode *parent) { double MaxValue = 0.0; double PrbD = 0.0; TreeNode *aux = 0; TreeNode *Sel = 0; int DPV = 0; // depth PV int DOpt = 0; for(aux = parent->SelectBestReal();aux; aux = aux->SelectBestReal()) { DPV++; } double np = parent->SubtreeSize; const double Cucb = 2.0; //0.0000001; //2000.0; for(aux = parent->MoveTo(FIRSTCHILD); aux; aux = aux->MoveTo(NEXTSIBBLING)) { PrbD = aux->OptPrb ; if( PrbD > MaxValue ) { MaxValue = PrbD; Sel = aux ; } } // PV can not be shorter than opt path if(Sel == NULL) Sel = parent->SelectBestReal(); aux = Sel->TraceDown(1); for(;aux && aux != TreeNode::GetRootNode(); aux = aux->MoveTo(PARENT)) DOpt++; if(DOpt > DPV) return parent->SelectBestReal(); return Sel; }
void BStar::Search() { int Cancelar = 0; int i,NExpandFD = 0; int LastIteration = -1; Cancelar = 0; DumpTree *dt; TreeNode *CurNode = NULL; // last move expanded TreeNode *CurBestNode = NULL; // last best if(DumpData) { dt = new DumpTree(); } TreeNode *a = NULL; TreeNode *SelectedNode = NULL; ColorRoot = TreeNode::GetRootNode()->Color; NExpandFD = 18; for(i=1;i < FixedDepth;i++) { NExpandFD *= 3; // Branch factor 3 } if(FixedDepth) { SelectNodes = (NExpandFD * 6)/10; VerifyNodes = NExpandFD - SelectNodes; } for(;;) { if(LastIteration == TotalExpand) break; // avoid cicle without expands. LastIteration = TotalExpand; if(Cancel||Cancelar) break; // printf("SELECT Step %d\n",TotalExpand); while (GetRealValBestAtRoot() <= OptValAnyOtherMoveAtRoot()) { if(BestMoveAtRoot != CurBestNode) { if(CurBestNode != NULL) PrintPV(); CurBestNode = BestMoveAtRoot; LastChange = TotalExpand; PrintPV(); } if(TreeNode::GetRootNode()->RealVal > (MATE-50) || TreeNode::GetRootNode()->RealVal < (50-MATE) ) { Cancelar= 1; // switch to verify break; } TargetVal = ((BestMoveAtRoot->RealVal) + OptVal2ndBest)/2; // it is unlikely that any other move can achieve as good a RealVal ? if( SecondRootOptPrb() < MinAct) { if(GetRealValBestAtRoot() >= (RealVal2ndBstMoveAtRoot() + 1)) // goto salida; break; } if(DumpData ) { dt->Print("SELECT STEP Color %d Best %d Target Value %d\n",ColorRoot,BestMoveAtRoot->RealVal,TargetVal); dt->Write(); } // Select Root Node with greatest OptPrb; a = GetBestOptPrb(TreeNode::GetRootNode()); if(!a) break; if(a != CurNode) { CurNode = a; } // Trace down the child subtree selecting // For Player-to-Move nodes, child with largest OptPrb // For Opponent-to-Move nodes, child with best RealVal // Until arriving at a leaf node; SelectedNode = a->TraceDownNotStopper(true); if(DumpData) { dt->Print("Selected node:"); dt->DumpPath(SelectedNode,TreeNode::GetRootNode()); dt->Print("Color root %d\n",TreeNode::GetRootNode()->Color); dt->DumpRoot(); } if(SelectedNode->MoveCount != 0) // already expanded, mate pos? { break; } // Get RealVal for each Child Node of this leaf; // If it is a Player-to-Move node get OptVals for each Child; if(Cancelar||Cancel) break; Expand(SelectedNode,PLAYER); // search path down to new expanded SelectedNode = a->TraceDown(true); a = SelectedNode; if(DumpData) { dt->Print("Backup Node :"); dt->DumpPath(a,TreeNode::GetRootNode()); } // Back up Values; if( SelectedNode->RealVal == 0 && SelectedNode->OptVal == 0 && SelectedNode->MoveCount == -1 ) Backup(PLAYER,a->MoveTo(PARENT)); else Backup(PLAYER,a); // best move at root can change after a Backup GetRealValBestAtRoot(); TargetVal = ((BestMoveAtRoot->RealVal) + OptVal2Best())/2; BackupPrb(a); if(TotalExpand > MaxExpand) { Cancelar = 1; break; } if(FixedDepth) { if(TotalExpand > NExpandFD ) //18*(3^FixedDepth)) { Cancelar = 1; break; // EffortLimitsExceeded } } else if((TimeElapsed()-ini) >= TimeLimit ) { Cancelar = 1; break; // EffortLimitsExceeded } if ((ExpandCount > SelectNodes)) { ExpandCount = 0; break; // EffortLimitsExceeded } } if(Cancel||Cancelar) break; TargetVal = RealVal2ndBstMoveAtRoot() + 1; if(TargetVal == (-UNDEFINED+1)) goto salida; // printf("VERIFY Step %d\n",TotalExpand); if(DumpData) { dt->Print("VERIFY Step\n"); dt->Print("Target Value %d\n",TargetVal); } if(!FixedDepth && (TimeElapsed()-ini) >= TimeLimit ) { break; } if(FixedDepth) { if(TotalExpand > NExpandFD) //18*(3^FixedDepth)) { break; // EffortLimitsExceeded } } VerifyInit(); if(!FixedDepth && (TimeElapsed()-ini) >= TimeLimit ) break; GetRealValBestAtRoot() ; if(BestMoveAtRoot->RealVal < TargetVal && GetRealValBestAtRoot() > OptValAnyOtherMoveAtRoot()) break; if(BestMoveAtRoot->RealVal >= MATE-50 || BestMoveAtRoot->RealVal <= 50-MATE) break; ExpandCount = 0; while(BestMoveAtRoot->RealVal >= TargetVal) { if(BestMoveAtRoot != CurBestNode) { CurBestNode = BestMoveAtRoot; LastChange = TotalExpand; // print info PrintPV(); } if(DumpData) { dt->Print("Verify 1:"); } // Select reply Node with Greatest RealVal a = BestMoveAtRoot; if(DumpData) dt->Print("BestMove Real %d Opt %d Pess %d\n",a->RealVal,a->OptVal,a->PessVal); // Trace down the child subtree selecting // For Opponent-to-Move nodes, child with largest OptPrb // For Player-to-Move nodes, child with best RealVal // Until arriving at a leaf node; SelectedNode = TraceDownVerify(a); if(DumpData) { dt->Print("Verify Selected node:"); dt->DumpPath(SelectedNode,TreeNode::GetRootNode()); } if(DumpData) { dt->Print("Verify 2:"); } // TODO // if(IsOver(a)) // return; // Solved if(SelectedNode->RealVal == MATE || SelectedNode->RealVal == -MATE) break; // goto salida; // Get RealVal for each Child Node of this leaf; // If it is an Opponent-to-Move node get OptVals for each Child; Expand(SelectedNode,OPPONENT); if(SelectedNode->MoveCount > 0) { SelectedNode = TraceDownVerify(SelectedNode); // Search leaf node Backup(OPPONENT,SelectedNode); // and Back up Values; if(DumpData) { dt->Print("Verify Selected node:"); dt->DumpPath(SelectedNode,TreeNode::GetRootNode()); dt->DumpRoot(); } } else { if( SelectedNode->RealVal == 0 && SelectedNode->OptVal == 0 && SelectedNode->MoveCount == -1 ) break; } if(DumpData) { dt->Print("Verify 3:"); } if(TotalExpand > MaxExpand) { Cancelar = 1; break; } if(FixedDepth) { if(TotalExpand > NExpandFD) // 18*(3^FixedDepth)) { goto salida; break; // EffortLimitsExceeded } } else if (((TimeElapsed()-ini) >= TimeLimit && ExpandCount > 3 )|| (ExpandCount > VerifyNodes)) { ExpandCount = 0; if((TimeElapsed()-ini) >= TimeLimit ) { goto salida; } break; } } if(DumpData) { int TargetVal = ((BestMoveAtRoot->RealVal) + OptVal2Best())/2; dt->Print("Target %d\n",TargetVal); dt->Write(); } } salida: PrintPV(); if(DumpData) { delete dt; } }