private Move findSemiRandomMove(Search sc, MoveGen.MoveList moves) { sc.timeLimit(minTimeMillis, maxTimeMillis); Move bestM = sc.iterativeDeepening(moves, 1, maxNodes, verbose); int bestScore = bestM.score; long t0 = SystemHelper.currentTimeMillis(); Random rndGen = new Random((int)t0); int sum = 0; for (int mi = 0; mi < moves.size; mi++) { sum += moveProbWeight(moves.m[mi].score, bestScore); } int rnd = rndGen.Next(sum); for (int mi = 0; mi < moves.size; mi++) { int weight = moveProbWeight(moves.m[mi].score, bestScore); if (rnd < weight) { return(moves.m[mi]); } rnd -= weight; } SystemHelper.println("Assert error. Should never get here!"); return(null); }
private void initBook(bool verbose) { bookMap = new Dictionary <ulong, List <BookEntry> >(); long t0 = SystemHelper.currentTimeMillis(); numBookMoves = 0; try { /* read /book.bin into buf */ Byte[] buf = Bookbin.DATA; Position startPos = TextIO.readFEN(TextIO.startPosFEN); Position pos = new Position(startPos); UndoInfo ui = new UndoInfo(); int len = buf.Length; for (int i = 0; i < len; i += 2) { int b0 = buf[i]; if (b0 < 0) { b0 += 256; } int b1 = buf[i + 1]; if (b1 < 0) { b1 += 256; } int move = (b0 << 8) + b1; if (move == 0) { pos = new Position(startPos); } else { bool bad = ((move >> 15) & 1) != 0; int prom = (move >> 12) & 7; Move m = new Move(move & 63, (move >> 6) & 63, promToPiece(prom, pos.whiteMove)); if (!bad) { addToBook(pos, m); } pos.makeMove(m, ui); } } } catch (ChessParseError ex) { throw new RuntimeException(); } catch (IOException ex) { SystemHelper.println("Can't read opening book resource"); throw new RuntimeException(); } if (verbose) { long t1 = SystemHelper.currentTimeMillis(); SystemHelper.printf("Book moves: " + numBookMoves.ToString() + "(parse time: " + ((t1 - t0) / 1000).ToString() + ")"); } }
/** Return a random book move for a position, or null if out of book. */ public Move getBookMove(Position pos) { long t0 = SystemHelper.currentTimeMillis(); Random rndGen = new Random((int)t0); ulong key = pos.zobristHash(); bool iskey = bookMap.ContainsKey(key); List <BookEntry> bookMoves = (iskey ? bookMap[key] : null); if (bookMoves == null) { return(null); } MoveGen.MoveList legalMoves = new MoveGen().pseudoLegalMoves(pos); MoveGen.RemoveIllegal(pos, legalMoves); int sum = 0; for (int i = 0; i < bookMoves.Count; i++) { BookEntry be = bookMoves[i]; bool contains = false; for (int mi = 0; mi < legalMoves.size; mi++) { if (legalMoves.m[mi].equals(be.move)) { contains = true; break; } } if (!contains) { // If an illegal move was found, it means there was a hash collision. return(null); } sum += getWeight(bookMoves[i].count); } if (sum <= 0) { return(null); } int rnd = rndGen.Next(sum); sum = 0; for (int i = 0; i < bookMoves.Count; i++) { sum += getWeight(bookMoves[i].count); if (rnd < sum) { return(bookMoves[i].move); } } // Should never get here throw new RuntimeException(); }
/** * Handle a special command. * @param moveStr The command to handle * @return True if command handled, false otherwise. */ public bool handleCommand(string moveStr) { if (moveStr == "new") { moveList = new List <Move>(); uiInfoList = new List <UndoInfo>(); drawOfferList = new List <bool>(); currentMove = 0; pendingDrawOffer = false; drawState = GameState.ALIVE; resignState = GameState.ALIVE; try { pos = TextIO.readFEN(TextIO.startPosFEN); } catch (ChessParseError ex) { throw new RuntimeException(); } whitePlayer.clearTT(); blackPlayer.clearTT(); activateHumanPlayer(); return(true); } else if (moveStr == "undo") { if (currentMove > 0) { pos.unMakeMove(moveList[currentMove - 1], uiInfoList[currentMove - 1]); currentMove--; pendingDrawOffer = false; drawState = GameState.ALIVE; resignState = GameState.ALIVE; return(handleCommand("swap")); } else { SystemHelper.println("Nothing to undo"); } return(true); } else if (moveStr == "redo") { if (currentMove < moveList.Count) { pos.makeMove(moveList[currentMove], uiInfoList[currentMove]); currentMove++; pendingDrawOffer = false; return(handleCommand("swap")); } else { SystemHelper.println("Nothing to redo"); } return(true); } else if ((moveStr == "swap") || (moveStr == "go")) { Player tmp = whitePlayer; whitePlayer = blackPlayer; blackPlayer = tmp; return(true); } else if (moveStr == "list") { listMoves(); return(true); } else if (moveStr.StartsWith("setpos ")) { string fen = moveStr.Substring(moveStr.IndexOf(" ") + 1); Position newPos = null; try { newPos = TextIO.readFEN(fen); } catch (ChessParseError ex) { SystemHelper.printf("Invalid FEN: " + fen); } if (newPos != null) { handleCommand("new"); pos = newPos; activateHumanPlayer(); } return(true); } else if (moveStr == "getpos") { string fen = TextIO.toFEN(pos); SystemHelper.println(fen); return(true); } else if (moveStr.StartsWith("draw ")) { if (getGameState() == GameState.ALIVE) { string drawCmd = moveStr.Substring(moveStr.IndexOf(" ") + 1); return(handleDrawCmd(drawCmd)); } else { return(true); } } else if (moveStr == "resign") { if (getGameState() == GameState.ALIVE) { resignState = pos.whiteMove ? GameState.RESIGN_WHITE : GameState.RESIGN_BLACK; return(true); } else { return(true); } } else if (moveStr.StartsWith("book")) { string bookCmd = moveStr.Substring(moveStr.IndexOf(" ") + 1); return(handleBookCmd(bookCmd)); } else if (moveStr.StartsWith("time")) { try { string timeStr = moveStr.Substring(moveStr.IndexOf(" ") + 1); int timeLimit = int.Parse(timeStr); whitePlayer.timeLimit(timeLimit, timeLimit, false); blackPlayer.timeLimit(timeLimit, timeLimit, false); return(true); } catch (NumberFormatException nfe) { SystemHelper.printf("Number format exception: " + moveStr); return(false); } } else if (moveStr.StartsWith("perft ")) { try { string depthStr = moveStr.Substring(moveStr.IndexOf(" ") + 1); int depth = int.Parse(depthStr); MoveGen moveGen = new MoveGen(); long t0 = SystemHelper.currentTimeMillis(); ulong nodes = perfT(moveGen, pos, depth); long t1 = SystemHelper.currentTimeMillis(); SystemHelper.printf("perft(" + depth.ToString() + ") = " + nodes.ToString() + " t=" + ((t1 - t0) / 1000).ToString() + "s"); } catch (NumberFormatException nfe) { SystemHelper.printf("Number format exception: " + moveStr); return(false); } return(true); } else { return(false); } }