Автоматизация и боты

 Помощь      Поиск      Пользователи
Сайт Кибор     Программируемый кликер Кибор     Видео обучение     Заказать бот

 Страниц (1): [1]   

> Без описания
Dantes3000
Отправлено: 24 Марта, 2023 - 13:44:52
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1470
Дата рег-ции: Июнь 2016  
Репутация: 58




CODE:
string key_order[3]={"Ж", "К", "З"};
string lab[4][7];
/*
[Ж][З][Ж][З]
[К][З][Ж][Ж]
[Ж][К][К][К]
[К][Ж][З][Ж]
[З][З][К][З]
[Ж][З][Ж][З]
[К][Ж][К][Ж]
*/

lab[0][0]="Ж"; lab[1][0]="З"; lab[2][0]="Ж"; lab[3][0]="З";
lab[0][1]="К"; lab[1][1]="З"; lab[2][1]="Ж"; lab[3][1]="Ж";
lab[0][2]="Ж"; lab[1][2]="К"; lab[2][2]="К"; lab[3][2]="К";
lab[0][3]="К"; lab[1][3]="Ж"; lab[2][3]="З"; lab[3][3]="Ж";
lab[0][4]="З"; lab[1][4]="З"; lab[2][4]="К"; lab[3][4]="З";
lab[0][5]="Ж"; lab[1][5]="З"; lab[2][5]="Ж"; lab[3][5]="З";
lab[0][6]="К"; lab[1][6]="Ж"; lab[2][6]="К"; lab[3][6]="Ж";


Есть лабиринт по цветам - желтый, красный, зеленый.
Идти можно только поочередно по каждому цвету, после зеленого идет снова желтый.
Назад идти нельзя. Есть только один путь. Размер лабаринта одинаковый.

Есть идеи как можно реализовать? Нужно получить массив в какую сторону идти дальше.
Пример решения лабиринта со скриншота:

начало в клетке 1, потом низ - право - право - низ - низ - лево - лево - низ - низ - низ


Нажмите для увеличения
 
 Top
Zireael
Отправлено: 24 Марта, 2023 - 14:36:53
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4421
Дата рег-ции: Нояб. 2017  
Репутация: 584




Начало всегда в левой верхней клетке?
Как определять где конец лабиринта? Всегда на нижней границе или может сбоку?
Лучше несколько вариантов лабиринта выложить.

(Отредактировано автором: 24 Марта, 2023 - 14:41:10)

 
 Top
Kibor
Отправлено: 24 Марта, 2023 - 14:50:40
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 8111
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 355




 Dantes3000 пишет:
Есть идеи как можно реализовать? Нужно получить массив в какую сторону идти дальше.


