// start_thinking() wakes up the main thread sleeping in MainThread::idle_loop() // so to start a new search, then returns immediately. public void start_thinking(Position pos, LimitsType limits, StateStackPtr states) { wait_for_think_finished(); Search.SearchTime = Time.now(); // As early as possible Search.Signals.stopOnPonderhit = Search.Signals.firstRootMove = false; Search.Signals.stop = Search.Signals.failedLowAtRoot = false; Search.RootMoves.Clear(); Search.RootPos = pos; Search.Limits = limits; if (states.Count > 0) // If we don't set a new position, preserve current state { Search.SetupStates = states; // Ownership transfer here //Debug.Assert(states==null); } for (MoveList it = new MoveList(pos, GenTypeS.LEGAL); it.move()!= 0; ++it) if (limits.searchmoves.Count == 0 || Misc.existSearchMove(limits.searchmoves, it.move())) Search.RootMoves.Add(new RootMove(it.move())); main().thinking = true; main().notify_one(); // Starts main thread }
/// move_from_uci() takes a position and a string representing a move in /// simple coordinate notation and returns an equivalent legal Move if any. public static Move move_from_uci(Position pos, string str) { if (str.Length == 5) { // Junior could send promotion piece in uppercase char[] strChar = str.ToCharArray(); strChar[4] = char.ToLower(strChar[4]); str = new String(strChar); } for (MoveList it = new MoveList(pos, GenTypeS.LEGAL); it.mlist[it.cur].move != MoveS.MOVE_NONE; ++it) { if (str == move_to_uci(it.move(), pos.is_chess960() != 0)) { return(it.move()); } } return(MoveS.MOVE_NONE); }
/// probe() tries to find a book move for the given position. If no move is /// found returns MOVE_NONE. If pickBest is true returns always the highest /// rated move, otherwise randomly chooses one, based on the move score. public Move probe(Position pos, string fName, bool pickBest) { if (fName == null || (fileName != fName && !open(fName))) { return(MoveS.MOVE_NONE); } PolyglotBook.Entry e = new PolyglotBook.Entry(); UInt16 best = 0; uint sum = 0; Move move = MoveS.MOVE_NONE; Key key = polyglot_key(pos); stream.Seek(find_first(key) * SIZE_OF_BOOKENTRY, SeekOrigin.Begin); while (read(ref e) && e.key == key) { best = Math.Max(best, e.count); sum += e.count; // Choose book move according to its score. If a move has a very // high score it has higher probability to be choosen than a move // with lower score. Note that first entry is always chosen. if ((sum != 0 && ((((uint)RKiss.rand64()) % sum) < e.count)) || (pickBest && e.count == best)) { move = (e.move); } } if (move == 0) { return(MoveS.MOVE_NONE); } // A PolyGlot book move is encoded as follows: // // bit 0- 5: destination square (from 0 to 63) // bit 6-11: origin square (from 0 to 63) // bit 12-14: promotion piece (from KNIGHT == 1 to QUEEN == 4) // // Castling moves follow "king captures rook" representation. So in case book // move is a promotion we have to convert to our representation, in all the // other cases we can directly compare with a Move after having masked out // the special Move's flags (bit 14-15) that are not supported by PolyGlot. int pt = (move >> 12) & 7; if (pt != 0) { move = Types.make(Types.from_sq(move), Types.to_sq(move), MoveTypeS.PROMOTION, (pt + 1)); } // Add 'special move' flags and verify it is legal for (MoveList ml = new MoveList(pos, GenTypeS.LEGAL); ml.mlist[ml.cur].move != MoveS.MOVE_NONE; ++ml) { if (move == (ml.move() ^ Types.type_of_move(ml.move()))) { return(ml.move()); } } return(MoveS.MOVE_NONE); }