public Image <Bgr, byte> ConstructBoardImage(BoardView board, Color backgroundColor = (Color)(-1)) { Image <Bgr, byte> image = new Image <Bgr, byte>(boardSize); for (int y = 0; y < Board.height; y++) { for (int x = 0; x < Board.width; x++) { int bc = backgroundColor == (Color)(-1) ? (x + y) % 2 : (int)backgroundColor; Point start = new Point(x * fieldSize.Width, y * fieldSize.Height); image.ROI = new Rectangle(start, fieldSize); Piece piece = board.board.At(new Point(x, y)); if (piece == null) { templateFields[bc].CopyTo(image); } else { templatePieces[bc, (int)piece.color, (int)piece.type].CopyTo(image); } } } image.ROI = Rectangle.Empty; return(image); }
public bool RecognizeBoard(Image <Bgr, byte> boardImage, out BoardView board) { board = new BoardView(); int allowedMistakes = 4; for (int y = 0; y < Board.height && allowedMistakes >= 0; y++) { for (int x = 0; x < Board.width && allowedMistakes >= 0; x++) { int bc = (x + y) % 2; Point start = new Point(x * fieldSize.Width, y * fieldSize.Height); boardImage.ROI = new Rectangle(start, fieldSize); templateFields[bc].ROI = clippedROI; Image <Gray, float> fieldMatch = boardImage.MatchTemplate(templateFields[bc], TemplateMatchingType.SqdiffNormed); templateFields[bc].ROI = Rectangle.Empty; fieldMatch.MinMax(out double[] fieldScores, out _, out _, out _); double fieldScore = fieldScores[0]; double bestPieceScore = double.MaxValue; int bestPC = 0, bestP = 0; for (int pc = 0; pc < (int)Color.Length; pc++) { for (int p = 0; p < (int)Type.Length; p++) { templatePieces[bc, pc, p].ROI = clippedROI; Image <Gray, float> pieceMatch = boardImage.MatchTemplate(templatePieces[bc, pc, p], TemplateMatchingType.SqdiffNormed); templatePieces[bc, pc, p].ROI = Rectangle.Empty; pieceMatch.MinMax(out double[] pieceScores, out _, out _, out _); double pieceScore = pieceScores[0]; if (pieceScore < bestPieceScore) { bestPieceScore = pieceScore; bestPC = pc; bestP = p; } } } if (fieldScore > 0.1 && bestPieceScore > 0.1) { allowedMistakes--; if (fieldScore > 0.2 && bestPieceScore > 0.2) { allowedMistakes = -1; } } if (bestPieceScore < fieldScore) { Point pos = new Point(x, y); board.AddPiece(new Piece(pos, (Type)bestP, (Color)bestPC)); } } } boardImage.ROI = Rectangle.Empty; return(allowedMistakes >= 0); }
public Board(BoardView boardView) { int[] piecesTop = new int[(int)Color.Length]; int[] piecesBottom = new int[(int)Color.Length]; foreach (Piece piece in boardView.board) { if (piece != null) { if (piece.pos.Y < height / 2) { piecesTop[(int)piece.color]++; } else { piecesBottom[(int)piece.color]++; } } } int whiteAtBottomVotes = piecesTop[(int)Color.Black] + piecesBottom[(int)Color.White]; int blackAtBottomVotes = piecesTop[(int)Color.White] + piecesBottom[(int)Color.Black]; score = boardView.score; if (whiteAtBottomVotes >= blackAtBottomVotes) { board = boardView.board; nextPlayer = Color.White; rotated = false; } else { board = boardView.Rotate180().board; nextPlayer = Color.Black; rotated = true; } if (FenLayout.Equals(initLayout)) { nextPlayer = Color.White; } repeatedFens.AddOrUpdate(FenPositionNoClocks, 1, (_, count) => count + 1); }
public bool Update(BoardView boardView, int maxMoves) { if (rotated ? Equals(boardView.Rotate180()) : Equals(boardView)) { return(true); } else if (maxMoves > 0) { maxMoves--; List <Move> moves = GetMovesInaccurate(); foreach (Move move in moves) { MakeMove(move); string fen = FenPositionNoClocks; if (Update(boardView, maxMoves)) { repeatedFens.AddOrUpdate(fen, 1, (_, count) => count + 1); return(true); } UndoMove(move); } } return(false); }