Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Написание игр _ Хелп ми плиз With Lines

Автор: Falcon 00*5 18.11.2006 13:38

Срочно нужны исходники игры Lines , это которая шарики и все такое.. Сам сделал процентов на 40 , но хотелось бы еще увидеть ваши варианты, может быть у кого то уже есть эта игра?

Автор: XaMMaX 18.11.2006 16:33

Плиз мне тоже оч нужны! а то не знаю по какому алгоритму проверять соответствия что бы это было не очень ресурсо ёмко!

Автор: Michael_Rybak 18.11.2006 16:44

Какие такие соответствия?

Автор: XaMMaX 18.11.2006 16:48

Ну ээ... lol.gif может я не правильно понимаю игру lines dry.gif Там вроде в ряд должно совпасть и я говорю о проверки совпало или нет =) Наверное я чего-то путаю

Автор: Michael_Rybak 18.11.2006 18:27

Проверить совпало или нет очень просто. Идешь по строкам-столцам-диагоналям да проверяешь. Примерно так:


//не проверял

const dx: array[0..2] of integer = (1, 1, 0);
const dy: array[0..2] of integer = (0, 1, 1);

var a: array[1 .. 10, 1 .. 10] of integer; //поле: 0 если пусто, цвет шарика если шарик

...

procedure FindLines()

var will_delete[1 .. 10, 1.. 10] of boolean; //здесь будем отмечать все шарики, которые пропадут за ход
i, j, dir, k, len, color: integer;

begin

for i := 1 to 10 do
for j := 1 to 10 do
will_delete[i, j] := false;

for i := 1 to 10 do
for j := 1 to 10 do
for dir := 0 to 2 do begin //направление: вправо, по диаголи или вниз

len := 1;
color := a[i, j];
if color = 0 then
continue;

//идем по направлению, пока не вылезем за поле/не встретим другой цвет
while (i + len * dy[dir] <= 10) and (j + len * dx[dir] <= 10) and
(a[i + len * dy[dir], j + len * dx[dir]] = color) do
Inc(len);

if (len >= 5)
for k := 0 to len - 1 do
will_delete[i + k * dy[dir], j + k * dx[dir]] := true;

end;


for i := 1 to 10 do
for j := 1 to 10 do
if will_delete[i, j] then
a[i, j] := 0;

end;


Автор: XaMMaX 18.11.2006 20:43

Не чень мне понятно:


for i := 1 to 10 do
for j := 1 to 10 do
for dir := 0 to 2 do begin //направление: вправо, по диаголи или вниз

len := 1;
color := a[i, j];
if color = 0 then
continue;

//идем по направлению, пока не вылезем за поле/не встретим другой цвет
while (i + len * dy[dir] <= 10) and (j + len * dx[dir] <= 10) and
(a[i + len * dy[dir], j + len * dx[dir]] = color) do
Inc(len);

if (len >= 5)
for k := 0 to len - 1 do
will_delete[i + k * dy[dir], j + k * dx[dir]] := true;

end;


