__int64 moves (int from,int to ,int disks) { if(disks==0)return 0; if(a[disks]==from) return moves(from,6-from-to,disks-1); if(a[disks]==to) return st2[disks]+moves(6-from-to,to,disks-1); ind=0; return 0; }
void moves(int n,char a,char c,char b) { if (n==1) { printf("Disk %d from %c to %c \n",n,a,c); return; } if (n==0) { return; } moves(n-1,a,b,c); printf("Disk %d from %c to %c \n",n,a,c); moves(n-1,b,c,a); }
bool Checkers::do_turn() { int color = (turn_num % 2 == 0) ? IS_RED : IS_WHITE; Player* p = (color == IS_RED) ? p1 : p2; set<Loc, less<Loc> > permitted_moves; bool must_jump = board.get_move_candidates(permitted_moves, color); if( permitted_moves.size() == 0 ) return false; cout << "Starting turn: " << p->get_name() << endl; p->set_board(board); list<Loc> moves( p->get_moves() ); cout << "Moves acquired (" << p->get_name() << "). Length: " << moves.size() << endl; /* for( list<Loc>::iterator i = moves.begin(); i != moves.end(); i++ ) cout << (*i) << endl; */ Move m; m.to = moves.front(); moves.pop_front(); int move_eval = INVALID; if( permitted_moves.find(m.to) == permitted_moves.end() ) throw GameEx("Checkers::do_turn", "not allowed to take this move", m.to.x, m.to.y); while( moves.size() > 0 ) { m.from = m.to; m.to = moves.front(); moves.pop_front(); move_eval = board.eval_move(m, color); if( move_eval == INVALID ) throw GameEx("Checkers::do_turn", "Invalid move", m.to.x, m.to.y); if( must_jump && move_eval & JUMP == 0 ) throw GameEx("Checkers::do_turn", "move must be a jump", m.to.x, m.to.y); board.move_piece(m); if( move_eval & JUMP ) { board.setloc( Loc((m.from.x+m.to.x)/2, (m.from.y+m.to.y)/2), EMPTY ); } if( move_eval & KINGED ) { board.setloc(m.to, board.get(m.to) | IS_KING); break; } } if( moves.size() > 0 ) throw GameEx("Checkers::do_turn", "requested too many moves", m.to.x, m.to.y); if( !(move_eval & KINGED) && move_eval & JUMP && board.can_jump_from(m.to) ) throw GameEx("Checkers::do_turn", "turn terminated too early", m.to.x, m.to.y); ++turn_num; return true; }
//! Main cycle of the thread. It handles the behaviour of the objects in the level. void LogicEngine::run() { running = true; while(running) { msleep(TIMER_X_MSEC); moves(); int noOfEndedPlayers = 0; for(int i = 0; i < clientList->size(); i++) { if(clientList->at(i)->player != NULL && clientList->at(i)->player->isEnded()) noOfEndedPlayers++; } /* // IF ALL PLAYERS ENDED UNLOAD LEVEL if(noOfEndedPlayers != 0 && noOfEndedPlayers == clientList->size() && isReady()) { for(int i = 0; i < clientList->size(); i++) { clientList->at(i)->thread->sendNextLevelPacket(); } server->sender->stopSend(); server->dataReceiver->unBind(); server->getLogic()->unloadLevel(); }*/ } }
TEST(MovesTest, Constructor) { Board board; Pieces pieces; Position position; MoveList list; Move m; ExtendedMove em(m, 50); list[0] = em; EXPECT_EQ(em.value(), list[0].value()); EXPECT_EQ(0, list.cur_ply()); Moves moves(board, pieces, position, list); // Test if MoveList::inc_ply() has been implicitly called by Moves() EXPECT_EQ(1, list.cur_ply()); EXPECT_EQ(BEST, moves.state()); EXPECT_EQ(0, moves.count(BEST)); EXPECT_EQ(0, moves.count(GOOD_CAPTURES)); EXPECT_EQ(0, moves.count(KILLERS)); EXPECT_EQ(0, moves.count(BAD_CAPTURES)); EXPECT_EQ(0, moves.count(QUIET_MOVES)); for (int i = 0; i < MAX_PLY; ++i) { EXPECT_EQ(0, list[i].value()); } list.dec_ply(); EXPECT_EQ(em.value(), list[0].value()); }
void PD_API MCPackSideChains( WorkSpace& wspace, Physics::Forcefield& ffs, Physics::Forcefield& ff, const Library::RotamerLibrary& rotLib ) { // Our moveset Manipulator::MoveSet moves( wspace ); Manipulator::SidechainRotamerLibMove* rotamer = new Manipulator::SidechainRotamerLibMove( wspace, rotLib, 1.0, 1.0 ); moves.addWithOwnership( rotamer ); // Minimise only the sidechains Protocol::DualFFMinimiser eval(ff, ffs, PickSidechains() ); eval.SDPreMinSteps = 31; eval.StericMinSteps = 501; eval.Steps = 501; eval.StepSize = 2E1; //eval.!OutputLevel = true; eval.UpdateScr = 50; //eval.UpdateTra = 1; //eval.UpdateMon = 10; eval.run(); // Perform a montecarlo procedure Protocol::MonteCarlo mc( eval, moves ); mc.Steps = 10; mc.UpdateTra = 1; mc.UpdateScr = 1; mc.UpdateTraAcc = true; //mc.UpdateTraRej = true; mc.FinalState = Protocol::MonteCarlo::LowestEpot; mc.run(); // Pack sidechains using the rotamers }
int MatchCSA::SendMove( THINK_INFO* pthink_info ){ /************************************************ 指し手の送信 ************************************************/ ostringstream ss; int value; // 送信する文字列を生成 ss << pshogi->GetStrMoveCSA(); if( floodgate != 0 && pthink_info != NULL && pthink_info->bPVMove ){ // floodgateモード 評価値を送信 value = (int)pthink_info->value * 100 / pshogi->GetV_BAN( SFU ); if( info.sengo == GOTE ){ value = -value; } ss << ",\'* "<< value; // 読みを送信 2010/09/10 int i; KOMA sengo; Moves moves( MAX_DEPTH ); pcons->GetPVMove( moves ); sengo = pshogi->GetSengo(); for( i = 1 ; i < moves.GetNumber() ; i++ ){ ss << ' ' << Shogi::GetStrMoveCSA( moves[i], sengo ); sengo ^= SENGO; } } // 改行 ss << '\n'; if( -1 == SendMessage( ss.str().c_str() ) ){ cerr << "Couldn't send a message." << '\n'; return 0; } // 応答を待つ。 if( info.sengo == SENTE ){ if( GetRecFlag( MATCH_CSA_SENTE ) ){ InputTime( MoveStrSelf() ); return 1; } } else{ if( GetRecFlag( MATCH_CSA_GOTE ) ){ InputTime( MoveStrSelf() ); return 1; } } return 0; }
int main(void) { int n,i; int a[10001]; while(1) { scanf("%d",&n); if(n==-1) break; for(i=0;i<n;i++) scanf("%d",&a[i]); moves(a,n); } return 0; }
SgPoint SpSimplePlayer::GenMove(const SgTimeRecord& time, SgBlackWhite toPlay) { SG_UNUSED(time); SgPointSet relevant = SpUtil::GetRelevantMoves(Board(), toPlay, UseFilter()); // Generate moves. SgEvaluatedMovesArray moves(relevant); // note: generators can disable certain unwanted moves by calling // Disable(p) m_generator->GenerateMoves(moves, toPlay); // Generate random moves if no other found if ((moves.BestMove() == SG_PASS) && m_randomGenerator) m_randomGenerator->GenerateMoves(moves, toPlay); return moves.BestMove(); }
int main(void) { int n; printf("Enter the number of disks: "); scanf("%d",&n); int i; int m=1; for (i=1;i<n+1;i++) { m=2*m; } m=m-1; printf("The Tower of Hanoi is solved in %d moves. \n",m); printf("This involves the moves: \n \n"); moves(n,'A','C','B'); return 0; }
bool Solver::solve(Grid& solution, int& steps, Grid& grid) { int index = selectIndex(grid); if (index == -1) { solution = grid; return true; } vector<int> moves(begin(grid[index]), end(grid[index])); sortMoves(grid, moves, index); for (auto& value : moves) { steps++; Grid nextGrid(grid); if (nextGrid.assign(index, value) && solve(solution, steps, nextGrid)) return true; } return false; }
bool AnimalDatabase::save() { const auto dataByID = getByID(); QFile file(k_path); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qCritical() << "Could not open" << k_path; return false; } QXmlStreamWriter writer(&file); writer.setAutoFormatting(true); writer.writeStartDocument(); writer.writeStartElement("animals"); for (const auto & p : dataByID) { const auto data = p.second; writer.writeStartElement(k_name); writer.writeAttribute("id", QString::number(p.first)); writer.writeStartElement("name"); writer.writeCharacters(data.getName()); writer.writeEndElement(); { writer.writeStartElement("type"); writer.writeStartElement("primary"); writer.writeCharacters(data.primaryType()); writer.writeEndElement(); writer.writeStartElement("secondary"); writer.writeCharacters(data.secondaryType()); writer.writeEndElement(); writer.writeEndElement(); } { writer.writeStartElement("basestats"); writer.writeStartElement("hp"); writer.writeCharacters(QString::number(data.baseHP())); writer.writeEndElement(); writer.writeStartElement("attack"); writer.writeCharacters(QString::number(data.baseAttack())); writer.writeEndElement(); writer.writeStartElement("defense"); writer.writeCharacters(QString::number(data.baseDefense())); writer.writeEndElement(); writer.writeStartElement("speed"); writer.writeCharacters(QString::number(data.baseSpeed())); writer.writeEndElement(); writer.writeStartElement("specialattack"); writer.writeCharacters(QString::number(data.baseSpecialAttack())); writer.writeEndElement(); writer.writeStartElement("specialdefense"); writer.writeCharacters(QString::number(data.baseSpecialDefense())); writer.writeEndElement(); writer.writeStartElement("xp"); writer.writeCharacters(QString::number(data.baseXP())); writer.writeEndElement(); writer.writeEndElement(); } { writer.writeStartElement("moves"); for (const auto & move : data.moves()) { writer.writeStartElement("move"); writer.writeStartElement("name"); writer.writeCharacters(move.second); writer.writeEndElement(); writer.writeStartElement("level"); writer.writeCharacters(QString::number(move.first)); writer.writeEndElement(); writer.writeEndElement(); } writer.writeEndElement(); } { writer.writeStartElement("evolutions"); for (const auto & evolution : data.evolutions()) { writer.writeStartElement("evolution"); writer.writeStartElement("name"); writer.writeCharacters(std::get<0>(evolution)); writer.writeEndElement(); writer.writeStartElement("method"); writer.writeCharacters(std::get<1>(evolution)); writer.writeEndElement(); writer.writeStartElement("value"); writer.writeCharacters(QString::number(std::get<2>(evolution))); writer.writeEndElement(); writer.writeEndElement(); } writer.writeEndElement(); } writer.writeEndElement(); } writer.writeEndElement(); writer.writeEndDocument(); return true; }
vector<Message> AIInterface::getValidMoves(Duel* d) { vector<Message> moves(0); int player = getPlayerToMove(d); if (d->turn == player && d->attackphase == PHASE_NONE && !(d->isChoiceActive) && d->castingcard == -1) { Message m("endturn"); m.addValue("player", d->turn); moves.push_back(m); } else if (d->isChoiceActive && player == d->choicePlayer) { if (d->choice->buttoncount > 0) { Message msg("choiceselect"); msg.addValue("selection", RETURN_BUTTON1); moves.push_back(msg); } if (d->choice->buttoncount > 1) { Message msg("choiceselect"); msg.addValue("selection", RETURN_BUTTON2); moves.push_back(msg); } for (vector<Card*>::iterator i = d->CardList.begin(); i != d->CardList.end(); i++) { if ((*i)->Zone != ZONE_EVOLVED) { if (d->choice->callvalid(d->choiceCard, (*i)->UniqueId) == 1) { Message msg("choiceselect"); msg.addValue("selection", (*i)->UniqueId); moves.push_back(msg); } } } } else if (d->attackphase == PHASE_TRIGGER && player == getOpponent(d->turn)) //use shield triggers { for (vector<Card*>::iterator i = d->hands[getOpponent(d->turn)].cards.begin(); i != d->hands[getOpponent(d->turn)].cards.end(); i++) { for (vector<int>::iterator j = d->shieldtargets.begin(); j != d->shieldtargets.end(); j++) { if (*j == (*i)->UniqueId) { if (d->getIsShieldTrigger(*j) && d->canUseShieldTrigger(*j) && d->getCardCanCast(*j)) { Message msg("triggeruse"); msg.addValue("trigger", *j); moves.push_back(msg); } } } } Message m("triggerskip"); moves.push_back(m); } else if (d->attackphase == PHASE_TARGET && player == d->turn) //target shields { for (vector<Card*>::iterator i = d->shields[getOpponent(d->turn)].cards.begin(); i != d->shields[getOpponent(d->turn)].cards.end(); i++) { Message m("targetshield"); m.addValue("attacker", d->attacker); m.addValue("shield", (*i)->UniqueId); moves.push_back(m); } } else if (d->attackphase == PHASE_BLOCK && player == getOpponent(d->turn)) //block { for (vector<Card*>::iterator i = d->battlezones[getOpponent(d->turn)].cards.begin(); i != d->battlezones[getOpponent(d->turn)].cards.end(); i++) { if (d->getCreatureCanBlock(d->attacker, (*i)->UniqueId) && (*i)->isTapped == false && ((*i)->UniqueId != d->defender || d->defendertype == DEFENDER_PLAYER)) { /*Message msg2("cardtap"); msg2.addValue("card", (*i)->UniqueId); MsgMngr.sendMessage(msg2);*/ Message msg("creatureblock"); msg.addValue("attacker", d->attacker); msg.addValue("blocker", (*i)->UniqueId); moves.push_back(msg); } } Message m("blockskip"); moves.push_back(m); } else if (d->castingcard != -1 && player == d->turn) //tap mana { for (vector<Card*>::iterator i = d->manazones[d->turn].cards.begin(); i != d->manazones[d->turn].cards.end(); i++) { if ((*i)->isTapped == false) { if (d->castingcost == 1) //last card to be tapped { if (d->getCardCivilization((*i)->UniqueId) == d->castingciv || d->castingcivtapped) { Message m("manatap"); m.addValue("card", (*i)->UniqueId); moves.push_back(m); } } else { Message m("manatap"); m.addValue("card", (*i)->UniqueId); moves.push_back(m); } } } } if (player == d->turn && !d->isChoiceActive) { for (vector<Card*>::iterator i = d->hands[d->turn].cards.begin(); i != d->hands[d->turn].cards.end(); i++) { if (d->getCardCost((*i)->UniqueId) <= d->manazones[d->turn].getUntappedMana() && d->isThereUntappedManaOfCiv(d->turn, d->getCardCivilization((*i)->UniqueId)) && d->getCardCanCast((*i)->UniqueId) == 1) { if (d->getIsEvolution((*i)->UniqueId) == 1) { for (vector<Card*>::iterator j = d->battlezones[d->turn].cards.begin(); j != d->battlezones[d->turn].cards.end(); j++) { if (d->getCreatureCanEvolve((*i)->UniqueId, (*j)->UniqueId) == 1) { Message msg("cardplay"); msg.addValue("card", (*i)->UniqueId); msg.addValue("evobait", (*j)->UniqueId); moves.push_back(msg); } } } else { Message msg("cardplay"); msg.addValue("card", (*i)->UniqueId); msg.addValue("evobait", -1); moves.push_back(msg); } } if (d->manaUsed == 0) { Message msg("cardmana"); msg.addValue("card", (*i)->UniqueId); moves.push_back(msg); } } } if (player == d->turn && !d->isChoiceActive) { for (vector<Card*>::iterator i = d->battlezones[d->turn].cards.begin(); i != d->battlezones[d->turn].cards.end(); i++) { int canattack = d->getCreatureCanAttackPlayers((*i)->UniqueId); if ((canattack == CANATTACK_ALWAYS || ((d->CardList.at((*i)->UniqueId)->summoningSickness == 0 || d->getIsSpeedAttacker((*i)->UniqueId) == 1) && (canattack == CANATTACK_TAPPED || canattack == CANATTACK_UNTAPPED))) && d->CardList.at((*i)->UniqueId)->isTapped == false) { Message msg("creatureattack"); msg.addValue("attacker", (*i)->UniqueId); msg.addValue("defender", getOpponent(d->turn)); msg.addValue("defendertype", DEFENDER_PLAYER); moves.push_back(msg); } for (vector<Card*>::iterator j = d->battlezones[getOpponent(d->turn)].cards.begin(); j != d->battlezones[getOpponent(d->turn)].cards.end(); j++) { int canattack = d->getCreatureCanAttackCreature((*i)->UniqueId, (*j)->UniqueId); if (((*j)->isTapped == true || canattack == CANATTACK_UNTAPPED) && canattack <= CANATTACK_UNTAPPED && d->CardList.at((*i)->UniqueId)->summoningSickness == 0 && d->CardList.at((*i)->UniqueId)->isTapped == false) { Message msg("creatureattack"); msg.addValue("attacker", (*i)->UniqueId); msg.addValue("defender", (*j)->UniqueId); msg.addValue("defendertype", DEFENDER_CREATURE); moves.push_back(msg); } } } } return moves; }
int main(void) { // for application time calculations static GLfloat last = 0; GLfloat timer = glfwGetTime(); GLfloat start; start = timer; last = timer; // array of circles Circle circles[CIRCLE_NUM]; int length = CIRCLE_NUM; int i; int currentCircleIndex; // time to wait before moving the circle GLfloat sleep = 0.01; // total running time GLfloat total = TOTAL_TIME * 60; // 1 minutes has 60 seconds // output file name char text[] = "output.txt"; // output stream FILE * out = fopen(text, "w"); globalOut = out; //initialize the global variable chosenCircleIndex = 0; currentCircleIndex = chosenCircleIndex; currentCircle = &circles[currentCircleIndex]; srand(time(NULL)); initCircleArray(circles, length); glfwSetErrorCallback(error); if (!glfwInit() || out == NULL) { return -1; } window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "two_co", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glViewport(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, 0, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR); glfwSetCursor( window, cursor ); // set to null to reset cursor glfwSetKeyCallback(window, key_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); while (timer - start < total && !glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT); timer = glfwGetTime(); writeToFile(out, circles[currentCircleIndex], timer, window); // whether we should change the color if (currentCircleIndex != chosenCircleIndex) { currentCircleIndex = chosenCircleIndex; // set all circle to blue for (i = 0; i < length; i++) { circles[i].colour[0] = 0; circles[i].colour[1] = 0; circles[i].colour[2] = 255; } // set green color to the chosen circle circles[currentCircleIndex].colour[0] = 0; circles[currentCircleIndex].colour[1] = 255; circles[currentCircleIndex].colour[2] = 0; currentCircle = &circles[currentCircleIndex]; } // whether we should move the circle if (timer - last > sleep) { last = timer; for (i = 0; i < length; i++) { moves(circles, length, i); drawCircle(circles[i]); } } else { for (i = 0; i < length; i++) { drawCircle(circles[i]); } } glfwSwapBuffers(window); glfwPollEvents(); } fclose(out); glfwDestroyWindow(window); glfwTerminate(); return 0; }
TEST(MovesTest, Score) { Board board; Pieces pieces; Position position; MoveList list; Moves moves(board, pieces, position, list); Moves::init_mvv_lva_scores(); for (const PieceType& v : PIECE_TYPES) { for (const PieceType& a : PIECE_TYPES) { Square to = E5; Square from; switch (a) { case KNIGHT: from = D3; break; default: from = D4; break; } board[from] = Piece(WHITE, a); board[to] = Piece(BLACK, v); Move capture(from, to, CAPTURE); Score score = moves.mvv_lva_score(capture); EXPECT_GT(BEST_SCORE, score); EXPECT_LT(KILLERS_SCORE, score); for (const PieceType& v2 : PIECE_TYPES) { for (const PieceType& a2 : PIECE_TYPES) { switch (a2) { case KNIGHT: from = D3; break; default: from = D4; break; } board[from] = Piece(WHITE, a2); board[to] = Piece(BLACK, v2); Move capture2(from, to, CAPTURE); Score score2 = moves.mvv_lva_score(capture2); if (v > v2) { EXPECT_GT(score, score2); } else if (v < v2) { EXPECT_LT(score, score2); } else { if (a > a2) { EXPECT_LT(score, score2); } else if (a < a2) { EXPECT_GT(score, score2); } else { EXPECT_EQ(score, score2); } } } } } } }
int Circle::check_collision_with_bat( Bat& bat, PotentialMove **pm, double ftr) { int current_ticks; int n; float future_x_at_bat_y; int vn; int result; double dx; /* Need to get this from the Bat Class - how far the bat moves horizontally. */ double cmx, cmy; double circle_to_bat_angle = principal_value_2(atan2( bat.cy - cc_y, bat.cx - cc_x )); PotentialMove *m; vector <PotentialMove *> moves(0); int move_number = 0; switch( bat.direction ) { case BAT_NOT_MOVING: dx = 0.0f; break; case BAT_MOVING_LEFT: //logfile << "setting \n"; dx = - bat.movement_inc * ftr; break; case BAT_MOVING_RIGHT: dx = bat.movement_inc * ftr; break; } /* check for collision against edges of bat */ for(vn = 0; vn < 4; ++vn) { if( circle_and_line_collision( PONGPING_TRANSLATION, bat.bat_vertices[vn], bat.bat_vertices[vn + 1], bat.get_bat_midpoint_x(), bat.get_bat_midpoint_y(), 0, dx, 0.0, this, *pm, 0, ftr) ) { /* Do I need to distinguish between side collisions and vertex collisions ? */ (*pm)->set_hit_type_and_side(PONGPING_BAT_COLLISION, vn); return 1; } } /* check for collision against vertices of bat */ m = new PotentialMove(); moves.push_back(m); for(vn = 0; vn < 4; ++vn) { logfile << "checking vertex " << vn << "\n\n"; /* int (const unsigned char vertex_move, const double cx, const double cy, const int use_centre_of_mass, const double cmx, const double cmy, const Point v, const double angle, const int dx, const int dy, Circle *c, PotentialMove& move); */ if(cvc( PONGPING_TRANSLATION, 0.0, 0.0, PONGPING_USE_CENTRE_OF_MASS, bat.get_bat_midpoint_x(), bat.get_bat_midpoint_y(), bat.get_mass(), bat.bat_vertices[vn], 0.0, dx, 0.0, this, moves[move_number], ftr)) { moves[move_number]->set_hit_type_and_side(PONGPING_BAT_COLLISION, vn); ++move_number; //logfile << "move_number = " << move_number << "\n"; //pm.hit_type = PONGPING_BAT_COLLISION; m = new PotentialMove(); moves.push_back(m); //return 1; } } vector< PotentialMove* >::iterator it = moves.end(); if(move_number > 0) { --it; sort(moves.begin(), it, compare_distance); (*pm) = moves[0]; //logfile << "got a vertex hit.\n"; //eek(); return 1; } return 0; }
double ChessAI::findBestMove(bool playIt, int iter) { PieceColor color=colorToMove; Square s, e; MoveHolder moves(settings.checkWidth); if (checkForBoringTie()) { //err << "\n\n\n BORING TIE FOUND\n\n\n" << err; return 0.5; } for (int i=((color==WHITE)?0:16); i<((color==WHITE)?16:32); ++i) { if (pieces[i].alive) { s=pieces[i].square; for (e.y=0; e.y<8; ++e.y) { for (e.x=0; e.x<8; ++e.x) { bool path=checkMovePath(s, e); bool check=checkCheck(colorToMove, s, e); if (path && check) { forceMove(s, e); moves.add(MoveData(s, e, eval(color))); undo(); checkBoard(); } } } } } if (moves.size()<1) { if (checkCheck(color, kings[color]->square, kings[color]->square)) return 0.5; else return 0.0; } MoveData bestMove; bestMove.score=-1; for (auto i=moves.begin(); i!=moves.end(); ++i) { for (int j=settings.checkDepth; j>iter; --j) err << " "; err << pieceColor2Name(color) << " " << pieceType2Name(board((*i).s)->type) << " from " << (*i).s.str() << " to " << (*i).e.str() << err; forceMove((*i).s, (*i).e); double score=0; if (iter<=0) { score=eval(color); } else { score=1-findBestMove(false, iter-1); } undo(); for (int j=settings.checkDepth+1; j>iter; --j) err << " "; err << "best score for " << pieceColor2Name(myColor) << ": " << ((myColor==color)?score:1-score) << err; if (score>bestMove.score) { bestMove.s=(*i).s; bestMove.e=(*i).e; bestMove.score=score; } } if (playIt) { return game->playMove(bestMove.s, bestMove.e); } else { return bestMove.score; } }
void EngineControl::startThread(int minTimeLimit, int maxTimeLimit, int maxDepth, int maxNodes) { Parameters& par = Parameters::instance(); Search::SearchTables st(tt, kt, ht, *et); sc = std::make_shared<Search>(pos, posHashList, posHashListSize, st, pd, nullptr, treeLog); sc->setListener(std::make_shared<SearchListener>(os)); sc->setStrength(par.getIntPar("Strength"), randomSeed); std::shared_ptr<MoveGen::MoveList> moves(std::make_shared<MoveGen::MoveList>()); MoveGen::pseudoLegalMoves(pos, *moves); MoveGen::removeIllegal(pos, *moves); if (searchMoves.size() > 0) moves->filter(searchMoves); onePossibleMove = false; if ((moves->size < 2) && !infinite) { onePossibleMove = true; if (!ponder) { if (maxTimeLimit > 0) { maxTimeLimit = clamp(maxTimeLimit/100, 1, 100); minTimeLimit = clamp(minTimeLimit/100, 1, 100); } else { if ((maxDepth < 0) || (maxDepth > 2)) maxDepth = 2; } } } pd.addRemoveWorkers(par.getIntPar("Threads") - 1); pd.wq.resetSplitDepth(); pd.startAll(); sc->timeLimit(minTimeLimit, maxTimeLimit); tt.nextGeneration(); bool ownBook = par.getBoolPar("OwnBook"); bool analyseMode = par.getBoolPar("UCI_AnalyseMode"); int maxPV = (infinite || analyseMode) ? par.getIntPar("MultiPV") : 1; if (analyseMode) { Evaluate eval(*et); int evScore = eval.evalPosPrint(pos) * (pos.getWhiteMove() ? 1 : -1); std::stringstream ss; ss.precision(2); ss << std::fixed << (evScore / 100.0); os << "info string Eval: " << ss.str() << std::endl; } auto f = [this,ownBook,analyseMode,moves,maxDepth,maxNodes,maxPV]() { Move m; if (ownBook && !analyseMode) { Book book(false); book.getBookMove(pos, m); } if (m.isEmpty()) m = sc->iterativeDeepening(*moves, maxDepth, maxNodes, false, maxPV); while (ponder || infinite) { // We should not respond until told to do so. Just wait until // we are allowed to respond. std::this_thread::sleep_for(std::chrono::milliseconds(10)); } Move ponderMove = getPonderMove(pos, m); std::lock_guard<std::mutex> L(threadMutex); os << "bestmove " << moveToString(m); if (!ponderMove.isEmpty()) os << " ponder " << moveToString(ponderMove); os << std::endl; if (shouldDetach) { engineThread->detach(); pd.stopAll(); pd.fhInfo.reScale(); } engineThread.reset(); sc.reset(); }; shouldDetach = true; { std::lock_guard<std::mutex> L(threadMutex); engineThread = std::make_shared<std::thread>(f); } }