/// <summary> /// Constructs a test batch of specified size. /// </summary> /// <param name="evaluator"></param> /// <param name="count"></param> /// <param name="fen"></param> /// <returns></returns> public static EncodedPositionBatchFlat MakeTestBatch(NNEvaluator evaluator, int count, string fen = null) { EncodedPositionBatchFlat batch; if (fen == null) { fen = Position.StartPosition.FEN; } Position rawPos = Position.FromFEN(fen); MGPosition mgPos = MGPosition.FromPosition(rawPos); EncodedPositionWithHistory position = EncodedPositionWithHistory.FromFEN(fen); EncodedPositionWithHistory[] positions = new EncodedPositionWithHistory[count]; Array.Fill(positions, position); batch = new EncodedPositionBatchFlat(positions, count); bool hasPositions = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Positions); bool hasMoves = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Moves); bool hasHashes = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Hashes); bool hasBoards = evaluator.InputsRequired.HasFlag(NNEvaluator.InputTypes.Boards); if (fen != null) { if (hasPositions) { batch.Positions = new MGPosition[count]; } if (hasHashes) { batch.PositionHashes = new ulong[count]; } if (hasMoves) { batch.Moves = new MGMoveList[count]; } for (int i = 0; i < count; i++) { if (hasPositions) { batch.Positions[i] = MGChessPositionConverter.MGChessPositionFromFEN(fen); } if (hasHashes) { batch.PositionHashes[i] = (ulong)i + (ulong)batch.Positions[i].GetHashCode(); } if (hasMoves) { MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in mgPos, moves); batch.Moves[i] = moves; } } } return(batch); }
public string GetBoardPicture(bool weAreWhite) { string fen = ""; for (int r = 7; r >= 0; r--) { fen = fen + EncodedPositionWithHistory.GetRowString(r * 8, this, weAreWhite) + "\r\n"; } fen += "Reps = " + Repetitions.Data + "\r\n"; return(fen); }
/// <summary> /// Sets the Batch field with set of positions coming from a specified Span<MCTSNode>. /// </summary> /// <param name="context"></param> /// <param name="nodes"></param> /// <returns></returns> int SetBatch(MCTSIterator context, Span <MCTSNode> nodes) { //Console.WriteLine(nodes.Length + " BATCH NODES"); if (nodes.Length > NNEvaluatorDef.MAX_BATCH_SIZE) { throw new Exception($"Requested batch is larger than {NNEvaluatorDef.MAX_BATCH_SIZE}"); } if (nodes.Length > 0) { for (int i = 0; i < nodes.Length; i++) { if (EvaluatorDef.PositionTransform == NNEvaluatorDef.PositionTransformType.Mirror) { if (rawPosArray[i].MiscInfo.InfoPosition.MirrorEquivalent) { EncodedPositionWithHistory mirrored = rawPosArray[i].Mirrored; nodes[i].Annotation.CalcRawPosition(nodes[i], ref mirrored); } } else { nodes[i].Annotation.CalcRawPosition(nodes[i], ref rawPosArray[i]); } } if (EvaluatorDef.Location == NNEvaluatorDef.LocationType.Local) { Batch.Set(rawPosArray, nodes.Length); } if (BatchEvaluatorIndexDynamicSelector != null) { Batch.PreferredEvaluatorIndex = (short)BatchEvaluatorIndexDynamicSelector(context); } } return(nodes.Length); }
public string GetFEN(bool weAreWhite) { string fen = ""; for (int r = 7; r >= 0; r--) { if (r != 7) { fen += "/"; } int numBlank = 0; int startIndex = r * 8; for (int c = 7; c >= 0; c--) { string thisChar = EncodedPositionWithHistory.FENCharAt(this, startIndex + (7 - c), weAreWhite, " "); if (thisChar == " ") { numBlank++; } else { if (numBlank > 0) { fen += numBlank; } numBlank = 0; fen += thisChar; } } if (numBlank > 0) { fen += numBlank; } } return(fen); }
/// <summary> /// Initializes a specified EncodedPosition to reflect the a specified node's position. /// </summary> /// <param name="node"></param> /// <param name="boardsHistory"></param> internal unsafe void CalcRawPosition(MCTSNode node, ref EncodedPositionWithHistory boardsHistory) { Span <EncodedPositionBoard> destBoards = new Span <EncodedPositionBoard>(Unsafe.AsPointer(ref boardsHistory), EncodedPositionBoards.NUM_MOVES_HISTORY); // Now we fill in the history boards, extracted from up to 4 distinct places: // 1. the current node's board (always) // 2. possibly sequence of boards by ascending tree toward root // 3. possibly sequence of boards coming from the prior history that // this search was launched with (nodes before the root) // 4. possibly one or more fill-in boards, which can be // either zero (if history fill-in feature turned off) // otherwise the last actual board in the history repeated destBoards[0] = LC0BoardPosition; MCTSNode priorNode = node.Parent; // Ascend in tree copying positions from ancestors int nextBoardIndex = 1; while (nextBoardIndex < EncodedPositionBoards.NUM_MOVES_HISTORY && priorNode != null) { if (nextBoardIndex % 2 == 1) { destBoards[nextBoardIndex++] = priorNode.Annotation.LC0BoardPosition.ReversedAndFlipped; } else { destBoards[nextBoardIndex++] = priorNode.Annotation.LC0BoardPosition; } priorNode = priorNode.Parent; } // Boards from prior history int priorPositionsIndex = 0; while (nextBoardIndex < EncodedPositionBoards.NUM_MOVES_HISTORY && priorPositionsIndex < node.Tree.EncodedPriorPositions.Count) { if (nextBoardIndex % 2 == 1) { destBoards[nextBoardIndex++] = node.Tree.EncodedPriorPositions[priorPositionsIndex].ReversedAndFlipped; } else { destBoards[nextBoardIndex++] = node.Tree.EncodedPriorPositions[priorPositionsIndex]; } priorPositionsIndex++; } // Finally, set last boards either with repeated last position (if fill in) or zeros int indexBoardToRepeat = nextBoardIndex - 1; bool historyFillIn = node.Context.ParamsSearch.HistoryFillIn; while (nextBoardIndex < EncodedPositionBoards.NUM_MOVES_HISTORY) { if (historyFillIn) { destBoards[nextBoardIndex++] = destBoards[indexBoardToRepeat]; } else { destBoards[nextBoardIndex++] = default; } } boardsHistory.SetMiscInfo(new EncodedTrainingPositionMiscInfo(MiscInfo, default)); }