Kibor |
Отправлено: 27 Сентября, 2018 - 22:29:29
|
Эксперт
Просматривает форум
Сообщений всего: 8218
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Короче вот готовая функция нахождения лучшего хода.
А как уже сканируют экран не важно.
Из за ограничений передачи указателей переданных с функции в функцию другую (а хотелось сделать без глобальных переменных ) пришлось прибегнуть к адресной арифметике, что несколько тормозит работу.
Это надо сохранить в файл и назвать как угодно. К примеру Лучший_ход.txt
CODE:function perebor(int #t, int X, int Y, int #kx1, int #ky1, int #kx2, int #ky2)//Перебирает все возможные комбинации меняя соседнте фишки
{
int adr=address(#t[0][0]);
int tp;
int Max=-1;
int tMax=-1;
int x, y;
for (y=1; y<Y-1; y++)
{
for (x=1; x<X-1; x++)
{
//Делаем ход меняя x на x-1
tp=t[x][y];
t[x][y]=t[x-1][y];
t[x-1][y]=tp;
Max=proverka(X, Y, adr);//Оцениваем полученную ситуацию
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x-1; ky2=y;}//Если оценка больше предыдущей, записываем координаты и оценку сохраняем.
//Меняем назад на исходную.
tp=t[x][y];
t[x][y]=t[x-1][y];
t[x-1][y]=tp;
tp=t[x][y];
t[x][y]=t[x+1][y];
t[x+1][y]=tp;
Max=proverka(X, Y, adr);
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x+1; ky2=y;}
tp=t[x][y];
t[x][y]=t[x+1][y];
t[x+1][y]=tp;
tp=t[x][y];
t[x][y]=t[x][y-1];
t[x][y-1]=tp;
Max=proverka(X, Y, adr);
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x; ky2=y-1;}
tp=t[x][y];
t[x][y]=t[x][y-1];
t[x][y-1]=tp;
tp=t[x][y];
t[x][y]=t[x][y+1];
t[x][y+1]=tp;
Max=proverka(X, Y, adr);
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x; ky2=y+1;}
tp=t[x][y];
t[x][y]=t[x][y+1];
t[x][y+1]=tp;
}
}
return tMax;
}
function proverka(int X, int Y, int mas)//Оценивает после замены ситуацию. Находит все совпавшие линии ровные присваивая им оценку равную кол фишек.
{
int Ocenka;
int tOcenka=-1;
int x, y;
for (x=0; x<X; x++)
{
Ocenka=1;
for (y=0; y<Y-1; y++)
{
if (addressi(mas+(x*Y+y)*4)==addressi(mas+(x*Y+y+1)*4))Ocenka++;
else Ocenka=1;
if (Ocenka>tOcenka)tOcenka=Ocenka;
}
}
for (y=0; y<Y; y++)
{
Ocenka=1;
for (x=0; x<X-1; x++)
{
if (addressi(mas+(x*Y+y)*4)==addressi(mas+((x+1)*Y+y)*4))Ocenka++;
else Ocenka=1;
if (Ocenka>tOcenka)tOcenka=Ocenka;
}
}
return tOcenka;
}
Это его использование в своем скрипте
CODE:#include "C:\Лучший_ход.txt"//В начале скрипта
int X=7, Y=8;//Размерность поля
/*
Массив с типами фигур. Заполнить любыми числами по типу и любым способом
Координаты фишек надо хранить так же в двухмерных массивах. Пример:
new int fX[X][Y];//Координаты X фишек
new int fY[X][Y];//Координаты Y фишек
*/
new int mas[X][Y];
/*
Индексы заменяемых массивов. kx1 ky1 меняется на kx2 ky2
то есть фишки с координатами fX[kx1][ky1] fY[kx1][ky1] и fX[kx2][ky2] fY[kx2][ky2] поменяются местами
*/
int kx1, ky1, kx2, ky2;
/*
//Использование
if (perebor(#mas[0][0], X, Y, #kx1, #ky1, #kx2, #ky2)>2)//Есть замена
{
//Тут поменять местами фишки.
messagebox ("Есть замена "+format(kx1)+" " +format(ky1)+" -" +format(mas[kx1][ky1])+" на "+format(kx2)+" " +format(ky2)+" -" +format(mas[kx2][ky2]));
}
*/
//Тест с файла (убрать после весь ниже код)
if (fopen ("c:\Исходник.txt", "r")!=0)//В этом файле массив 7 на 8 заполнен цифрами которые соответствуют фишкам
{
for(int n1=0; n1<Y; n1++)
{
for(int n=0; n<X; n++)
{ fread(mas[n][n1]);
}
}
fclose();//закрываем файл
}
int L=perebor(#mas[0][0], X, Y, #kx1, #ky1, #kx2, #ky2);
//Покажет лучший результат замены
messagebox ("Лучший ход на "+format(L)+" Заменить "+format(kx1)+" " +format(ky1)+" -" +format(mas[kx1][ky1])+" на "+format(kx2)+" " +format(ky2)+" -" +format(mas[kx2][ky2]));
Сам файл теста примерно такой
CODE:0 1 2 3 4 5 2
2 3 1 1 2 5 3
1 5 1 7 5 9 2
5 5 2 1 5 5 2
4 3 2 5 2 0 5
0 6 1 4 5 6 1
5 5 5 2 5 5 5
0 5 4 5 5 1 5
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
А это быстрее, но с глобальной одной переменной.
mas_pole. Такое имя должно быть массива в котором хранятся фишки.
Это надо сохранить в файл и назвать как угодно. К примеру Лучший_ход.txt
CODE:function perebor(int X, int Y, int #kx1, int #ky1, int #kx2, int #ky2)//Перебирает все возможные комбинации меняя соседнте фишки
{
int tp;
int Max=-1;
int tMax=-1;
int x, y;
for (y=1; y<Y-1; y++)
{
for (x=1; x<X-1; x++)
{
//Делаем ход меняя x на x-1
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x-1][y];
mas_pole[x-1][y]=tp;
Max=proverka(X, Y);//Оцениваем полученную ситуацию
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x-1; ky2=y;}//Если оценка больше предыдущей, записываем координаты и оценку сохраняем.
//Меняем назад на исходную.
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x-1][y];
mas_pole[x-1][y]=tp;
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x+1][y];
mas_pole[x+1][y]=tp;
Max=proverka(X, Y);
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x+1; ky2=y;}
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x+1][y];
mas_pole[x+1][y]=tp;
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x][y-1];
mas_pole[x][y-1]=tp;
Max=proverka(X, Y);
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x; ky2=y-1;}
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x][y-1];
mas_pole[x][y-1]=tp;
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x][y+1];
mas_pole[x][y+1]=tp;
Max=proverka(X, Y);
if (Max>=tMax){tMax=Max; kx1=x; ky1=y; kx2=x; ky2=y+1;}
tp=mas_pole[x][y];
mas_pole[x][y]=mas_pole[x][y+1];
mas_pole[x][y+1]=tp;
}
}
return tMax;
}
function proverka(int X, int Y)//Оценивает после замены ситуацию. Находит все совпавшие линии ровные присваивая им оценку равную кол фишек.
{
int Ocenka;
int tOcenka=-1;
int x, y;
for (y=0; y<Y; y++)
{
Ocenka=1;
for (x=0; x<X-1; x++)
{
if (mas_pole[x][y]==mas_pole[x+1][y])Ocenka++;
else Ocenka=1;
if (Ocenka>tOcenka)tOcenka=Ocenka;
}
}
for (x=0; x<X; x++)
{
Ocenka=1;
for (y=0; y<Y-1; y++)
{
if (mas_pole[x][y]==mas_pole[x][y+1])Ocenka++;
else Ocenka=1;
if (Ocenka>tOcenka)tOcenka=Ocenka;
}
}
return tOcenka;
}
Это его использование в своем скрипте
CODE:#include "C:\Лучший_ход.txt"//В начале скрипта
int X=7, Y=8;//Размерность поля
/*
Массив с типами фигур. Заполнить любыми числами по типу и любым способом
Координаты фишек надо хранить так же в двухмерных массивах. Пример:
new int fX[X][Y];//Координаты X фишек
new int fY[X][Y];//Координаты Y фишек
*/
new int mas_pole[X][Y];//ОБЯЗАТЕЛЬНО с ТАКИМ ИМЕНЕМ, так как тут она используется глобально в коде нахождения лучшего хода
/*
Индексы заменяемых массивов. kx1 ky1 меняется на kx2 ky2
то есть фишки с координатами fX[kx1][ky1] fY[kx1][ky1] и fX[kx2][ky2] fY[kx2][ky2] поменяются местами
*/
int kx1, ky1, kx2, ky2;
/*
//Использование
if (perebor(X, Y, #kx1, #ky1, #kx2, #ky2)>2)//Есть замена
{
//Тут поменять местами фишки.
messagebox ("Есть замена "+format(kx1)+" " +format(ky1)+" -" +format(mas[kx1][ky1])+" на "+format(kx2)+" " +format(ky2)+" -" +format(mas[kx2][ky2]));
}
*/
//Тест с файла (убрать после весь ниже код)
if (fopen ("c:\Исходник.txt", "r")!=0)//В этом файле массив 7 на 8 заполнен цифрами которые соответствуют фишкам
{
for(int n1=0; n1<Y; n1++)
{
for(int n=0; n<X; n++)
{
fread(mas_pole[n][n1]);
}
}
fclose();//закрываем файл
}
int L=perebor(X, Y, #kx1, #ky1, #kx2, #ky2);
//Покажет лучший результат замены
messagebox ("Лучший ход на "+format(L)+" Заменить "+format(kx1)+" " +format(ky1)+" -" +format(mas_pole[kx1][ky1])+" на "+format(kx2)+" " +format(ky2)+" -" +format(mas_pole[kx2][ky2]));
|
|
|
Zireael |
Отправлено: 28 Сентября, 2018 - 21:01:30
|
Эксперт
Покинул форум
Сообщений всего: 4465
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Цитата: Почему то добавление mas_pole[posX[j]][posY[j]]==ii; не работает....
CODE:new int field[row][col]; // поле
Во всем скрипте переименовать массив field в mas_pole. |
|
|
Zireael |
Отправлено: 29 Сентября, 2018 - 19:30:00
|
Эксперт
Покинул форум
Сообщений всего: 4465
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Цитата: совместить Ваш код с кодом от Кибора
code (Отобразить)CODE:#include "C:\Лучший_ход.txt" // скрипт, тот что с глобальной переменной mas_pole
int kx1, ky1, kx2, ky2;
external(INT, "Sort", "Sort", pathfolder()+"\math.dll" ); // функция сортировки из длл
int row=8, col=8; // размеры поля (количество строк и столбцов)
int count_image = 7; // сколько картинок
string path="C:\Users\yacir\Desktop\"; // путь для сохранения массива
////////////
// параметры для findheapcolor
int r=10; // разбежность для поиска картинок (подобрать, если не находит картинки)
int sx=331, sy=90, fx=951, fy=721; // координаты для findimage
int color1[1], color2[1], color3[1], color4[1], color5[1], color6[1], color7[1];
color1[0]=16055294; // череп
color2[0]=13049233; // фиолетовый
color3[0]=3329668; // зелёный
color4[0]=12683820; // синий
color5[0]=5753324; // жёлтый
color6[0]=4007637; // красный
color7[0]=4277098; // коричневый
int kol1[1], kol2[1], kol3[1], kol4[1], kol5[1], kol6[1], kol7[1];
kol1[0]=100;
kol2[0]=100;
kol3[0]=100;
kol4[0]=100;
kol5[0]=100;
kol6[0]=100;
kol7[0]=100;
////////////
// тут ничего не менять
int size_mas_pole=row*col; // размер поля
new int mas_pole[row][col]; // поле
new int arr[size_mas_pole][3]; // массив для всех найденных картинок, хранит координаты и номер картинки
new int posX[size_mas_pole];
new int posY[size_mas_pole]; // массивы для координат картинок
int found;
int stepX=(fx-sx)/col, stepY=(fy-sy)/row; // расстояние между картинками
////////////
loop()
{
dynamic(); // поиск динамики, ждёт когда фишки перестанут сдвигаться
found=find(); // поиск картинок и их сортировка
////// вывод количества найденных картинок (можно убрать)
if(found==size_mas_pole)textbkcolor(16000000, 65280);
else textbkcolor(65280, 300);
textout(99, 300, 800, "Найдено картинок: "+format(found)+" из "+format(row*col), 0);
////////
if(found==size_mas_pole) // если найдено нужное количество картинок
{
SaveArray(); // сохранение массива в файл (можно убрать)
find_hod() // поиск хода и ход
}
sleep(100);
}
function dynamic()
{
int x, y;
loop()
{
finddynamic(0, #x, #y, 0, 0, 0, 0, sx, sy, fx, fy, -1); sleep(200);
if (finddynamic(1, #x, #y, 10, 10, 20, 20, sx, sy, fx, fy, -1)==0)
{
finddynamic(0, #x, #y, 0, 0, 0, 0, sx, sy, fx, fy, -1); sleep(200);
if (finddynamic(1, #x, #y, 10, 10, 20, 20, sx, sy, fx, fy, -1)==0)break;
}
}
}
function SaveArray()
{
int i, j, k;
// сохранение массива в файл, сохраняется рядом с каринками
if(fopen(path+"Array.txt", "w")!=0)
{
string tmp;
for (i=0; i<row; i++)
{
tmp="";
for (j=0; j<col; j++)
{
for (k=0; k<count_image; k++)
{
if(mas_pole[i][j]==k){tmp=tmp+format(k)+" "; break;}
}
}
fwrite(tmp);fwrite(ENDL);
}
fclose();
}
}
function find()
{
int i=0, z=0, a;
// поиск картинок
a=findheapcolor(size_mas_pole, #color1[0], #kol1[0], 1, 1, #posX[0], #posY[0],stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // поиск черепов
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
a=findheapcolor(size_mas_pole, #color2[0], #kol2[0], 1, 1, #posX[0], #posY[0],stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // фиолетовые
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
a=findheapcolor(size_mas_pole, #color3[0], #kol3[0], 1, 1, #posX[0], #posY[0], stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // зелёные
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
a=findheapcolor(size_mas_pole, #color4[0], #kol4[0], 1, 1, #posX[0], #posY[0],stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // синие
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
a=findheapcolor(size_mas_pole, #color5[0], #kol5[0], 1, 1, #posX[0], #posY[0],stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // жёлтые
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
a=findheapcolor(size_mas_pole, #color6[0], #kol6[0], 1, 1, #posX[0], #posY[0],stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // красные
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
a=findheapcolor(size_mas_pole, #color7[0], #kol7[0], 1, 1, #posX[0], #posY[0],stepX/2,stepY/2,stepX,stepY,sx,sy,fx,fy,r,r,r,r,r,r,-1); // коричневые
//messagebox(a); // сколько найдено
if(a>0){coord(a, i, #z); i++;}
if(z==size_mas_pole)sort_image(#arr[0][0], #mas_pole[0][0], row, col); // если найдено нужное количество картинок, то они сортируются
return z;
}
// сортировка картинок по полю
function sort_image(int #m, int #m1, int row, int column)
{
int i, j;
new int temp[row][3]; // дополнительный массив
Sort(address(#m[0][0]), row*column, 3, 0 ); // сортировка массива по первому столбцу (по координате X)
for(i=0; i<column; i++)
{
for(j=0; j<row; j++)
{
temp[j][0]=m[i*row+j][0];
temp[j][1]=m[i*row+j][1];
temp[j][2]=m[i*row+j][2];
}
Sort(address(#temp[0][0]), row, 3, 1); // сортировка массива по второму столбцу (по координате Y)
for(j=0; j<row; j++)m1[j][i]=temp[j][2];
}
delete temp;
}
function find_hod()
{
if (perebor(row, col, #kx1, #ky1, #kx2, #ky2)>2)
{
//messagebox(format(kx1)+" "+format(ky1)+" "+format(kx2)+" "+format(ky2));
hod(kx1, ky1, kx2, ky2);
}
}
function hod(int x1, int y1, int x2, int y2)
{
mouse(LEFT, sx+stepX*y1+stepX/2, sy+stepY*x1+stepY/2 ); sleep(300);
mouse(LEFT, sx+stepX*y2+stepX/2, sy+stepY*x2+stepY/2 ); sleep(300);
mousemove(sx-10, sy); sleep(300);
}
function coord(int aa, int ii, int #zz)
{
for(int j=0;j<aa;j++)
{
if(zz<size_mas_pole)
{
arr[zz][0]=posX[j]; // координата X
arr[zz][1]=posY[j]; // координата Y
arr[zz][2]=ii; // номер картинки
zz++;
}
}
} |
|
|
Zireael |
Отправлено: 30 Сентября, 2018 - 00:17:40
|
Эксперт
Покинул форум
Сообщений всего: 4465
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Цитата: function proverka(int X, int Y, int mas)//Оценивает после замены ситуацию. Находит все совпавшие линии ровные присваивая им оценку равную кол фишек.
Тоже самое в 1.5 раза быстрее (Отобразить)CODE:function proverka(int X, int Y)//Оценивает после замены ситуацию. Находит все совпавшие линии ровные присваивая им оценку равную кол фишек.
{
int tOcenka=-1;
int x, y;
string R="(\d)\1{7}|(\d)\2{6}|(\d)\3{5}|(\d)\4{4}|(\d)\5{3}|(\d)\6{2}"; // подряд идущие числа от 8 до 3, например 55555 или 3333333
string temp="";
for (y=0; y<Y; y++){for (x=0; x<X; x++)temp=temp+format(mas_pole[x][y]);temp=temp+" ";} // массив в 1 строку
if(regexsearch(1, #temp, temp, R)>0){if (size(temp)>tOcenka)tOcenka=size(temp);} // поиск подряд идущих чисел от 8 до 3
for (x=0; x<X; x++){for (y=0; y<Y; y++)temp=temp+format(mas_pole[x][y]);temp=temp+" ";} // массив в 1 строку
if(regexsearch(1, #temp, temp, R)>0){if (size(temp)>tOcenka)tOcenka=size(temp);} // поиск подряд идущих чисел от 8 до 3
return tOcenka;
} |
|
|
|