Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> игра "точки" -> помогите с заливкой 
:(
    Опции темы
Immortal
Дата 17.8.2003, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 15.8.2003

Репутация: нет
Всего: нет



Конечно спасибо огромное за совет, но есть онда меленькая проблемка smile.gif я с ассемблером както не очень-то, если не трудно напиши как это будет выглядеть. Только оставь имя массива без изменений.

Буду благодарен. smile.gif
PM MAIL ICQ   Вверх
p0s0l
Дата 18.8.2003, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Т.к. я не знаю структуру твоего массива, то сам подправишь:
Код
const
 MaxWidth     = 256;  // максимальный размер поля
 MaxHeight    = 256;

type
 Ttmp         = record
   param      : byte; // param обязательно д.б. первым, иначе надо менять _ParamOfs!
   a          : integer;
   b          : byte;
 end;
 TtmpArray    = array [0..MaxWidth-1, 0..MaxHeight-1] of Ttmp;

var
 tmpArray     : TtmpArray;

const
 _ElementSize = SizeOf(Ttmp); // размер одного элемента массива
 _ColumnSize  = _ElementSize*MaxHeight; // размер колонки
 _ParamOfs    = 0; // смещение к полю param
 _StackSize   = MaxWidth * MaxHeight * 4 * 4 + 1024; // размер стека (на каждую ячейку 4 просмотра * 4 байта)

/////////////////////////////////////////

procedure asmEnemy3; assembler;
// esi = адрес ячейки
// ebx, ecx, edx, ebp - смещения для просмотра соседних четырех ячеек поля
// edi = отрицательная сумма ebx+ecx+edx+ebp
// al  = 0 (пустая ячейка)
// ah  = 1 (чем заливается)
asm
 mov byte ptr [esi], ah

 add esi, ebx
 cmp byte ptr [esi], al
 jnz @Check1
 call asmEnemy3

@Check1:
 add esi, ecx
 cmp byte ptr [esi], al
 jnz @Check2
 call asmEnemy3

@Check2:
 add esi, edx
 cmp byte ptr [esi], al
 jnz @Check3
 call asmEnemy3

@Check3:
 add esi, ebp
 cmp byte ptr [esi], al
 jnz @Check4
 call asmEnemy3

@Check4:
 add esi, edi // восстановили esi
 ret
end;

procedure Enemy3 (x, y : integer); assembler; register; // eax = x, edx = y
asm
 pushad

 push eax
 mov eax, _ElementSize
 mul edx
 mov esi, [_fld]
 lea esi, [esi + eax + _ParamOfs]
 pop eax
 mov ecx, _ColumnSize
 mul ecx
 add esi, eax

 xor eax, eax
 mov ah, 1 // чем заливаться будет
// смещения для просмотра соседних ячеек поля
 mov ebx, _ElementSize
 mov ecx, -_ElementSize*2
 mov edx, _ElementSize + _ColumnSize
 mov ebp, -_ColumnSize*2
 mov edi, _ColumnSize // для восстановления esi
 call asmEnemy3

 popad
 ret
end;

Надо вызывать Enemy3.



--------------------
С уважением, г-н Посол.
PM   Вверх
Immortal
Дата 18.8.2003, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 15.8.2003

Репутация: нет
Всего: нет



p0s0l спасибо тебе за помощь, но он чёй-то говорит, что не знает, что такое _fld в функции Enemy3, если не трудно посмотри. smile.gif
PM MAIL ICQ   Вверх
p0s0l
Дата 18.8.2003, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Ага, там надо вместо mov esi, [_fld] поставить lea esi, [tmpArray]...



--------------------
С уважением, г-н Посол.
PM   Вверх
Immortal
Дата 18.8.2003, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 15.8.2003

Репутация: нет
Всего: нет



asm'овская заливка в среднем на небольших захватах работает в 2-3 раза быстрее, это очень даже не плохие результаты, но последняя просьба smile.gif в координатах Enemy3 ты использовал тип Integer, это мне не надо, я подставляю smallint предварительно поменяв в разамере стека из 4 на 2 байта на каждую ячейку (надеюсь я не ошибаюсь smile.gif ). Но мне хватает и Byte, а при подстановки типа он выдаёт ошибку. Конечно если не трудно помоги, но в общем большое спасибо smile.gif
PM MAIL ICQ   Вверх
p0s0l
Дата 18.8.2003, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Про стек - убери вообще эту константу (_stacksize). Это атавизм - нужен был для проверки больших площадей, чтобы не было stack overflow.
Для byte надо изменить начало Enemy3:
Код
procedure Enemy3 (x, y : byte); assembler; register; // al = x, dl = y
asm
 pushad

 push eax
 mov eax, _ElementSize
  {!!!} mul dl
 lea esi, [tmpArray]
 lea esi, [esi + eax + _ParamOfs]
 pop eax
  {!!!} movzx eax, al
 mov ecx, _ColumnSize
 mul ecx
 add esi, eax


Мне интересно узнать: какую область ты заливаешь, например, в таком случае (точку поставят на место плюса):
_ _ 2 2 2 _ _ _ (4 области)
_ 2 _ _ _ 2 _ _
2 _ 2 _ 2 _ 2 _
2 _ _ + _ _ 2 _
2 _ 2 _ 2 _ 2 _
_ 2 _ _ _ 2 _ _
_ _ 2 2 2 _ _ _

или в таком упрощенном варианте:
_ 2 _ 2 _ (2 области)
2 _ + _ 2
_ 2 _ 2 _

И как ты находишь точку внутри захваченной области ? Ведь область может быть какой-нибудь извилистой ?

Это сообщение отредактировал(а) p0s0l - 18.8.2003, 17:30


--------------------
С уважением, г-н Посол.
PM   Вверх
Immortal
Дата 18.8.2003, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 15.8.2003

Репутация: нет
Всего: нет



В 1 примере я область не заливаю вообще так как она уже залита раньше, а во втором примере от этой точки по алгоритму А* я ищу все кротчайшие пути в эту же точку smile.gif
Но есть интересная особенность путь продолжается искаться не до прохода в начальную точку, а до соприкосновения с другим путём например:

1 * * * * * * *
* 1 * * * 4 * *
* * 1 * 4 * 4 *
* * * + * * * 3
* * 2 * 3 * 3 *
* * 2 * * 3 * *
* * * 2 3 * * *

В данном случае + это начальная точка а цифры это пути: когда 3 встречается с 4, то считается, что 3-4 пстреча уже есть, в дальнейшем если 3 и 4 ещё встретятся это за замкнутость считаться не будет.
Затем 2 встречается с 3 это происходит первый раз и поэтому русуется замкнутость.
путь 1 не встечается не с кем и замкнутость не образует.

И начсёт точки внутри. Т. к. я ищу только кротчайшие пути, то получается следующее.

* * 2 2 2 * *
* 2 * * * 2 *
* 2 * * о 2 *
* * 2 2 2 * *
* * * * * * *

Я нахожу из всего массива точек замкнутости две которые имеют наибольшую симму координат в данном случае это две нижних правых точки. И беру от них минимальный Х и минимальный Y и получаю координату точки о.

* * 2 2 2 * *
* 2 * * * 2 *
* 2 * * о 2 *
* * 2 2 2 2 *
* * * * * * *

единственный случай когда это не срабоет, но он невозможен, так как путь ищется самый короткий, а самая ижняя левая двойка будет добавлять одно лишнее звено.

Если будут ещё вопросы спрашивай, мне будет даже интересно поделиться опытом

PM MAIL ICQ   Вверх
p0s0l
Дата 18.8.2003, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Метод интересный, только это быстро работает ?
Если хочешь, то я тебе кину еще одну asm-функцию Enemy4 (люблю оптимизировать и ускорятьsmile.gif ).
Функция:
1) ищет и заливает незалитые замкнутые области автоматически (не надо давать точку внутри области)
2) возвращает кол-во новых залитых ячеек

Т.е. так искать пути, области и точки внутри областей не нужно.

Но если у тебя все работает быстро, то тогда лучше оставь как есть, т.к. эта функция работает медленнее:
если Enemy3 у меня в среднем 0,1..0,5 мс, то Enemy4 - 1..2 мс...
Особенно заметна разница на маленьких площадях, т.к. Enemy4 проверяет всё поле.

Если чо, дак сообщи в PM.


--------------------
С уважением, г-н Посол.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0482 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.