Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.01.2011, 10:58
Fenia Fenia вне форума
Прохожий
 
Регистрация: 02.01.2011
Сообщения: 12
Репутация: 10
По умолчанию Алгоритм

Здравствуйте. прошу подсказать мне не рекурсивный алгоритм: надо закрасить определенным цветом клетку DrawGrid'a и все клетки, такого же цвета, которые располагаются рядом с выделенной клеткой. например, если мы имеем DrawGrid 20на20 элементов и все они красного цвета и начинаем закрашивать одну клетку зеленым цветом, то закрасится весь DrawGrid, т.к. все элементы одинакового цвета и находятся рядом с выделенной кнопкой, либо соединены с ней клетками такого же цвета. конечно мог бы воспользоваться и рекурсией, но в делфи она не работает, по видимому переполнение стека)
Ответить с цитированием
  #2  
Старый 10.01.2011, 13:41
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
конечно мог бы воспользоваться и рекурсией, но в делфи она не работает, по видимому переполнение стека)
Даже в самом худшем варианте при DrawGrid 20x20 (т.е. 400 элементов), если передавать в процедуру координаты клетки в integer (Хотя достаточно байта), и два цвета (что красим и чем красим, хотя можно использовать глобальные переменные), прогрузить стек можно только на 400*16 = 6400 байт. По идеи такое стек не переполнит. Так что скорее всего там ошибка.

Вообще в теории можно любой рекурсивный алгоритм записать циклом.
Еще есть например алгоритм закраски строками, правда не помню, как называется. Там вообще почти никакой нагрузки на стек не будет.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #3  
Старый 10.01.2011, 13:47
Fenia Fenia вне форума
Прохожий
 
Регистрация: 02.01.2011
Сообщения: 12
Репутация: 10
По умолчанию

ну суть в том, что рекурсией у меня не получилось. хотя я и не задумывался об этом варианте серьезно. написал на скорую руку рекурсию, результат - стэк переполнен. а вот в цикле такое организовать я просто не представляю как. есть какие-то мысли, но они настолько трудны, что я не представляю как это написать прошу помощи. программа готова, осталось только это( сдавать послезавтра
Ответить с цитированием
  #4  
Старый 10.01.2011, 14:41
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Например можно попробовать так:
Начинается цикл. Текущую клетку (координаты X и Y) закрашиваем. Смотим соседа слева (если имеется таковой).
Если его цвет нужный, то в массив (самодельный стек) заносим например 0 (чтоб знать что пришли слева), потом X уменьшаем на 1. Если же цвет не тот или нет соседа слева - аналогично для права, потом верха и потом низа, только заносить будем соответственно 1, 2 или 3.
Следующий проход цикла - имеем новые координаты, и делаем все то же для них.
Если у N-ной клетки не оказалось соседей - берем из массива направление, откуда пришли, и возвращаемся по нему, не выполняя сравнения для тех сторон, которые уже были (если например вернулись с цифрой 2, значит остается сравнить только для направления 3).

Как-то так. Довольно сложная комбинация IF-ов. Проще рекурсией.
Код:
procedure Paint(x,y:byte);
begin
 //с DrawGrid не работал, не знаю как он там внутри устроен, напишу для массива.
 a[x,y]:=Color2;
 
 if x<Nx-1 then
  if a[x+1,y] = color1 then 
   Paint(x+1,y);
 if x>0 then
  if a[x-1,y] = color1 then
   Paint(x-1,y);

 if y<Ny-1 then
  if a[x,y+1] = color1 then 
   Paint(x,y+1);
 if y>0 then
  if a[x,y-1] = color1 then
   Paint(x,y-1);
end;
По идеи так не должно слетать. Стек прогружается одним вызовом на 6 байт, для DrawGrid 20x20 максимум будет 2400 байт.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #5  
Старый 10.01.2011, 15:12
Fenia Fenia вне форума
Прохожий
 
Регистрация: 02.01.2011
Сообщения: 12
Репутация: 10
По умолчанию

я думаю, этот алгоритм будет закрашивать только клетки которые находятся слева, справа,сверху,снизу на любой длине от основной клетки в пределах поля. а как же клетки, которые могут находится справа сверху. т.е. если клетка справа нам подходит по цвету и при этом клетка сверху от правой подходит по цвету, то нам надо закрасить и клетку, которая сверху от правой. а этот алгоритм разве будет это делать?
Ответить с цитированием
  #6  
Старый 10.01.2011, 15:49
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Будет. Для КАЖДОЙ соседней клетки проверяется соответствие клеток слева, справа, сверху и снизу.
Только что запускал в паскале для массива 20х20. все работает нормально.

Да, предварительно лучше сделать проверку, что Color1<>Color2, иначе точно будет переполнение стека.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 10.01.2011 в 15:53.
Ответить с цитированием
  #7  
Старый 11.01.2011, 19:21
Fenia Fenia вне форума
Прохожий
 
Регистрация: 02.01.2011
Сообщения: 12
Репутация: 10
По умолчанию

да такая проверка есть. сам алгоритм проверить пока нету возможности) как проверю - отпишу) заранее спасибо
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 14:07.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter