/** Return a string describing all book moves. */ public string getAllBookMoves(Position pos) { string ret = ""; List<BookEntry> bookMoves = bookMap[pos.zobristHash()]; if (bookMoves != null) { BookEntry be; for (int i = 0; i < bookMoves.Count; i++) { be = bookMoves[i]; string moveStr = TextIO.moveTostring(pos, be.move, false); ret = ret + (moveStr + "(" + be.count.ToString() + ") "); } } return ret; }
/** 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(); }
/** Extract the PV starting from pos, using hash entries, both exact scores and bounds. */ public string extractPV(Position pos) { string ret = ""; pos = new Position(pos); // To avoid modifying the input parameter bool first = true; TTEntry ent = probe(pos.historyHash()); UndoInfo ui = new UndoInfo(); List<ulong> hashHistory = new List<ulong>(); bool repetition = false; while (ent.type != TTEntry.T_EMPTY) { string type = ""; if (ent.type == TTEntry.T_LE) { type = "<"; } else if (ent.type == TTEntry.T_GE) { type = ">"; } Move m = new Move(0,0,0); ent.getMove(m); MoveGen MG = new MoveGen(); MoveGen.MoveList moves = MG.pseudoLegalMoves(pos); MoveGen.RemoveIllegal(pos, moves); bool contains = false; for (int mi = 0; mi < moves.size; mi++) if (moves.m[mi].equals(m)) { contains = true; break; } if (!contains) break; string moveStr = TextIO.moveTostring(pos, m, false); if (repetition) break; if (!first) { ret += " "; } ret += type + moveStr; pos.makeMove(m, ui); if (hashHistory.Contains(pos.zobristHash())) { repetition = true; } hashHistory.Add(pos.zobristHash()); ent = probe(pos.historyHash()); first = false; } return ret; }
/** * Extract a list of PV moves, starting from "rootPos" and first move "m". */ public List<Move> extractPVMoves(Position rootPos, Move m) { Position pos = new Position(rootPos); m = new Move(m); List<Move> ret = new List<Move>(); UndoInfo ui = new UndoInfo(); List<ulong> hashHistory = new List<ulong>(); MoveGen moveGen = new MoveGen(); while (true) { ret.Add(m); pos.makeMove(m, ui); if (hashHistory.Contains(pos.zobristHash())) { break; } hashHistory.Add(pos.zobristHash()); TTEntry ent = probe(pos.historyHash()); if (ent.type == TTEntry.T_EMPTY) { break; } m = new Move(0,0,0); ent.getMove(m); MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos); MoveGen.RemoveIllegal(pos, moves); bool contains = false; for (int mi = 0; mi < moves.size; mi++) if (moves.m[mi].equals(m)) { contains = true; break; } if (!contains) break; } return ret; }
/** Check if a draw claim is allowed, possibly after playing "move". * @param move The move that may have to be made before claiming draw. * @return The draw string that claims the draw, or empty string if draw claim not valid. */ private string canClaimDraw(Position pos, ulong[] posHashList, int posHashListSize, Move move) { string drawStr = ""; if (Search.canClaimDraw50(pos)) { drawStr = "draw 50"; } else if (Search.canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize)) { drawStr = "draw rep"; } else { string strMove = TextIO.moveTostring(pos, move, false); posHashList[posHashListSize++] = pos.zobristHash(); UndoInfo ui = new UndoInfo(); pos.makeMove(move, ui); if (Search.canClaimDraw50(pos)) { drawStr = "draw 50 " + strMove; } else if (Search.canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize)) { drawStr = "draw rep " + strMove; } pos.unMakeMove(move, ui); } return drawStr; }
/** Add a move to a position in the opening book. */ private void addToBook(Position pos, Move moveToAdd) { ulong key = pos.zobristHash(); bool iskey = bookMap.ContainsKey(key); List<BookEntry> ent = (iskey ? bookMap[key] : null ); if (ent == null) { ent = new List<BookEntry>(); bookMap.Add( pos.zobristHash(), ent); } for (int i = 0; i < ent.Count; i++) { BookEntry be = ent[i]; if (be.move.equals(moveToAdd)) { be.count++; return; } } BookEntry be2 = new BookEntry(moveToAdd); ent.Add(be2); numBookMoves++; }