И чего за dir ? Для чего он? Оргаментируй там каждую строчку плиз, а то я тупой очень(само критика рулит) =) И ты уверен что твой способ не ресурсо ёмкий? мои рамки сильно ограничены =(

Автор: XaMMaX 18.11.2006 20:54

Да и как сделать что бы после нажатия на шарик он мог вставать только на пустой квадрат К КОТОРОМУ НЕ ЗАКРЫТ ПУТЬ? Оч интерестно =\

Автор: Michael_Rybak 18.11.2006 21:37

Цитата
И чего за dir ? Для чего он?

Алгоритм такой. Берем каждую непустую клетку, и от нее пытаемся идти до упора вправо, пока не встретим шарик другого цвета, или не упремся в границу поля. Потом проверяем, что длина найденного ряда шариков одинакового цвета больше или равна пяти, и если это так - удаляем (точнее не удаляем, а запоминаем, что их надо в конце удалить, т.к. ряды могут пересекаться).

Потом делаем то же самое, но идем не вправо, а по диагонали. А потом - вниз. Переменная dir задает направление движения, определяемое смещением dy[dir], dx[dir]. Когда dir = 0, получается dx = 1, dy = 0, т.е. движемся вправо. И т.д.

Цитата

И ты уверен что твой способ не ресурсо ёмкий? мои рамки сильно ограничены =(

Этот способ не самый оптимальный, но летать будет даже на Поиске.

Автор: XaMMaX 18.11.2006 21:48

Этот способ не самый оптимальный, но летать будет даже на Поиске.
-----
Дело в том что игру разрабатываю не для PC , а для GP2X(да есть такая вещь) =) И хочется опитимизировать хорошенько чтобы мощности и для эффектов+музыки осталось =Р

Так как на счёт второго вопроса? "Да и как сделать что бы после нажатия на шарик он мог вставать только на пустой квадрат К КОТОРОМУ НЕ ЗАКРЫТ ПУТЬ? Оч интерестно =\" Без этого у меня игра не получится =(

Автор: Falcon 00*5 18.11.2006 23:39

О! Пасиба за идею , мне она тоже потребуется... а все таки? каких нить заготовок нет ни у кого?

Автор: XaMMaX 18.11.2006 23:53

Присоединяюсь ибо не понимаю как опредилить закрыт ли путь к клетке? (см. мой предидущий вопрос) Оч надо срочно =(

Автор: Michael_Rybak 19.11.2006 6:37

Цитата
хочется опитимизировать хорошенько
давай ты так сначала попробуешь, а там поговорим ;)

Цитата
К КОТОРОМУ НЕ ЗАКРЫТ ПУТЬ


Это делается поиском в ширину. Смотри. У тебя есть клетка, на которой стоит клацнутый шарик. Делаем копию поля, пока что всем клеткам ставим статус 0 (не посещена), а начальной - 1 (посещена), и помещаем ее в очередь. Дальше, пока очередь не пуста, берем из нее клетку, и смотрим на каждого из ее четырех соседей. Каждую соседнюю клетку, которая 1) находится в пределах поля, 2) не содержит шарик и 3) имеет статус 0, мы помещаем в очередь и присваиваем статус 1.

В конце получится, что статус 1 имеют все достижимые клетки, 0 - остальные.

Автор: XaMMaX 19.11.2006 14:01

Блин звучит разумно только не очень понятно =( Можно что ли рисунок не большой? Или код ?

Автор: Michael_Rybak 19.11.2006 17:00

Короче тебе в любом случае надо не только узнавать, можно ли дойти до клетки, но и находить, собственно, сам путь.

Вот тебе урла: http://www.firststeps.ru/theory/karta.html

Вот оттуда картинка:

Изображение

На пальцах: ставим в начальную клетку нолик. Теперь в каждую пустую клетку, соседствующую с ноликом, ставим единицу. Теперь в каждую пустую клетку, соседствующую с одной из единиц, ставим двойку и т.д.

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

По окончании "волн" число в клетке будет обозначать минимальное количество ходов до нее.

Так вот. Когда юзер клацает на шарике, который надо мувать, ты пускаешь такую "волну" до упора, и запоминаешь ее. Потом, когда юзер клацнул в клетку, в которую надо перейти - смотришь, дошла ли туда волна. Если волна не дошла - значит, нельзя туда попасть. Если же дошла - нам надо восстановить путь. Делаем это с конца. Пусть в целевой клетке стоит число 14 (как на картинке). Это значит, что мы дошли туда за 14 "волн". И это значит, что где-то рядом стоит число 13! Перебираем четырех соседей, идем туда, где 13. Теперь то же самое: где-то рядом есть 12, идем туда. Теперь дальше: где-то рядом есть 11. Видим, что есть 2 клетки, в которых 11 - не страшно, идем в любую, ведь любая из них достижима из начальной за 11 ходов. И так далее.

Автор: XaMMaX 19.11.2006 17:21

Хм да это уже понятнее =) Надо только код сформулировать mega_chok.gif Попробую если не получистя ещё приду!

Автор: Michael_Rybak 19.11.2006 18:41

Приходи, приходи smile.gif

Автор: XaMMaX 19.11.2006 19:18

Блин чё то я не врубаюсь как код сделать! Хелп!

Автор: Michael_Rybak 19.11.2006 19:46

