public void AppendMove(string moveStr) { MGPosition mgPos = MGPosition.FromPosition(FinalPosition); MGMove thisMove = MGMoveFromString.ParseMove(mgPos, moveStr); if (thisMove.IsNull) { throw new Exception("Unexpected null move"); } // Verify move is legal from this position MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in mgPos, moves); if (Array.IndexOf(moves.MovesArray, thisMove) == -1) { throw new Exception($"The move {moveStr} is not legal from position {FinalPosition.FEN}"); } Moves.Add(MGMoveFromString.ParseMove(mgPos, moveStr)); if (haveFinalized) { InitPositionsAndFinalPosMG(); } }
/// <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 static MGMove ToMGMove(MGPosition mgPos, EncodedMove encodedMove) { MGMoveList movesLegal = new MGMoveList(); MGMoveGen.GenerateMoves(in mgPos, movesLegal); int indexLegalMove = MoveInMGMovesArrayLocator.FindMoveInMGMoves(in mgPos, movesLegal.MovesArray, encodedMove, 0, movesLegal.NumMovesUsed, mgPos.BlackToMove); if (indexLegalMove == -1) { throw new Exception($"Move not found {encodedMove}"); } return(movesLegal.MovesArray[indexLegalMove]); // Move move = MGMoveConverter.ToMove(theMove); }
/// <summary> /// Returns the MGMove corresponding to a given Move. /// </summary> /// <param name="pos"></param> /// <param name="move"></param> /// <returns></returns> public static MGMove MGMoveFromPosAndMove(Position pos, Move move) { PositionWithMove moveAndPos = new PositionWithMove(pos, move); MGPosition mgPos = MGPosition.FromPosition(in moveAndPos.Position); MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in mgPos, moves); for (int i = 0; i < moves.NumMovesUsed; i++) { if (moves.MovesArray[i].EqualsMove(move)) { return(moves.MovesArray[i]); } } throw new Exception("Move not found"); }
/// <summary> /// Generates the set of moves and positions possible as the next move in a position. /// </summary> /// <param name="startPos"></param> /// <param name="moveToIncludeFilter"></param> /// <returns></returns> public static IEnumerable <(MGMove, Position)> GenPositions(Position startPos, Predicate <MGMove> moveToIncludeFilter = null) { MGPosition posMG = MGChessPositionConverter.MGChessPositionFromFEN(startPos.FEN); // TODO: more efficient? MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in posMG, moves); for (int i = 0; i < moves.NumMovesUsed; i++) { // Only consider captures (would reduce number of pieces into range of tablebase) if (moveToIncludeFilter == null || moveToIncludeFilter(moves.MovesArray[i])) { // Make this move and get new Position MGPosition newPosMG = new MGPosition(posMG); newPosMG.MakeMove(moves.MovesArray[i]); Position newPos = MGChessPositionConverter.PositionFromMGChessPosition(in newPosMG); yield return(moves.MovesArray[i], newPos); } } }
public IEncodedPositionBatchFlat GetSubBatchCopied(int startIndex, int count) { float[] w = null; float[] l = null; if (W != null) { w = new float[count]; Array.Copy(W, startIndex, w, 0, count); } if (L != null) { l = new float[count]; Array.Copy(L, startIndex, l, 0, count); } byte[] posPlaneValuesEncoded = new byte[count * EncodedPositionWithHistory.NUM_PLANES_TOTAL]; Array.Copy(PosPlaneValues, startIndex * EncodedPositionWithHistory.NUM_PLANES_TOTAL, posPlaneValuesEncoded, 0, count * EncodedPositionWithHistory.NUM_PLANES_TOTAL); ulong[] posPlaneBitmaps = new ulong[count * EncodedPositionWithHistory.NUM_PLANES_TOTAL]; Array.Copy(PosPlaneBitmaps, startIndex * EncodedPositionWithHistory.NUM_PLANES_TOTAL, posPlaneBitmaps, 0, count * EncodedPositionWithHistory.NUM_PLANES_TOTAL); EncodedPositionBatchFlat ret = new EncodedPositionBatchFlat(posPlaneBitmaps, posPlaneValuesEncoded, w, l, null, count); if (Positions != null) { ulong[] hashes = new ulong[count]; MGPosition[] positionsMG = new MGPosition[count]; MGMoveList[] moves = new MGMoveList[count]; Array.Copy(PositionHashes, startIndex, hashes, 0, count); Array.Copy(Positions, startIndex, positionsMG, 0, count); Array.Copy(Moves, startIndex, moves, 0, count); ret.PositionHashes = hashes; ret.Positions = positionsMG; ret.Moves = moves; } return(ret); }