private void Update() { PossibleCells = _gamePreset.OCellSprites .Select(x => new KeyValuePair <ImageContainer, CellType>(new ImageContainer(x), CellType.OCell)) .Union(_gamePreset.XCellSprites .Select(x => new KeyValuePair <ImageContainer, CellType>(new ImageContainer(x), CellType.XCell))) .Union(_gamePreset.FreeCellSprites .Select(x => new KeyValuePair <ImageContainer, CellType>(new ImageContainer(x), CellType.Free))) .ToList(); TurnImage = new ImageContainer(_gamePreset.TurnSprite); StartImage = new ImageContainer(_gamePreset.StartSprite); OnGameStateUpdated?.Invoke(); }
private bool UpdateBoard(ImageContainer screen) { bool isBoardUpdated = false; if (Board.GetLength(0) != _gamePreset.Rows || Board.GetLength(1) != _gamePreset.Columns) { Board = new CellType[_gamePreset.Rows, _gamePreset.Columns]; } for (int row = 0; row < _gamePreset.Rows; row++) { for (int column = 0; column < _gamePreset.Columns; column++) { var cell = UpdateCellType(row, column, screen); isBoardUpdated |= SetBoardCell(cell); } } return(isBoardUpdated); }
private Cell UpdateCellType(int row, int column, ImageContainer screen) { var horCellDistance = (_gamePreset.LastCell.X - _gamePreset.FirstCell.X) / (_gamePreset.Columns - 1); var verCellDistance = (_gamePreset.LastCell.Y - _gamePreset.FirstCell.Y) / (_gamePreset.Rows - 1); var x = _gamePreset.FirstCell.X + horCellDistance * column; var y = _gamePreset.FirstCell.Y + verCellDistance * row; var width = _gamePreset.FirstCell.Width; var height = _gamePreset.FirstCell.Height; var cell = new Cell(CellType.Unknown, row, column, x, y, height, width); if (width == 0 || height == 0) { return(cell); } var cellCenterX = cell.X + cell.Width / 2; var cellCenterY = cell.Y + cell.Height / 2; int?minDiff = null; foreach (var possibleCell in PossibleCells) { var image = possibleCell.Key; x = cellCenterX - image.Width / 2; y = cellCenterY - image.Height / 2; width = image.Width - 1; height = image.Height - 1; var diff = screen.Difference(ref image, x, y, x + width, y + height, new Size(width, height), AnalysisAccuracy); if (minDiff == null || minDiff.Value > diff) { cell.X = x; cell.Y = y; cell.Width = possibleCell.Key.Width; cell.Height = possibleCell.Key.Height; cell.CellType = diff <= Dispersion ? possibleCell.Value : CellType.Unknown; minDiff = diff; } } return(cell); }
/// <summary> /// Поиск изображения. /// </summary> /// <param name="fbmp">Искомое изображение.</param> /// <param name="deep">Точность анализа.</param> /// <param name="fault">Величина погрешности.</param> /// <returns></returns> public Point Find(ImageContainer fbmp, int deep, int fault) { Point pos = new Point(); int fbmph = fbmp.Height, fbmpw = fbmp.Width; int mindef = fault + 1; // поиск области с нужной суммой for (int y = fbmph + 1; y < _bmph; y++) { for (var x = fbmpw + 1; x < _bmpw; x++) { var bdef = Difference(ref fbmp, x - fbmpw, y - fbmph, x, y, new Size(fbmpw, fbmph), deep); if (bdef < mindef) { pos.X = x; pos.Y = y; mindef = bdef; } } } return(pos); }
/// <summary> /// Сравнение на идентичность эталонного изображения и участка из скриншота. /// </summary> /// <param name="frgbS">Искомое изображение.</param> /// <param name="x0">Координата X верхнего левого угла сравниваемой области.</param> /// <param name="y0">Координата Y верхнего левого угла сравниваемой области.</param> /// <param name="x1">Координата X нижнего правого угла сравниваемой области.</param> /// <param name="y1">Координата Y нижнего правого угла сравниваемой области.</param> /// <param name="size">Размер искомого изображения.</param> /// <param name="deep">Глубина сравнения (точность)</param> /// <returns></returns> public int Difference(ref ImageContainer frgbS, int x0, int y0, int x1, int y1, Size size, int deep) { bool hor; if (x1 >= Width || y1 >= Height) { return(int.MaxValue); } if (deep == 0) // если достигнута максимальная глубина рекурсии - начать подъем { return(Math.Abs(RSumm(x1 - size.Width + 1, y1 - size.Height + 1, x1, y1) - frgbS.RSumm(x1 - x0 - size.Width, y1 - y0 - size.Height, x1 - x0 - 1, y1 - y0 - 1))); } if (size.Height > size.Width) { hor = true; size.Height /= 2; } else { hor = false; size.Width /= 2; } int res = Difference(ref frgbS, x0, y0, x1, y1, size, deep - 1); if (hor) // получениe координат второй половины { y1 -= size.Height; } else { x1 -= size.Width; } res += Difference(ref frgbS, x0, y0, x1, y1, size, deep - 1); return(res); }