//задает соседа для данной ячейки, position - положение cell относительно данной ячейки //0 - она сверху данной ячейки, 4 - снизу, 6 - слева и т.д. public void setNeighbour(SaperCell cell, int position) { neighbours[position] = cell; if (cell.value == 9) numberOf9TypeNeighbours++; if (cell.value == -1) numberOfFlags++; }
//задает соседа для данной ячейки, position - положение cell относительно данной ячейки //0 - она сверху данной ячейки, 4 - снизу, 6 - слева и т.д. public void setNeighbour(SaperCell cell, int position) { neighbours[position] = cell; if (cell.value == 9) { numberOf9TypeNeighbours++; } if (cell.value == -1) { numberOfFlags++; } }
//находит соседей для данной ячейки public void FindNeighboursOfCell(SaperCell cell) { cell.numberOf9TypeNeighbours = 0; cell.numberOfFlags = 0; //если сверху есть сосед, то добавляем его if (cell.Y > 0) { cell.setNeighbour(saperField[cell.Y - 1, cell.X], 0); } //если сверху справа есть сосед, то добавляем его if (cell.Y > 0 && cell.X < 29) { cell.setNeighbour(saperField[cell.Y - 1, cell.X + 1], 1); } //если справа есть сосед, то добавляем его if (cell.X < 29) { cell.setNeighbour(saperField[cell.Y, cell.X + 1], 2); } //если справа снизу есть сосед, то добавляем его if (cell.Y < 15 && cell.X < 29) { cell.setNeighbour(saperField[cell.Y + 1, cell.X + 1], 3); } //если снизу есть сосед, то добавляем его if (cell.Y < 15) { cell.setNeighbour(saperField[cell.Y + 1, cell.X], 4); } //если снизу слева есть сосед, то добавляем его if (cell.Y < 15 && cell.X > 0) { cell.setNeighbour(saperField[cell.Y + 1, cell.X - 1], 5); } //если слева есть сосед, то добавляем его if (cell.X > 0) { cell.setNeighbour(saperField[cell.Y, cell.X - 1], 6); } //если сверху слева есть сосед, то добавляем его if (cell.Y > 0 && cell.X > 0) { cell.setNeighbour(saperField[cell.Y - 1, cell.X - 1], 7); } }
public SaperCell[] get9TypeNeighbours() { SaperCell[] notOpenedCells = new SaperCell[numberOf9TypeNeighbours]; int counter = 0; for (int i = 0; i < 8; ++i) { if (neighbours[i] != null && neighbours[i].value == 9) { notOpenedCells[counter++] = neighbours[i]; } } return notOpenedCells; }
public SaperCell[] get9TypeNeighbours() { SaperCell[] notOpenedCells = new SaperCell[numberOf9TypeNeighbours]; int counter = 0; for (int i = 0; i < 8; ++i) { if (neighbours[i] != null && neighbours[i].value == 9) { notOpenedCells[counter++] = neighbours[i]; } } return(notOpenedCells); }
public static bool IfAnyChanges(SaperCell[,] table, Rectangle rect, int y, int x) { //получает текущую диспозицию, исходя из окна var gameBmp = Form1.GetScreenImage(rect); Image<Bgr, Byte> img = new Image<Bgr, byte>(gameBmp); InitiateCellsWin7(); var cell = img.GetSubRect(new Rectangle(FIRST_WINDOW_X7 + x * (WINDOW_WIDTH7 + WINDOW_DIST7), FIRST_WINDOW_Y7 + y * (WINDOW_WIDTH7 + WINDOW_DIST7), WINDOW_WIDTH7, WINDOW_HEIGHT7)); int value = CellRecognitionWin7(cell); if (table[y, x].value != value) return true; return false; }
//получить массив из неоткрытых ячеек public SaperCell[] GetNotOpened() { SaperCell[] notOpened = new SaperCell[numberOfNotOpened]; int counter = 0; for (int i = 0; i < 16; ++i) { for (int j = 0; j < 30; ++j) { if (saperField[i, j].value == 9) { notOpened[counter++] = saperField[i, j]; } } } return(notOpened); }
//конструктор создает из числовой таблицы таблицу с соответствующими элементами класса SaperCell public SaperFieldOfCells(int[,] fieldOfNumbers) { saperField = new SaperCell[16, 30]; for (int i = 0; i < 16; ++i) for (int j = 0; j < 30; ++j) { saperField[i, j] = new SaperCell(fieldOfNumbers[i, j], j, i); if (fieldOfNumbers[i, j] == 9) { numberOfNotOpened++; } if (fieldOfNumbers[i, j] == -1) { numberOfMines--; } } SetNeighboursForAllCells(); }
//конструктор создает из числовой таблицы таблицу с соответствующими элементами класса SaperCell public SaperFieldOfCells(int[,] fieldOfNumbers) { saperField = new SaperCell[16, 30]; for (int i = 0; i < 16; ++i) { for (int j = 0; j < 30; ++j) { saperField[i, j] = new SaperCell(fieldOfNumbers[i, j], j, i); if (fieldOfNumbers[i, j] == 9) { numberOfNotOpened++; } if (fieldOfNumbers[i, j] == -1) { numberOfMines--; } } } SetNeighboursForAllCells(); }
//по неизвестным причинам при первом нажатии правой кнопки мыши, метод RightClick //неправильно срабатывает, для этого вставлен данный костыль public void FirstTimeRightClick(int y, int x, SaperCell[,] field) { mouse_event((int)(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); mouse_event((int)(MouseEventFlags.RIGHTDOWN), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); mouse_event((int)(MouseEventFlags.RIGHTDOWN), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); System.Threading.Thread.Sleep(10 * (Form1.mouseSpeed + SPEED_ADDER)); mouse_event((int)(MouseEventFlags.RIGHTUP), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); }
public void RightClick(int y, int x, SaperCell[,] field) { mouse_event((int)(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); mouse_event((int)(MouseEventFlags.RIGHTDOWN), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); System.Threading.Thread.Sleep(10 * (Form1.mouseSpeed + SPEED_ADDER)); mouse_event((int)(MouseEventFlags.RIGHTUP), (leftSideOfSaperWindow + FIRST_WINDOW_X + x * (WINDOW_WIDTH + WINDOW_DIST) + WINDOW_WIDTH / 2) * 65536 / SCREEN_WIDTH, (topSideOfSaperWindow + FIRST_WINDOW_Y + y * (WINDOW_HEIGHT + WINDOW_DIST) + WINDOW_HEIGHT / 2) * 65536 / SCREEN_HEIGHT, 0, 0); if (Form1.version == Form1.SAPER_TYPE.XP) { if (SaperImageDetection.IfAnyChanges(field, rect, y, x) == false) { FirstTimeRightClick(y, x, field); } } if (Form1.version == Form1.SAPER_TYPE.Seven) { if (SaperImageDetectionWindows7.IfAnyChanges(field, rect, y, x) == false) { FirstTimeRightClick(y, x, field); } } }
//метод проверяет, входят ли все неоткрытые соседи данной клетки в массив private bool IfCommonNotOpenedNeighbours(int y, int x, SaperCell[] otherNeighbours) { SaperCell[,] saperField = field.GetSaperField(); foreach (var cell in saperField[y, x].get9TypeNeighbours()) { if (otherNeighbours.Contains(cell) == false) return false; } return true; }
//метод пересчитывает соседей для всех соседних клеток данной ячейки, он необходим //для внесения изменений в соседние ячейки, после установки флага о мине private void CalculateNeighboursForAllNeighboursOfThisCell(SaperCell cell) { foreach (var neighbour in cell.getNeighbours()) { if (neighbour != null) { field.FindNeighboursOfCell(neighbour); } } }
//получить массив из неоткрытых ячеек public SaperCell[] GetNotOpened() { SaperCell[] notOpened = new SaperCell[numberOfNotOpened]; int counter = 0; for (int i = 0; i < 16; ++i) for (int j = 0; j < 30; ++j) { if (saperField[i, j].value == 9) { notOpened[counter++] = saperField[i, j]; } } return notOpened; }