private void Sample() { CuckComp = new ComputerPlayer(); CuckHumn = new HumanPlayer(); CuckBK = new Book(false); CuckGM = new Game(CuckHumn, CuckComp); Position pos = CuckGM.getPos(); // e4(102) d4(31) ... string CurrentBookMoves = CuckBK.getAllBookMoves(pos); // Nb1-a3;Nb1-c3;...;a2-a3;a2-a4;... string CurrentValidMoves = TextIO.AllMovesTostring(pos, true); // RNB...w KQkq... string CurrentPositionFEN = TextIO.toFEN(pos); // Display board to console TextIO.DispBoard(pos); // Swap & move CuckGM.whitePlayer = CuckComp; CuckGM.blackPlayer = CuckHumn; ////CuckComp.bookEnabled = false; CuckComp.maxTimeMillis = 1 * 100; CuckComp.maxTimeMillis = 6 * 100; ////CuckComp.maxDepth = 6; // Ng1-f3 string CommandFromComp = CuckComp.getCommand(new Position(pos), CuckGM.haveDrawOffer(), CuckGM.getHistory()); }
public List <string> getPosHistory() { List <string> ret = new List <string>(); Position pos2 = new Position(pos /*this.pos*/); for (int i = currentMove; i > 0; i--) { pos2.unMakeMove(moveList[i - 1], uiInfoList[i - 1]); } ret.Add(TextIO.toFEN(pos2)); // Store initial FEN string moves = ""; for (int i = 0; i < moveList.Count; i++) { Move move = moveList[i]; string strMove = TextIO.moveTostring(pos2, move, false); moves += " " + strMove; UndoInfo ui = new UndoInfo(); pos2.makeMove(move, ui); } ret.Add(moves); // Store move list string int numUndo = moveList.Count - currentMove; ret.Add(((int)numUndo).ToString()); return(ret); }
/** Search a position and return the best move and score. Used for test suite processing. */ public TwoReturnValues <Move, string> searchPosition(Position pos, int maxTimeMillis) { // Create a search object ulong[] posHashList = new ulong[200]; tt.nextGeneration(); Search sc = new Search(pos, posHashList, 0, tt); // Determine all legal moves MoveGen.MoveList moves = new MoveGen().pseudoLegalMoves(pos); MoveGen.RemoveIllegal(pos, moves); sc.scoreMoveList(moves, 0); // Find best move using iterative deepening sc.timeLimit(maxTimeMillis, maxTimeMillis); Move bestM = sc.iterativeDeepening(moves, -1, -1, false); // Extract PV string PV = TextIO.moveTostring(pos, bestM, false) + " "; UndoInfo ui = new UndoInfo(); pos.makeMove(bestM, ui); PV += tt.extractPV(pos); pos.unMakeMove(bestM, ui); // tt.printStats(); // Return best move and PV return(new TwoReturnValues <Move, string>(bestM, PV)); }
/** * Update the game state according to move/command string from a player. * @param str The move or command to process. * @return True if str was understood, false otherwise. */ public bool processstring(string str) { if (handleCommand(str)) { return(true); } if (getGameState() != GameState.ALIVE) { return(false); } Move m = TextIO.stringToMove(pos, str); if (m == null) { return(false); } UndoInfo ui = new UndoInfo(); pos.makeMove(m, ui); TextIO.fixupEPSquare(pos); while (currentMove < moveList.Count) { moveList.RemoveAt(currentMove); uiInfoList.RemoveAt(currentMove); drawOfferList.RemoveAt(currentMove); } moveList.Add(m); uiInfoList.Add(ui); drawOfferList.Add(pendingDrawOffer); pendingDrawOffer = false; currentMove++; return(true); }
/** 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); }
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 { SystemHelper.println("Can't read opening book resource"); throw new RuntimeException(); } if (verbose) { long t1 = SystemHelper.currentTimeMillis(); SystemHelper.println("Book moves: " + numBookMoves.ToString() + "(parse time: " + ((t1 - t0) / 1000).ToString() + ")"); } }
/** 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); }
public static string simplyCalculateMove(string sFEN, int depth) { bool w2m = sFEN.Contains(" w "); CuckComp = new ComputerPlayer(); CuckHumn = new HumanPlayer(); if (w2m) { CuckGM = new Game(CuckComp, CuckHumn); } else { CuckGM = new Game(CuckHumn, CuckComp); } CuckGM.handleCommand("setpos " + sFEN); Position pos = CuckGM.getPos(); CuckComp.maxTimeMillis = 1 * 100; CuckComp.maxTimeMillis = 6 * 100; CuckComp.maxDepth = depth; string CurrentPositionFEN = TextIO.toFEN(pos); string cmd = CuckComp.getCommand(new Position(pos), CuckGM.haveDrawOffer(), CuckGM.getHistory()); string a = cmd; if ((a.Length > 1) && (("NBRQK").IndexOf(a[0]) >= 0)) { a = a.Substring(1); } if (a[0] == 'O') { a = (a.Length == 3 ? (w2m ? "e1g1" : "e8g8") : (w2m ? "e1c1" : "e8c8")); } else { a = ((a.Length > 4) ? a.Substring(0, 2) + a.Substring(3) : ""); } return(a); }
private bool handleDrawCmd(string drawCmd) { if (drawCmd.StartsWith("rep") || drawCmd.StartsWith("50")) { bool rep = drawCmd.StartsWith("rep"); Move m = null; string ms = drawCmd.Substring(drawCmd.IndexOf(" ") + 1); if (ms.Length > 0) { m = TextIO.stringToMove(pos, ms); } bool valid; if (rep) { valid = false; List <Position> oldPositions = new List <Position>(); Position tmpPos; if (m != null) { UndoInfo ui = new UndoInfo(); tmpPos = new Position(pos); tmpPos.makeMove(m, ui); oldPositions.Add(tmpPos); } oldPositions.Add(pos); tmpPos = pos; for (int i = currentMove - 1; i >= 0; i--) { tmpPos = new Position(tmpPos); tmpPos.unMakeMove(moveList[i], uiInfoList[i]); oldPositions.Add(tmpPos); } int repetitions = 0; Position firstPos = oldPositions[0]; for (int i = 0; i < oldPositions.Count; i++) { Position p = oldPositions[i]; if (p.drawRuleEquals(firstPos)) { repetitions++; } } if (repetitions >= 3) { valid = true; } } else { Position tmpPos = new Position(pos); if (m != null) { UndoInfo ui = new UndoInfo(); tmpPos.makeMove(m, ui); } valid = tmpPos.halfMoveClock >= 100; } if (valid) { drawState = rep ? GameState.DRAW_REP : GameState.DRAW_50; drawStateMoveStr = null; if (m != null) { drawStateMoveStr = TextIO.moveTostring(pos, m, false); } } else { pendingDrawOffer = true; if (m != null) { processstring(ms); } } return(true); } else if (drawCmd.StartsWith("offer ")) { pendingDrawOffer = true; string ms = drawCmd.Substring(drawCmd.IndexOf(" ") + 1); if (TextIO.stringToMove(pos, ms) != null) { processstring(ms); } return(true); } else if (drawCmd == "accept") { if (haveDrawOffer()) { drawState = GameState.DRAW_AGREE; } return(true); } else { return(false); } }
public string getMoveListstring(bool compressed) { string ret = ""; // Undo all moves in move history. Position pos2 = new Position(pos /*this.pos*/); for (int i = currentMove; i > 0; i--) { pos2.unMakeMove(moveList[i - 1], uiInfoList[i - 1]); } // Print all moves string whiteMove = ""; string blackMove = ""; for (int i = 0; i < currentMove; i++) { Move move = moveList[i]; string strMove = TextIO.moveTostring(pos2, move, false); if (drawOfferList[i]) { strMove += " (d)"; } if (pos2.whiteMove) { whiteMove = strMove; } else { blackMove = strMove; if (whiteMove.Length == 0) { whiteMove = "..."; } if (compressed) { ret += pos2.fullMoveCounter.ToString() + ". " + whiteMove + " " + blackMove + " "; } else { ret += pos2.fullMoveCounter.ToString() + ". " + whiteMove.PadRight(10) + " " + blackMove.PadRight(10) + " "; } whiteMove = ""; blackMove = ""; } UndoInfo ui = new UndoInfo(); pos2.makeMove(move, ui); } if ((whiteMove.Length > 0) || (blackMove.Length > 0)) { if (whiteMove.Length == 0) { whiteMove = "..."; } if (compressed) { ret += pos2.fullMoveCounter.ToString() + ". " + whiteMove + " " + blackMove + " "; } else { ret += pos2.fullMoveCounter.ToString() + ". " + whiteMove.PadRight(10) + " " + blackMove.PadRight(10) + " "; } } string gameResult = getPGNResultstring(); if (gameResult != "*") { ret += gameResult; } return(ret); }
/** * 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 { 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 { SystemHelper.println("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 { SystemHelper.println("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.println("perft(" + depth.ToString() + ") = " + nodes.ToString() + " t=" + ((t1 - t0) / 1000).ToString() + "s"); } catch { SystemHelper.println("Number format exception: " + moveStr); return(false); } return(true); } else { return(false); } }
/// <summary> /// Extract the PV starting from pos, using hash entries, both exact scores and bounds. /// </summary> /// <param name="pos"></param> /// <returns></returns> public string extractPV(Position pos) { pos = new Position(pos); string ret = ""; 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); }
public string getCommand(Position pos, bool drawOffer, List <Position> history) { // Create a search object ulong[] posHashList = new ulong[200 + history.Count]; int posHashListSize = 0; for (int i = 0; i < history.Count; i++) { Position p = history[i]; posHashList[posHashListSize++] = p.zobristHash(); } tt.nextGeneration(); Search sc = new Search(pos, posHashList, posHashListSize, tt); // Determine all legal moves MoveGen.MoveList moves = new MoveGen().pseudoLegalMoves(pos); MoveGen.RemoveIllegal(pos, moves); sc.scoreMoveList(moves, 0); // Test for "game over" if (moves.size == 0) { // Switch sides so that the human can decide what to do next. return("swap"); } if (bookEnabled) { Move bookMove = book.getBookMove(pos); if (bookMove != null) { SystemHelper.println("Book moves: " + book.getAllBookMoves(pos)); return(TextIO.moveTostring(pos, bookMove, true)); } } // Find best move using iterative deepening currentSearch = sc; sc.setListener(listener); Move bestM; if ((moves.size == 1) && (canClaimDraw(pos, posHashList, posHashListSize, moves.m[0]) == "")) { bestM = moves.m[0]; bestM.score = 0; } else if (randomMode) { bestM = findSemiRandomMove(sc, moves); } else { sc.timeLimit(minTimeMillis, maxTimeMillis); bestM = sc.iterativeDeepening(moves, maxDepth, maxNodes, verbose); } currentSearch = null; // tt.printStats(); string strMove = TextIO.moveTostring(pos, bestM, true); bestmv = bestM; // Claim draw if appropriate if (bestM.score <= 0) { string drawClaim = canClaimDraw(pos, posHashList, posHashListSize, bestM); if (drawClaim != "") { strMove = drawClaim; } } return(strMove); }
/** Useful for debugging. */ public string tostring() { return(TextIO.moveToUCIstring(this)); }