Если не заморачиваясь примитивно разжевано так:
CODE:
string lab[4][7];
int X=sizearray(lab);
int Y=sizearray(lab[]);
new int LAB[X][Y];
initialarray(#LAB[0][0], 0);
/*
[Ж][З][Ж][З]
[К][З][Ж][Ж]
[Ж][К][К][К]
[К][Ж][З][Ж]
[З][З][К][З]
[Ж][З][Ж][З]
[К][Ж][К][Ж]
*/

lab[0][0]="Ж"; lab[1][0]="З"; lab[2][0]="Ж"; lab[3][0]="З";
lab[0][1]="К"; lab[1][1]="З"; lab[2][1]="Ж"; lab[3][1]="Ж";
lab[0][2]="Ж"; lab[1][2]="К"; lab[2][2]="К"; lab[3][2]="К";
lab[0][3]="К"; lab[1][3]="Ж"; lab[2][3]="З"; lab[3][3]="Ж";
lab[0][4]="З"; lab[1][4]="З"; lab[2][4]="К"; lab[3][4]="З";
lab[0][5]="Ж"; lab[1][5]="З"; lab[2][5]="Ж"; lab[3][5]="З";
lab[0][6]="К"; lab[1][6]="Ж"; lab[2][6]="К"; lab[3][6]="Ж";


int N=1;
int x=0, y=0;
LAB[x][y]=N;
loop()
{
if (lab[x][y]=="Ж")
{
if (x>0){if (LAB[x-1][y]==0){if(lab[x-1][y]=="К") {N++; LAB[x-1][y]=N; x--; continue;}}}
if (y>0){if (LAB[x][y-1]==0){if(lab[x][y-1]=="К") {N++; LAB[x][y-1]=N; y--; continue;}}}
if (x+1<X){if (LAB[x+1][y]==0){if(lab[x+1][y]=="К") {N++; LAB[x+1][y]=N; x++; continue;}}}
if (y+1<Y){if (LAB[x][y+1]==0){if(lab[x][y+1]=="К") {N++; LAB[x][y+1]=N; y++; continue;}}}
}
if (lab[x][y]=="К")
{

if (x>0){if (LAB[x-1][y]==0){if(lab[x-1][y]=="З") {N++; LAB[x-1][y]=N; x--; continue;}}}
if (y>0){if (LAB[x][y-1]==0){if(lab[x][y-1]=="З") {N++; LAB[x][y-1]=N; y--; continue;}}}
if (x+1<X){if (LAB[x+1][y]==0){if(lab[x+1][y]=="З") {N++; LAB[x+1][y]=N; x++; continue;}}}
if (y+1<Y){if (LAB[x][y+1]==0){if(lab[x][y+1]=="З") {N++; LAB[x][y+1]=N; y++; continue;}}}
}
if (lab[x][y]=="З")
{
if (x>0){if (LAB[x-1][y]==0){if(lab[x-1][y]=="Ж") {N++; LAB[x-1][y]=N; x--; continue;}}}
if (y>0){if (LAB[x][y-1]==0){if(lab[x][y-1]=="Ж") {N++; LAB[x][y-1]=N; y--; continue;}}}
if (x+1<X){if (LAB[x+1][y]==0){if(lab[x+1][y]=="Ж") {N++; LAB[x+1][y]=N; x++; continue;}}}
if (y+1<Y){if (LAB[x][y+1]==0){if(lab[x][y+1]=="Ж") {N++; LAB[x][y+1]=N; y++; continue;}}}
}
break;
}







string Rez="";
for (y=0; y<Y; y++)
{
for (x=0; x<X; x++)
{
Rez=Rez+format(LAB[x][y])+" ";
}
Rez=Rez+"^r^n";
}

messagebox (Rez);


И проверки типа if (LAB[x-1][y]==0) вообще не нужны, так как строгая очередность цветов и назад он все равно не пойдет. Они нужны только если есть клетка проходи и тупика. И он может пойти назад.


 Цитата:
int x=0, y=0;

Это координата входа. Может быть в другом месте. Алгоритм будет идти пока есть куда. Или не выйдет с лабиринта.


Или сжато. То же самое
CODE:
string key_order[3]={"Ж", "К", "З"};
string lab[4][7];
int X=sizearray(lab);
int Y=sizearray(lab[]);
new int LAB[X][Y];
initialarray(#LAB[0][0], 0);
/*
[Ж][З][Ж][З]
[К][З][Ж][Ж]
[Ж][К][К][К]
[К][Ж][З][Ж]
[З][З][К][З]
[Ж][З][Ж][З]
[К][Ж][К][Ж]
*/

lab[0][0]="Ж"; lab[1][0]="З"; lab[2][0]="Ж"; lab[3][0]="З";
lab[0][1]="К"; lab[1][1]="З"; lab[2][1]="Ж"; lab[3][1]="Ж";
lab[0][2]="Ж"; lab[1][2]="К"; lab[2][2]="К"; lab[3][2]="К";
lab[0][3]="К"; lab[1][3]="Ж"; lab[2][3]="З"; lab[3][3]="Ж";
lab[0][4]="З"; lab[1][4]="З"; lab[2][4]="К"; lab[3][4]="З";
lab[0][5]="Ж"; lab[1][5]="З"; lab[2][5]="Ж"; lab[3][5]="З";
lab[0][6]="К"; lab[1][6]="Ж"; lab[2][6]="К"; lab[3][6]="Ж";

int t=0, g=t+1;
int N=1;
int x=0, y=0;
int E=0;
LAB[x][y]=N;
loop()
{
W:;
if (lab[x][y]==key_order[t])
{
if (x>0){if(lab[x-1][y]==key_order[g]) {N++; LAB[x-1][y]=N; x--; E=0; t++; if (t>2) t=0; g=t+1; if (g>2) g=0; continue;}}
if (y>0){if(lab[x][y-1]==key_order[g]) {N++; LAB[x][y-1]=N; y--; E=0; t++; if (t>2) t=0; g=t+1; if (g>2) g=0; continue;}}
if (x+1<X){if(lab[x+1][y]==key_order[g]) {N++; LAB[x+1][y]=N; x++; E=0; t++; if (t>2) t=0; g=t+1; if (g>2) g=0; continue;}}
if (y+1<Y){if(lab[x][y+1]==key_order[g]) {N++; LAB[x][y+1]=N; y++; E=0; t++; if (t>2) t=0; g=t+1; if (g>2) g=0; continue;}}
}
E++; if (E>3) break;
t++; if (t>2) t=0; g=t+1; if (g>2) g=0;
goto W;
break;
}







string Rez="";
for (y=0; y<Y; y++)
{
for (x=0; x<X; x++)
{
Rez=Rez+format(LAB[x][y])+" ";
}
Rez=Rez+"^r^n";
}

messagebox (Rez);


Или сжатый еще
CODE:
loop()
{
W:;
if (lab[x][y]==key_order[t])
{
if (x>0){if (find(-1, 0)) continue;}
if (y>0){if (find(0, -1)) continue;}
if (x+1<X){if (find(1, 0)) continue;}
if (y+1<Y){if (find(0, 1)) continue;}
}
E++; if (E>3) break;
t++; if (t>2) t=0; g=t+1; if (g>2) g=0;
goto W;
break;
}

function find(int xx, int yy)
{
if(lab[x+xx][y+yy]==key_order[g]) {N++; LAB[x+xx][y+yy]=N; x=x+xx; y=y+yy; E=0; t++; if (t>2) t=0; g=t+1; if (g>2) g=0; return 1;}
return 0;
}

Это к теме оптимизации кода по размеру у кого код такого рамера, что Кибор глючит
 
 Top
Dantes3000
Отправлено: 25 Марта, 2023 - 10:29:53
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1470
Дата рег-ции: Июнь 2016  
Репутация: 58




 Zireael пишет:
Начало всегда в левой верхней клетке?
Как определять где конец лабиринта? Всегда на нижней границе или может сбоку?
Лучше несколько вариантов лабиринта выложить.


начало может быть в рандомном месте сверху. Конец в рандомном месте снизу. Сбоку не может быть.
(Добавление)
 Kibor пишет:
Это координата входа. Может быть в другом месте. Алгоритм будет идти пока есть куда. Или не выйдет с лабиринта.


да...забыл уточнить. Вход надо тоже определить
 
 Top
Zireael
Отправлено: 26 Марта, 2023 - 23:46:24
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4421
Дата рег-ции: Нояб. 2017  
Репутация: 584




 Цитата:
Если не заморачиваясь

Тогда и не работает как надо. Если будет несколько вариантов куда можно двигаться, то проверит только 1 вариант.
 Цитата:
lab[1][3]="Ж"; lab[2][3]="З"; lab[3][3]="Ж";

С точки lab[2][3] двигаться можно влево и вправо...

 Цитата:
начало может быть в рандомном месте сверху. Конец в рандомном месте снизу.
Вход надо тоже определить

Длл распаковать и закинуть в папку с кибор. Проверял только на win10.
https://drive.google.com/file/d/...view?usp=sharing

Функция возвращает количество ходов, строку с направлением движения и координатами, такого вида:
 Цитата:
Start 0, 0
Down 1, 0
Right 1, 1
Right 1, 2
и т. д.

Right 1, 2 означает: Right - двигаемся вправо, 1 - номер строки, 2 - номер столбца.
Регуляркой можно получить необходимые данные.

CODE:
external(INT, "FindPath", "FindPath", "FindPath.dll");

char result[999];
int lab[7][4]; // 7 строк, 4 столбца

// 0 - Жёлтый, 1 - Красный, 2 - Зелёный.
lab[0][0] = 0; lab[0][1] = 2; lab[0][2] = 0; lab[0][3] = 2;
lab[1][0] = 1; lab[1][1] = 2; lab[1][2] = 0; lab[1][3] = 0;
lab[2][0] = 0; lab[2][1] = 1; lab[2][2] = 1; lab[2][3] = 1;
lab[3][0] = 1; lab[3][1] = 0; lab[3][2] = 2; lab[3][3] = 0;
lab[4][0] = 2; lab[4][1] = 2; lab[4][2] = 1; lab[4][3] = 2;
lab[5][0] = 0; lab[5][1] = 2; lab[5][2] = 0; lab[5][3] = 2;
lab[6][0] = 1; lab[6][1] = 0; lab[6][2] = 1; lab[6][3] = 0;

int CountHod = FindPath(address(#lab[0][0]), address(#result[0]));
if(CountHod>0)
{
messagebox("Всего ходов: "+format(CountHod));
messagebox(format(#result[0]));
}
else messagebox("Путь не найден");


Код длл (Отобразить)
 
 Top
Dantes3000
Отправлено: 28 Марта, 2023 - 12:11:41
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1470
Дата рег-ции: Июнь 2016  
Репутация: 58




Спасибо за помощь, работает идеально.


Может еще есть идеи как распознать лабиринт? Разные цвета, оттенки, моргает всё.
Думаю можно через findshape или через обычный findimage.

через sumcolor не выходит, много ошибок. Но наверное можно найти иделаьные параметры.

Там проблема в том, что многие цвета совпадают для всех ячеек, тем более если с расбежностью делать


Нажмите для увеличения

(Отредактировано автором: 28 Марта, 2023 - 12:13:33)

 
 Top
Kibor
Отправлено: 28 Марта, 2023 - 14:31:53
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 8111
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 355




findheapcolor
 
 Top
Zireael
Отправлено: 28 Марта, 2023 - 15:27:44
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4421
Дата рег-ции: Нояб. 2017  
Репутация: 584




 Цитата:
через sumcolor не выходит, много ошибок.

Нужно использовать разницу каналов. Если цвет красный, значит в нём большое значение красного канала и маленькое (точнее значительно меньше) зелёного и синего. Если цвет зелёный, значит большое значение зелёного канала и маленькое остальных.
К примеру:
Красный: rgb(180, 34, 36) много красного
Зелёный: rgb(9, 188, 8) много зелёного
Жёлтый: rgb(204, 209, 131) много красного и зелёного

Тут правильнее искать по разнице каналов, но такого поиска нет, так что исходим из того что есть.
CODE:
// координаты поля
// левый верхний угол левой верхней клетки
// правый нижний угол правой нижней клетки
int coord_field[4] = {17, 160, 397, 818};


int i, j, k;
int lab[7][4], result[3];
int scr[999][999]; // массив для скрина поля

// считаем размер клетки
int cellX = (coord_field[2] - coord_field[0]) / 4;
int cellY = (coord_field[3] - coord_field[1]) / 7;

// искомые цвета цвета
int Yellow = rgb(100, 100, 0); // жёлтый
int Red = rgb(100, 0, 0); // красный
int Green = rgb(0, 100, 0); // зелёный
int Colors[3] = {Yellow, Red, Green};

// отклонение цвета
int Deviation[3][3];
Deviation[0][0] = 155; Deviation[0][1] = 155; Deviation[0][2] = 100; // для жёлтого
Deviation[1][0] = 155; Deviation[1][1] = 100; Deviation[1][2] = 100; // для зелёного
Deviation[2][0] = 100; Deviation[2][1] = 155; Deviation[2][2] = 100; // для красного

pause(500); // пауза чтоб кибор свернулся

// скрин поля
screen (#scr[0][0], coord_field[0], coord_field[1], coord_field[2], coord_field[3], -1);


// распознавание клеток
for(i=0; i<7; i++)
{
for(j=0; j<4; j++)
{
// получить количество цветов клетки
for(k=0; k<3; k++)
{
result[k] = sumcolor(-1, cellX * j + 5, cellY * i + 5, cellX * (j + 1) - 5, cellY * (i + 1) - 5,
Colors[k], 0, Deviation[k][0], 0, Deviation[k][1], 0, Deviation[k][2], #scr[0][0]);
}

// проверка какого цвета больше всего
if(result[0]>result[1] && result[0]>result[2]) lab[i][j] = 0; // жёлтый
else
{
if(result[1]>result[2]) lab[i][j] = 1; // красный
else lab[i][j] = 2; // зелёный
}
}
}


// вывод массива
for(i=0; i<7; i++)
{
string tmp = "";
for(j=0; j<4; j++) tmp = tmp + format(lab[i][j]);
textout(i, 200, 100 + i * 20, tmp, 0);
}
loop()sleep(10);
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« Вопросы и решение проблем »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 




Powered by