Change encoding

This commit is contained in:
Victor Melnik 2012-01-11 16:55:25 +02:00
parent 59fdc4a3c0
commit b2473cdc2e
4 changed files with 137 additions and 137 deletions

View File

@ -3,19 +3,19 @@ package main;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
* Класс логики бота. * Класс логики бота.
* @author aNNiMON * @author aNNiMON
*/ */
public class BotFloodIt { public class BotFloodIt {
/* Количество цветов в игре */ /* Количество цветов в игре */
private static final int MAX_COLORS = 6; private static final int MAX_COLORS = 6;
/* На сколько шагов вперёд просчитывать ход */ /* На сколько шагов вперёд просчитывать ход */
private static final int FILL_STEPS = 4; private static final int FILL_STEPS = 4;
/* Игровое поле */ /* Игровое поле */
private byte[][] table; private byte[][] table;
/* Цвета, соответствующие ID */ /* Цвета, соответствующие ID */
private int[] colors; private int[] colors;
public BotFloodIt(int[][] table) { public BotFloodIt(int[][] table) {
@ -27,16 +27,16 @@ public class BotFloodIt {
} }
/** /**
* Получить цвета клеток в палитре * Получить цвета клеток в палитре
* @return массив цветов RGB * @return массив цветов RGB
*/ */
public int[] getColors() { public int[] getColors() {
return colors; return colors;
} }
/** /**
* Получить последовательность заливки цветов * Получить последовательность заливки цветов
* @return массив с идентификаторами цветов для заливки * @return массив с идентификаторами цветов для заливки
*/ */
public byte[] getFillSequence() { public byte[] getFillSequence() {
byte[][] copyTable = copyTable(table); byte[][] copyTable = copyTable(table);
@ -52,28 +52,28 @@ public class BotFloodIt {
} }
/* /*
* Получить индекс следующего цвета для заливки * Получить индекс следующего цвета для заливки
*/ */
private byte getNextFillColor(byte[][] table) { private byte getNextFillColor(byte[][] table) {
// Количество вариантов заливок // Количество вариантов заливок
int fillSize = (int) Math.pow(MAX_COLORS, FILL_STEPS); int fillSize = (int) Math.pow(MAX_COLORS, FILL_STEPS);
int[] fillRate = new int[fillSize]; int[] fillRate = new int[fillSize];
// Заполняем значениями степени заливки // Заполняем значениями степени заливки
int[] fillPow = new int[FILL_STEPS]; int[] fillPow = new int[FILL_STEPS];
for (int i = 0; i < FILL_STEPS; i++) { for (int i = 0; i < FILL_STEPS; i++) {
fillPow[i] = (int) Math.pow(MAX_COLORS, i); fillPow[i] = (int) Math.pow(MAX_COLORS, i);
} }
// Заливаем FILL_STEPS раз MAX_COLORS вариантов // Заливаем FILL_STEPS раз MAX_COLORS вариантов
for (int i = 0; i < fillSize; i++) { for (int i = 0; i < fillSize; i++) {
byte[][] iteration = copyTable(table); byte[][] iteration = copyTable(table);
for (int j = 0; j < FILL_STEPS; j++) { for (int j = 0; j < FILL_STEPS; j++) {
byte fillColor = (byte) (i / fillPow[j] % MAX_COLORS); byte fillColor = (byte) (i / fillPow[j] % MAX_COLORS);
fillTable(iteration, fillColor); fillTable(iteration, fillColor);
} }
// Подсчитываем число залитых ячеек // Подсчитываем число залитых ячеек
fillRate[i] = getFillCount(iteration); fillRate[i] = getFillCount(iteration);
} }
// Теперь ищем максимально залитый участок из FILL_STEPS итераций заливки // Теперь ищем максимально залитый участок из FILL_STEPS итераций заливки
int maxArea = fillRate[0]; int maxArea = fillRate[0];
int maxColor = 0; int maxColor = 0;
for (int i = 1; i < fillSize; i++) { for (int i = 1; i < fillSize; i++) {
@ -82,30 +82,30 @@ public class BotFloodIt {
maxArea = fillRate[i]; maxArea = fillRate[i];
} }
} }
// Получаем цвет с наибольшей площадью дальнейшей заливки // Получаем цвет с наибольшей площадью дальнейшей заливки
byte colorID = (byte) (maxColor % MAX_COLORS); byte colorID = (byte) (maxColor % MAX_COLORS);
fillTable(table, colorID); fillTable(table, colorID);
return colorID; return colorID;
} }
/* /*
* Преобразование массива с цветами в массив с идентификаторами * Преобразование массива с цветами в массив с идентификаторами
*/ */
private byte[][] colorsToIds(int[][] tableColor) { private byte[][] colorsToIds(int[][] tableColor) {
int size = tableColor.length; int size = tableColor.length;
byte[][] out = new byte[size][size]; byte[][] out = new byte[size][size];
int colorsReaded = 1; // сколько цветов распознано int colorsReaded = 1; // сколько цветов распознано
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
int color = tableColor[i][j]; int color = tableColor[i][j];
for (byte k = 0; k < colorsReaded; k++) { for (byte k = 0; k < colorsReaded; k++) {
// Добавляем цвет в палитру // Добавляем цвет в палитру
if (colors[k] == -1) { if (colors[k] == -1) {
colors[k] = color; colors[k] = color;
colorsReaded++; colorsReaded++;
if (colorsReaded > MAX_COLORS) colorsReaded = MAX_COLORS; if (colorsReaded > MAX_COLORS) colorsReaded = MAX_COLORS;
} }
// Если цвет уже в палитре, то присваиваем ему ID // Если цвет уже в палитре, то присваиваем ему ID
if (color == colors[k]) { if (color == colors[k]) {
out[i][j] = k; out[i][j] = k;
break; break;
@ -117,9 +117,9 @@ public class BotFloodIt {
} }
/** /**
* Залить заданное поле цветом color * Залить заданное поле цветом color
* @param table игровое поле для заливки * @param table игровое поле для заливки
* @param color цвет заливки * @param color цвет заливки
*/ */
private void fillTable(byte[][] table, byte color) { private void fillTable(byte[][] table, byte color) {
if (table[0][0] == color) return; if (table[0][0] == color) return;
@ -127,14 +127,14 @@ public class BotFloodIt {
} }
/* /*
* Заливка поля по координатам * Заливка поля по координатам
*/ */
private void fill(byte[][] table, int x, int y, byte prevColor, byte color) { private void fill(byte[][] table, int x, int y, byte prevColor, byte color) {
// Проверка на выход за границы игрового поля // Проверка на выход за границы игрового поля
if ( (x < 0) || (y < 0) || (x >= table.length) || (y >= table.length) ) return; if ( (x < 0) || (y < 0) || (x >= table.length) || (y >= table.length) ) return;
if (table[x][y] == prevColor) { if (table[x][y] == prevColor) {
table[x][y] = color; table[x][y] = color;
// Заливаем смежные области // Заливаем смежные области
fill(table, x-1, y, prevColor, color); fill(table, x-1, y, prevColor, color);
fill(table, x+1, y, prevColor, color); fill(table, x+1, y, prevColor, color);
fill(table, x, y-1, prevColor, color); fill(table, x, y-1, prevColor, color);
@ -143,24 +143,24 @@ public class BotFloodIt {
} }
/** /**
* Получить количество залитых ячеек * Получить количество залитых ячеек
* @param table игровое поле * @param table игровое поле
*/ */
private int getFillCount(byte[][] table) { private int getFillCount(byte[][] table) {
return getCount(table, 0, 0, table[0][0]); return getCount(table, 0, 0, table[0][0]);
} }
/* /*
* Подсчет залитых ячеек по координатам * Подсчет залитых ячеек по координатам
*/ */
private int getCount(byte[][] table, int x, int y, byte color) { private int getCount(byte[][] table, int x, int y, byte color) {
// Проверка на выход за границы игрового поля // Проверка на выход за границы игрового поля
if ( (x < 0) || (y < 0) || (x >= table.length) || (y >= table.length) ) return 0; if ( (x < 0) || (y < 0) || (x >= table.length) || (y >= table.length) ) return 0;
int count = 0; int count = 0;
if (table[x][y] == color) { if (table[x][y] == color) {
table[x][y] = -1; table[x][y] = -1;
count = 1; count = 1;
// Считаем смежные ячейки // Считаем смежные ячейки
count += getCount(table, x-1, y, color); count += getCount(table, x-1, y, color);
count += getCount(table, x+1, y, color); count += getCount(table, x+1, y, color);
count += getCount(table, x, y-1, color); count += getCount(table, x, y-1, color);
@ -170,7 +170,7 @@ public class BotFloodIt {
} }
/* /*
* Проверка, залита ли вся область одним цветом * Проверка, залита ли вся область одним цветом
*/ */
private boolean gameCompleted(byte[][] table) { private boolean gameCompleted(byte[][] table) {
byte color = table[0][0]; byte color = table[0][0];
@ -184,7 +184,7 @@ public class BotFloodIt {
} }
/* /*
* Копирование массива игрового поля * Копирование массива игрового поля
*/ */
private byte[][] copyTable(byte[][] table) { private byte[][] copyTable(byte[][] table) {
int size = table.length; int size = table.length;

View File

@ -5,32 +5,32 @@ import java.awt.image.BufferedImage;
import java.util.Random; import java.util.Random;
/** /**
* Класс обработки изображений. * Класс обработки изображений
* @author aNNiMON * @author aNNiMON
*/ */
public class ImageUtils { public class ImageUtils {
/* За сколько точек мы будем узнавать преобладающий фон */ /* За сколько точек мы будем узнавать преобладающий фон */
private static final int MAX_COLOR_POINTS = 50; private static final int MAX_COLOR_POINTS = 50;
/* Чувствительность к поиску кнопок */ /* Чувствительность к поиску кнопок */
private static final int FIND_BUTTON_TOLERANCE = 20; private static final int FIND_BUTTON_TOLERANCE = 20;
/* Изображение окна */ /* Изображение окна */
private BufferedImage image; private BufferedImage image;
/* Размер изображения */ /* Размер изображения */
private int w, h; private int w, h;
/* Размерность поля */ /* Размерность поля */
private int boardSize; private int boardSize;
/* Размер ячеек */ /* Размер ячеек */
private int cellSize; private int cellSize;
/* Координата угла игрового поля */ /* Координата угла игрового поля */
private Point board; private Point board;
/* Монохромное представление изображения */ /* Монохромное представление изображения */
private boolean[] monochrome; private boolean[] monochrome;
/** /**
* Конструктор для определения настроек * Конструктор для определения настроек
* @param image * @param image
* @param boardSize * @param boardSize
*/ */
@ -42,7 +42,7 @@ public class ImageUtils {
} }
/** /**
* Конструктор для проверки настроек * Конструктор для проверки настроек
* @param image * @param image
* @param boardSize * @param boardSize
* @param cellSize * @param cellSize
@ -59,7 +59,7 @@ public class ImageUtils {
} }
/** /**
* Получить размер ячейки * Получить размер ячейки
* @return * @return
*/ */
public int getCellSize() { public int getCellSize() {
@ -67,8 +67,8 @@ public class ImageUtils {
} }
/** /**
* Получить координаты игрового поля * Получить координаты игрового поля
* @return точка с координатами левого верхнего угла поля * @return точка с координатами левого верхнего угла поля
*/ */
public Point getBoardParameters() { public Point getBoardParameters() {
int[] pixels = new int[w * h]; int[] pixels = new int[w * h];
@ -79,8 +79,8 @@ public class ImageUtils {
} }
/** /**
* Получить изображение игрового поля * Получить изображение игрового поля
* @return картинка игрового поля * @return картинка игрового поля
*/ */
public BufferedImage getBoardImage() { public BufferedImage getBoardImage() {
int size = cellSize * boardSize; int size = cellSize * boardSize;
@ -92,34 +92,34 @@ public class ImageUtils {
} }
/** /**
* Получить координаты кнопок для автоматического нажатия * Получить координаты кнопок для автоматического нажатия
* @param colors массив цветов, по которым будем искать кнопки * @param colors массив цветов, по которым будем искать кнопки
* @return массив координат с точками, или null - если не удалось найти * @return массив координат с точками, или null - если не удалось найти
*/ */
public Point[] getButtons(int[] colors) { public Point[] getButtons(int[] colors) {
Point[] out = new Point[colors.length]; Point[] out = new Point[colors.length];
// Размер игрового поля в пикселах // Размер игрового поля в пикселах
int size = boardSize * cellSize; int size = boardSize * cellSize;
// Размеры частей изображения, на которых будем искать кнопки // Размеры частей изображения, на которых будем искать кнопки
Rectangle[] partsOfImage = new Rectangle[] { Rectangle[] partsOfImage = new Rectangle[] {
new Rectangle(0, board.y, board.x, size), // слева от поля new Rectangle(0, board.y, board.x, size), // слева от поля
new Rectangle(0, 0, w, board.y), // сверху от поля new Rectangle(0, 0, w, board.y), // сверху от поля
new Rectangle(board.x+size, board.y, new Rectangle(board.x+size, board.y,
w-board.x-size, size), // справа от поля w-board.x-size, size), // справа от поля
new Rectangle(0, board.y+size, new Rectangle(0, board.y+size,
w, h-board.x-size) // снизу от поля w, h-board.x-size) // снизу от поля
}; };
for (int i = 0; i < partsOfImage.length; i++) { for (int i = 0; i < partsOfImage.length; i++) {
Rectangle rect = partsOfImage[i]; Rectangle rect = partsOfImage[i];
BufferedImage part = image.getSubimage(rect.x, rect.y, rect.width, rect.height); BufferedImage part = image.getSubimage(rect.x, rect.y, rect.width, rect.height);
// Вырезаем часть изображения, в котором будем искать // Вырезаем часть изображения, в котором будем искать
boolean found = true; boolean found = true;
for (int j = 0; j < colors.length; j++) { for (int j = 0; j < colors.length; j++) {
if (colors[i] == -1) continue; if (colors[i] == -1) continue;
Point pt = findButton(part, colors[j]); Point pt = findButton(part, colors[j]);
if (pt != null) { if (pt != null) {
// Учитываем смещения относительно частей картинок // Учитываем смещения относительно частей картинок
pt.translate(rect.x, rect.y); pt.translate(rect.x, rect.y);
out[j] = pt; out[j] = pt;
} else { } else {
@ -129,19 +129,19 @@ public class ImageUtils {
} }
if (found) return out; if (found) return out;
} }
// Не удалось найти все точки // Не удалось найти все точки
return null; return null;
} }
/** /**
* Преобразовать массив цветов в графический вид * Преобразовать массив цветов в графический вид
* @param ids массив идентификаторов последовательности * @param ids массив идентификаторов последовательности
* @param palette массив палитры цветов * @param palette массив палитры цветов
* @return изображение последовательности цветов * @return изображение последовательности цветов
*/ */
public BufferedImage sequenceToImage(byte[] ids, int[] palette) { public BufferedImage sequenceToImage(byte[] ids, int[] palette) {
final int size = 20; // размер каждой ячейки final int size = 20; // размер каждой ячейки
// Разбивать будем по 10 клеток на строку // Разбивать будем по 10 клеток на строку
final int CELLS_IN_ROW = 10; final int CELLS_IN_ROW = 10;
int width = CELLS_IN_ROW * size; int width = CELLS_IN_ROW * size;
if (width == 0) width = size; if (width == 0) width = size;
@ -160,13 +160,13 @@ public class ImageUtils {
} }
/** /**
* Преобразовать цветное изображение в монохромное. * Преобразовать цветное изображение в монохромное.
* Нужно также учесть, что если поле расположено на светлом * Нужно также учесть, что если поле расположено на светлом
* фоне, то необходимо инвертировать изображение, чтобы * фоне, то необходимо инвертировать изображение, чтобы
* получить сплошную белую область на месте поля. * получить сплошную белую область на месте поля.
* @param pixels массив пикселей изображения * @param pixels массив пикселей изображения
* @param value разделяющее значение * @param value разделяющее значение
* @return массив boolean, true - белый, false - чёрный * @return массив boolean, true - белый, false - чёрный
*/ */
private boolean[] threshold(int[] pixels, int value) { private boolean[] threshold(int[] pixels, int value) {
boolean inverse = isBackgroundLight(MAX_COLOR_POINTS); boolean inverse = isBackgroundLight(MAX_COLOR_POINTS);
@ -180,12 +180,12 @@ public class ImageUtils {
} }
/** /**
* Получение состояния яркости фона. * Получение состояния яркости фона.
* @param numPoints сколько точек нужно для определения. * @param numPoints сколько точек нужно для определения.
* @return true - фон светлый, false - тёмный * @return true - фон светлый, false - тёмный
*/ */
private boolean isBackgroundLight(int numPoints) { private boolean isBackgroundLight(int numPoints) {
// Получаем numPoints случайных точек // Получаем numPoints случайных точек
Random rnd = new Random(); Random rnd = new Random();
int[] colors = new int[numPoints]; int[] colors = new int[numPoints];
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < numPoints; i++) {
@ -193,7 +193,7 @@ public class ImageUtils {
int y = rnd.nextInt(h); int y = rnd.nextInt(h);
colors[i] = image.getRGB(x, y); colors[i] = image.getRGB(x, y);
} }
// Находим среднюю яркость всех numPoints точек // Находим среднюю яркость всех numPoints точек
long sum = 0; long sum = 0;
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < numPoints; i++) {
int brightness = getBrightness(colors[i]); int brightness = getBrightness(colors[i]);
@ -204,13 +204,13 @@ public class ImageUtils {
} }
/** /**
* Определить координаты левой верхней ячейки игрового поля. * Определить координаты левой верхней ячейки игрового поля.
* @param boardSize размерность поля (10x10, 14x14 и т.д.) * @param boardSize размерность поля (10x10, 14x14 и т.д.)
* @return координата левого верхнего прямоугольника * @return координата левого верхнего прямоугольника
*/ */
private Point getBoardXY(int boardSize) { private Point getBoardXY(int boardSize) {
/* /*
* Сначала подсчитаем количество белых точек по горизонтали и вертикали * Сначала подсчитаем количество белых точек по горизонтали и вертикали
*/ */
int[] horizontal = new int[h]; int[] horizontal = new int[h];
for (int i = 0; i < h; i++) { for (int i = 0; i < h; i++) {
@ -231,15 +231,15 @@ public class ImageUtils {
} }
/* /*
* Затем "отфильтруем" лишнее: подсчитаем среднее значение * Затем "отфильтруем" лишнее: подсчитаем среднее значение
* и на его основе уберём малозначимые строки и столбцы. * и на его основе уберём малозначимые строки и столбцы.
*/ */
horizontal = filterByMean(horizontal); horizontal = filterByMean(horizontal);
vertical = filterByMean(vertical); vertical = filterByMean(vertical);
/* /*
* Ищем наибольшую ненулевую последовательность. * Ищем наибольшую ненулевую последовательность.
* Индексы границ последовательности и будут граничными точками поля. * Индексы границ последовательности и будут граничными точками поля.
*/ */
int[] vParam = getParamsFromSequence(horizontal); int[] vParam = getParamsFromSequence(horizontal);
int[] hParam = getParamsFromSequence(vertical); int[] hParam = getParamsFromSequence(vertical);
@ -249,15 +249,15 @@ public class ImageUtils {
int outY = vParam[0]; int outY = vParam[0];
int outWidth = hParam[1]; int outWidth = hParam[1];
int outHeight = vParam[1]; int outHeight = vParam[1];
// Подсчет размера ячейки // Подсчет размера ячейки
cellSize = Math.max((outWidth / boardSize), (outHeight / boardSize)); cellSize = Math.max((outWidth / boardSize), (outHeight / boardSize));
return new Point(outX, outY); return new Point(outX, outY);
} }
/** /**
* Фильтр последовательности от малозначимых значений. * Фильтр последовательности от малозначимых значений.
* @param source последовательность вхождений цвета * @param source последовательность вхождений цвета
* @return отфильтрованный массив со значениями 0 и 1 * @return отфильтрованный массив со значениями 0 и 1
*/ */
private int[] filterByMean(int[] source) { private int[] filterByMean(int[] source) {
long mean = 0; long mean = 0;
@ -272,9 +272,9 @@ public class ImageUtils {
} }
/** /**
* Поиск самой длинной последовательности в массиве. * Поиск самой длинной последовательности в массиве.
* @param source входная последовательность из нулей и единиц * @param source входная последовательность из нулей и единиц
* @return массив параметров - индекс начала последовательности и её длина * @return массив параметров - индекс начала последовательности и её длина
*/ */
private int[] getParamsFromSequence(int[] source) { private int[] getParamsFromSequence(int[] source) {
int maxStart = 0, start = 0; int maxStart = 0, start = 0;
@ -292,7 +292,7 @@ public class ImageUtils {
maxLength = length; maxLength = length;
} }
} else { } else {
// Если предыдущий элемент был нулевым - начинаем новую последовательность // Если предыдущий элемент был нулевым - начинаем новую последовательность
start = i; start = i;
} }
} }
@ -300,14 +300,14 @@ public class ImageUtils {
} }
/** /**
* Поиск координаты кнопки с цветом template * Поиск координаты кнопки с цветом template
* @param img изображение, на котором будем искать * @param img изображение, на котором будем искать
* @param template шаблон цвета * @param template шаблон цвета
* @return координата X. Y, или null если не нашли * @return координата X. Y, или null если не нашли
*/ */
private Point findButton(BufferedImage img, int template) { private Point findButton(BufferedImage img, int template) {
int h2 = img.getHeight() / 2; int h2 = img.getHeight() / 2;
// Искать будем с середины по вертикали, так быстрее найдём // Искать будем с середины по вертикали, так быстрее найдём
for (int y = 0; y < h2; y++) { for (int y = 0; y < h2; y++) {
for (int x = 0; x < img.getWidth(); x++) { for (int x = 0; x < img.getWidth(); x++) {
int color = img.getRGB(x, h2 - y); int color = img.getRGB(x, h2 - y);
@ -320,16 +320,16 @@ public class ImageUtils {
} }
} }
} }
// Не нашли // Не нашли
return null; return null;
} }
/** /**
* Проверка на соответствие цветов друг другу * Проверка на соответствие цветов друг другу
* @param color1 первый цвет * @param color1 первый цвет
* @param color2 второй цвет * @param color2 второй цвет
* @param tolerance чувствительность * @param tolerance чувствительность
* @return true - соответствуют, false - нет * @return true - соответствуют, false - нет
*/ */
private boolean isEquals(int color1, int color2, int tolerance) { private boolean isEquals(int color1, int color2, int tolerance) {
if (tolerance < 2) return color1 == color2; if (tolerance < 2) return color1 == color2;
@ -346,9 +346,9 @@ public class ImageUtils {
} }
/** /**
* Получение яркости цвета * Получение яркости цвета
* @param color исходный цвет * @param color исходный цвет
* @return яркость (0..255) * @return яркость (0..255)
*/ */
private int getBrightness(int color) { private int getBrightness(int color) {
int qr = (color >> 16) & 0xff; int qr = (color >> 16) & 0xff;
@ -358,8 +358,8 @@ public class ImageUtils {
} }
/* /*
* Получение цвета из монохромного изображения. * Получение цвета из монохромного изображения.
* return true - белый, false - чёрный * return true - белый, false - чёрный
*/ */
private boolean getBWPixel(int x, int y) { private boolean getBWPixel(int x, int y) {
if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return false; if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return false;

View File

@ -6,12 +6,12 @@ import java.awt.image.BufferedImage;
import javax.swing.*; import javax.swing.*;
/** /**
* Окно приложения. * Окно приложения
* @author aNNiMON * @author aNNiMON
*/ */
public class RobotFrame extends JFrame { public class RobotFrame extends JFrame {
/* Статус работы приложения */ /* Статус работы приложения */
private boolean isRunning; private boolean isRunning;
private Thread robotAction; private Thread robotAction;
@ -201,7 +201,7 @@ public class RobotFrame extends JFrame {
int windowX, windowY, boardSize, cellSize; int windowX, windowY, boardSize, cellSize;
BufferedImage detectImage; BufferedImage detectImage;
RobotUtils robot; RobotUtils robot;
// Получаем настройки // Получаем настройки
try { try {
robot = new RobotUtils(); robot = new RobotUtils();
detectImage = robot.getImage(-1, -1, -1, -1); detectImage = robot.getImage(-1, -1, -1, -1);
@ -214,9 +214,9 @@ public class RobotFrame extends JFrame {
return; return;
} }
ImageUtils iu = new ImageUtils(detectImage, boardSize, cellSize, windowX, windowY); ImageUtils iu = new ImageUtils(detectImage, boardSize, cellSize, windowX, windowY);
// Обрезаем картинку до вида игрового поля // Обрезаем картинку до вида игрового поля
detectImage = iu.getBoardImage(); detectImage = iu.getBoardImage();
// Получаем цвета из картинки // Получаем цвета из картинки
int[][] table = new int[boardSize][boardSize]; int[][] table = new int[boardSize][boardSize];
int offset = cellSize / 2; int offset = cellSize / 2;
for (int i = 0; i < boardSize; i++) { for (int i = 0; i < boardSize; i++) {
@ -226,17 +226,17 @@ public class RobotFrame extends JFrame {
} }
} }
BotFloodIt bfi = new BotFloodIt(table); BotFloodIt bfi = new BotFloodIt(table);
// Получаем результирующую последовательность цветов // Получаем результирующую последовательность цветов
byte[] result = bfi.getFillSequence(); byte[] result = bfi.getFillSequence();
int[] colors = bfi.getColors(); int[] colors = bfi.getColors();
// Пытаемся получить координаты кнопок для автоматической игры // Пытаемся получить координаты кнопок для автоматической игры
Point[] buttons = iu.getButtons(colors); Point[] buttons = iu.getButtons(colors);
if (buttons == null) { if (buttons == null) {
// Если не удалось найти кнопки, то просто выводим последовательность в виде картинки // Если не удалось найти кнопки, то просто выводим последовательность в виде картинки
BufferedImage out = iu.sequenceToImage(result, colors); BufferedImage out = iu.sequenceToImage(result, colors);
showImageWindow("Result: "+result.length+" steps", out); showImageWindow("Result: "+result.length+" steps", out);
} else { } else {
// Запускаем автоигру // Запускаем автоигру
robot.autoClick(buttons, result); robot.autoClick(buttons, result);
} }
isRunning = false; isRunning = false;
@ -249,7 +249,7 @@ public class RobotFrame extends JFrame {
}//GEN-LAST:event_startStopActionPerformed }//GEN-LAST:event_startStopActionPerformed
private void checkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkButtonActionPerformed private void checkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkButtonActionPerformed
if (isRunning) return; // нельзя проверять настройки во время работы if (isRunning) return; // нельзя проверять настройки во время работы
int windowX, windowY, boardSize, cellSize; int windowX, windowY, boardSize, cellSize;
BufferedImage detectImage; BufferedImage detectImage;
RobotUtils robot; RobotUtils robot;
@ -269,7 +269,7 @@ public class RobotFrame extends JFrame {
}//GEN-LAST:event_checkButtonActionPerformed }//GEN-LAST:event_checkButtonActionPerformed
private void detectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_detectButtonActionPerformed private void detectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_detectButtonActionPerformed
if (isRunning) return; // нельзя определять настройки во время работы if (isRunning) return; // нельзя определять настройки во время работы
RobotUtils robot; RobotUtils robot;
try { try {
robot = new RobotUtils(); robot = new RobotUtils();
@ -287,9 +287,9 @@ public class RobotFrame extends JFrame {
}//GEN-LAST:event_detectButtonActionPerformed }//GEN-LAST:event_detectButtonActionPerformed
/** /**
* Показать модальное окно с изображением * Показать модальное окно с изображением
* @param title заголовок окна * @param title заголовок окна
* @param image изображение * @param image изображение
* @throws SecurityException * @throws SecurityException
*/ */
private void showImageWindow(String title, BufferedImage image) throws SecurityException { private void showImageWindow(String title, BufferedImage image) throws SecurityException {

View File

@ -6,7 +6,7 @@ import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
/** /**
* Работа с классом Robot. * Работа с классом Robot.
* @author aNNiMON * @author aNNiMON
*/ */
public class RobotUtils { public class RobotUtils {
@ -15,16 +15,16 @@ public class RobotUtils {
private Robot robot; private Robot robot;
/** /**
* Конструктор * Конструктор
* @throws AWTException ошибка инициализации Robot * @throws AWTException ошибка инициализации Robot
*/ */
public RobotUtils() throws AWTException { public RobotUtils() throws AWTException {
robot = new Robot(); robot = new Robot();
} }
/** /**
* Кликнуть в нужную точку * Кликнуть в нужную точку
* @param click точка по которой нужно кликнуть * @param click точка по которой нужно кликнуть
*/ */
public void clickPoint(Point click) { public void clickPoint(Point click) {
robot.mouseMove(click.x, click.y); robot.mouseMove(click.x, click.y);
@ -34,9 +34,9 @@ public class RobotUtils {
} }
/** /**
* Автоматически воспроизвести заданную последовательность нажатий * Автоматически воспроизвести заданную последовательность нажатий
* @param buttons координаты точек, куда следует нажимать * @param buttons координаты точек, куда следует нажимать
* @param result последовательность id для указания на нужную кнопку * @param result последовательность id для указания на нужную кнопку
*/ */
public void autoClick(Point[] buttons, byte[] result) { public void autoClick(Point[] buttons, byte[] result) {
for (int i = 0; i < result.length; i++) { for (int i = 0; i < result.length; i++) {
@ -44,8 +44,8 @@ public class RobotUtils {
} }
} }
/** /**
* Автоматическое написание сообщения * Автоматическое написание сообщения
* @param text "печатаемый" текст * @param text "печатаемый" текст
*/ */
public void writeMessage(String text) { public void writeMessage(String text) {
for (char symbol : text.toCharArray()) { for (char symbol : text.toCharArray()) {
@ -64,8 +64,8 @@ public class RobotUtils {
} }
/* /*
* Получение картинки размером [width x height] с экрана с позиции [x, y] * Получение картинки размером [width x height] с экрана с позиции [x, y]
* Если width или height равны -1, то возвращаем весь экран. * Если width или height равны -1, то возвращаем весь экран.
*/ */
public BufferedImage getImage(int x, int y, int width, int height) { public BufferedImage getImage(int x, int y, int width, int height) {
Rectangle area; Rectangle area;