Ну как это - не врубаешься? Идею понял? Понял. Значит врубишься ;)

Сделай массивы x, y: array[1..100] of integer, и n: integer - счетчик, который будет обозначать количество пронумерованных клеток. Идешь по массиву, обрабатываешь.

Или гугли "волновой алгоритм" - кода там полно

Автор: XaMMaX 19.11.2006 20:58

Хм можно всё же пример ни как не получается =( В гугле тоже батва всякая вылезает =( Пожалуйста оч надо! Ну никак не пойму как это реализовать хотя идею вроде понял

Автор: XaMMaX 24.11.2006 21:57

У меня вопрос по проверки приведённой тобой! Значит ты проверяеш спереди, снизу и между? Значит диогональ может совпасть только если она идёт от начала и вниз =( Или я чего-то не понимаю?

Автор: Michael_Rybak 24.11.2006 22:15

Опа, действительно бага.
Надо добавить еще одно направление, по другой диагонали

Автор: XaMMaX 24.11.2006 22:25

Да ещё на счёт Inc(len); я не понял это типа len= len+1 ?

Автор: Michael_Rybak 24.11.2006 22:38

Угу

Автор: XaMMaX 24.11.2006 22:43

Как бы переделать получше код?

Автор: Michael_Rybak 24.11.2006 22:49

Разберись и сразу поймешь ;)

Автор: XaMMaX 24.11.2006 23:08

Так что ли?


const dx: array[0..2] of integer = (1, 1, 0,-1);
const dy: array[0..2] of integer = (0, 1, 1,-1);


Автор: Michael_Rybak 25.11.2006 2:18

Цитата(XaMMaX @ 24.11.2006 18:08) *

Так что ли?

const dx: array[0..2] of integer = (1, 1, 0,-1);
const dy: array[0..2] of integer = (0, 1, 1,-1);




Почти.
(-1, -1) - это то же самое, что (1, 1).

Надо (1, -1).

Кроме этого, надо увеличить размерность массива (0..3) и цикл для dir от 0 до 3.

И еще надо проверять теперь не только то, что x<=10 и y<=10, а и то, что y >= 1

Автор: XaMMaX 25.11.2006 15:44

О дело идёт к концу жду не дождусь когда скажу тебе огромное спасибо =)

Автор: Michael_Rybak 25.11.2006 16:53

Цитата(XaMMaX @ 25.11.2006 10:44) *

О дело идёт к концу жду не дождусь когда скажу тебе огромное спасибо =)


Отлично smile.gif

Автор: Falcon 00*5 21.12.2006 2:59

Люди! Помогите с волновым алгоритмом! ПЛZ!Уже второй день мучаюсь ! есть массив 9x9 есть точка х1у1 с которой начинать отсчет и точка ху до которой надо дойти.... как мне его сделать ??? функцией если можно.... мои наработки вот :

function volna(a:mas; x1,y1,x,y:integer):integer;
var b:mas; i,j:integer; ni,nk:integer; rez:integer;
begin
ni:=0;nk:=81;rez:=0;
for i:=1 to 9 do
for j:=1 to 9 do begin
if a[i,j]=0 then b[i,j]:=254;
if a[i,j]>0 then b[i,j]:=255;
if (i=x1) and (j=y1) then b[i,j]:=253;
if (i=x) and (j=y) then b[i,j]:=0;
end;

repeat
for i:=1 to 9 do begin
for j:=1 to 9 do begin
if b[i,j]=ni then begin
if b[i+1,j]=254 then b[i+1,j]:=ni+1;
if b[i+1,j]=253 then begin volna:=1;exit;end;
if b[i-1,j]=254 then b[i-1,j]:=ni+1;
if b[i-1,j]=253 then begin volna:=1;exit;end;
if b[i,j+1]=254 then b[i,j+1]:=ni+1;
if b[i,j+1]=253 then begin volna:=1;exit;end;
if b[i,j-1]=254 then b[i,j-1]:=ni+1;
if b[i,j-1]=253 then begin volna:=1;exit;end;
end;
end;inc(ni);
end;
until ni<=nk;
end;

Но только почему то не работает .... результат работы функции не 1 или 0 а 3 или даж 254 ... не понимаю(((