PDA

Просмотр полной версии : Работа с массивом. запись чтение


TAMBIK
04.09.2009, 18:00
как ?
правильно сделать надо ?

пример :

var
ItemBase:array[1..100] of integer;// создали массив
objectID:integer;
// при приходе пакета
begin
if FromServer and (pck[1]=#$21) and (ReadD(12)= itemID) then begin
// при условии
if условие then
// записать objectID в массив
objectID:=ReadD(8);
// как ЗАПИСАТЬ ?
// ЗАПИСЬ
//-------------------------------------------
// дальше чтение сравнение
// при условии
ЗАПИСЬ= 256// например
// выполнить что то

klemberg
04.09.2009, 18:39
var
ItemBase:array[1..100] of integer;// создали массив
objectID:integer;
i: integer; // номер ближайшего свободного элемента массива

procedure Init; //Вызывается при включении скрипта
begin
i:=1; // скрипт только стартанул,
// первый раз сохраняем objectID в первый элемент массива
end;


// при приходе пакета
begin
if FromServer and (pck[1]=#$21) and (ReadD(12)= itemID) then begin
// при условии
if условие then
// записать objectID в массив
objectID:=ReadD(8);

// как ЗАПИСАТЬ ?
ItemBase:= objectID; // да просто :)
inc(i,1); // но при данном алгоритме обязательно нужно увеличить i на единицу
// и следить за тем, чтобы i не было больше размерности массива, в нашем случае - 100\

end;
end;


sendMSG(IntToStr(ItemBase[1])); // для последнего ПХ, вывод содержимого первого элемента массива в окно лога.
end.



[I]Добавлено через 5 минут
это был первый вариант, при котором каждое значение objectID записывается в следующий по порядку элемент массива.


вариант второй, при котором каждое значение objectID записывается в первый свободный элемент массива:
var
ItemBase:array[1..100] of integer;// создали массив
objectID:integer;
i: integer;

procedure Init; //Вызывается при включении скрипта
begin
end;


// при приходе пакета
begin
if FromServer and (pck[1]=#$21) and (ReadD(12)= itemID) then begin
// при условии
if условие then
// записать objectID в массив
objectID:=ReadD(8);


for i:=1 to 100 do begin
if (ItemBase[i] == 0) then begin

// как ЗАПИСАТЬ ?
ItemBase[i]:= objectID; // да просто :)

Break; // прерываем дальнейший перебор массива.
end;
end;

end;
end;


sendMSG(IntToStr(ItemBase[1])); // для последнего ПХ, вывод содержимого первого элемента массива в окно лога.
end.



оба варианта - не более, чем примеры.
при обеих схемах рано или поздно массив заполнится и что тогда?

а если прийдт 15 пакетов с одинаковым значеним objectID, есть ли смысл хранить 15 одинаковых значений в массиве?

думай)

TAMBIK
04.09.2009, 19:37
а если прийдт 15 пакетов с одинаковым значеним objectID, есть ли смысл хранить 15 одинаковых значений в массиве?
как одинаковых есть условие
if условие then
ток одно значение objectID будит записоваться в массив
а как дальше
//-------------------------------------------
// дальше чтение сравнение
// при условии
ЗАПИСЬ= 256// например
// выполнить что то

klemberg
04.09.2009, 19:47
for i=1 to 100 do begin
if (ItemBase == 256) then begin // например

КактоОбработатьЭтоЗначение(ItemBase[i]);

end;
end;


[I]Добавлено через 7 минут
Но по-моему тебе нужно делать вот что:

var
ItemBase:array[1..100] of integer;// создали массив
objectID:integer;
i: integer;
flag: boolean;

procedure Init; //Вызывается при включении скрипта
begin
end;


// при приходе пакета
begin
if FromServer and (pck[1]=#$21) and (ReadD(12)= itemID) then begin
// при условии
if условие then
objectID:=ReadD(8);

flag:=false; // сбрасываем флажок


// ищем objectID в массиве
for i=1 to 100 do begin
if (ItemBase[i] = objectID) then begin

// текущий objectID уже есть в массиве, т.е. добавлять новый не надо.
// ставим флажок, который далее пропустит цикл поиска первого пустого значения и добавление в массив objectID
flag := true;

Break; // прерываем дальнейший перебор массива.
end;
end;


// нужно добавить текущий objectID в массив
if (flag = false) then begin

// ищем первый свободный элемент в массиве
for i:=1 to 100 do begin
if (ItemBase[i] = 0) then begin

// как только нашли - на его место пишем текущий objectID
ItemBase[i]:= objectID; // да просто :)

Break; // прерываем дальнейший перебор массива.
end;
end;
end;
end;
end;
end.

klemberg
04.09.2009, 19:54
дык, какой вопрос - таков и ответ :)
попробуем иначе:
//-------------------------------------------
// дальше чтение сравнение
// при условии
ЗАПИСЬ= 256// например
// выполнить что то



// дальше чтение сравнение


// запускаем перебор всех значений массива
for i=1 to 100 do begin

// при условии ЗАПИСЬ= 256// например
if (ItemBase[i] == 256) then begin // например

// выполнить что то
end;
end;

А если так?

alexteam
04.09.2009, 20:43
plugin_demo4 не в помощь ?

Добавлено через 7 минут
кстати... гдето я кидал 2 процедурки сторящие и удаляющие элементы в массиве со смещением...

Добавлено через 8 минут
во. нашел.
http://coderx.ru/showpost.php?p=35707&postcount=787
добавить еще такую функцию

Function ObjIdInArray(value:integer):integer;
var
i:integer;
begin
result := 0;
while (i < itemcount) and (itemarray[result] <> value) do inc(result);
end;

Существует ли значение в массиве (value = ObjId прочитаный с пакета. index : integer; )


index := ObjIdInArray(value); //лучше поуступать так. избегая повторного запуска цикла.
If index < itemcount then
//значение существует. его к примеру можно удалить вот так
GetItemIdAndMove(index) //индекс мы получили выше
else
//значение не существует, добавляем
additemtoarray(value)

ну и в этом духе

Добавлено через 1 минуту
проверка на превышение -
if itemcount >= 255 then ....

TAMBIK
05.09.2009, 22:07
спасибо вот это как раз
долго лазил по форуму смотрел как сделано в других
скриптах с массивом НО так как я в школе курил ток травку в коридорах то не понял нечего
может тема пригодится другим


var
ItemBase:array[1..100] of integer;// создали массив
objectID:integer;
i: integer;

procedure Init; //Вызывается при включении скрипта
begin
end;
// при приходе пакета
begin
if FromServer and (pck[1]=#$21) and (ReadD(12)= itemID) then begin
// при условии
if условие then
// записать objectID в массив
objectID:=ReadD(8);
for i:=1 to 100 do begin
if (ItemBase[i] == 0) then begin
// как ЗАПИСАТЬ ?
ItemBase[i]:= objectID; // да просто :)
Break; // прерываем дальнейший перебор массива.
end;
end;
end;
end;

мне не надо следить за количеством записаных objectID
и не надо следить за количеством вещей

поэтому как дополнить скрипт
тем что сказал alexteam
просьба при совете использовать значения из скрипта выше
Function ObjIdInArray(value:integer):integer;
var
i:integer;
begin
result := 0;
while (i < itemcount) and (itemarray[result] <> value) do inc(result);
end;

index := ObjIdInArray(value); //лучше поуступать так. избегая повторного запуска цикла.
If index < itemcount then
//значение существует. его к примеру можно удалить вот так
GetItemIdAndMove(index) //индекс мы получили выше
else
//значение не существует, добавляем
additemtoarray(value)

alexteam
05.09.2009, 23:16
Что ау ?

var
itemcount:integer;
itemarray:array[0..255] of integer;

Function GetItemIdAndMove(index:integer):integer;
var
i:integer;
begin
result := 0;
if index >= itemcount then exit;
result := itemarray[index];
i := index;
while i < itemcount -1 do
begin
itemarray[i] := itemarray[i+1];
inc(i);
end;
itemarray[i] := 0;
dec (itemcount);
end;

procedure additemtoarray(itemobjid:integer);
begin
itemarray[itemcount] := itemobjid;
inc(itemcount);
end;

Function ObjIdInArray(value:integer):integer;
var
i:integer;
begin
result := 0;
while (i < itemcount) and (itemarray[result] <> value) do inc(result);
end;

procedure Init; //Вызывается при включении скрипта
begin
itemcount := 0;

end;

procedure Free; //Вызывается при выключении скрипта
begin

end;


//основная часть скрипта
//вызывается при приходе каждого пакета если скрипт включен
begin

if FromServer
and (pck[1]=#$21)
and (ReadD(12)= itemID) then
begin
objectID := ReadD(8);
if ObjIdInArray(objectID) < itemcount then
begin // если вещь в массиве есть
end
else
begin // если вещи в массиве нет - добавляем.
additemtoarray(objectID);
end;
if itemcount = 255 then //Если массив вот вот лопнет - удаляем самую "старую" шмотку с аррая.
GetItemIdAndMove(0);
end;

end.

TAMBIK
15.09.2009, 10:59
как сосчитать в массиве предметы с определеными данными?
и как сравнить значения ?
1.sumitemID=сосчитать всего предметов в массиве с одиноковым itemID
2.sumMaxlvl=сосчитать предметов в массиве с одиноковым itemID и уровнем заточки Maxlvl
3. при равенстве значений sumMaxlv и sumitemID
выполнить: действие например STOP

TAMBIK
16.09.2009, 11:30
ДОБАВЬТЕ !!!!!!!!!!!!!!!!
const
max=80;
itemID=142;
Maxlvl=10;
var
BaseItems:array[1..max,1..10] of integer;

Amount:integer;
enchantLevel:integer;
sumitemID:integer;
sumMaxlvl:integer;
sumitemIDOID:integer;
sumMaxlvlOID:integer;
//...................
procedure ItemList;
var
i, j, k: integer;
ListSize: integer;
begin
j:=4;
ListSize:=ReadH(j);
for i:=1 to ListSize do
if (i<=ListSize) then begin
BaseItems[i,1]:=ReadH(j);
BaseItems[i,2]:=ReadD(j);
BaseItems[i,3]:=ReadD(j); //ItemID
BaseItems[i,4]:=ReadD(j);
BaseItems[i,5]:=ReadD(j); //Amount:
j:=j+4;
BaseItems[i,6]:=ReadH(j);
BaseItems[i,7]:=ReadH(j);
BaseItems[i,8]:=ReadH(j);
BaseItems[i,9]:=ReadD(j);
BaseItems[i,10]:=ReadH(j);//EnchantLevel
inc(j,30);// ФИНАЛ
end else for k:=1 to 10 do BaseItems[i,k]:=0;
sumitemIDOID:=GetsumitemID(itemID);// сколько предметов
end;

// СЧИТАЕМ ПРЕДМЕТЫ
//...................
procedure Resultenchant;
begin
sumMaxlvlOID:=GetsumMaxlvl(itemID,Maxlvl);// сколько предметов с itemID и Maxlvl=10
end;
// сколько предметов с itemID
//-------------------
function GetsumitemID(itemID:integer) : integer;
var
i : integer;
begin
for i:=1 to max do
if (BaseItems[i,3]=itemID) then begin
Amount:=BaseItems[i,5];
sumitemID:=sumitemID+ BaseItems[i,5];
//<<<<<=== ЧТО ТО НАДО

end;
end;
// сколько предметов с itemID и Maxlvl=10
//---------------------
function GetsumMaxlvl(itemID,Maxlvl:integer) : integer;
var
i : integer;
begin
for i:=1 to max do
if (BaseItems[i,3]=itemID) and (BaseItems[i,10]=Maxlvl) then begin
enchantLevel:=BaseItems[i,10];
sumMaxlvl:=sumMaxlvl+BaseItems[i,5];
//<<<<<=== ЧТО ТО НАДО
end;
end;
// при равенстве предметов с itemID и предметов сitemID и Maxlvl=10
//---------------------
//<<<<<=== ЧТО ТО НАДО
//========================
далее не важно

TAMBIK
16.09.2009, 11:53
alexteam,
я так для примера
насчет ошибок х..р с ними
что здесь делать . добавить
что нехватает
//<<<<<=== ЧТО ТО НАДО

alexteam
16.09.2009, 12:22
как то так.
result - результат функции.
его так же можно использовать как локальную переменную.

// СКОЛЬКО предметов с itemID
//-------------------
function GetsumitemID(itemID:integer) : integer;
var
i : integer;
begin
Result := 0; //В начале у нас 0 вещей.
for i:=1 to max do
if (BaseItems=itemID) then
inc(result, BaseItems[i,5]);
end;

// СКОЛЬКО предметов с itemID и Maxlvl
//---------------------
function GetsumMaxlvl(itemID,Maxlvl:integer) : integer;
var
i : integer;
begin
result := 0;
for i:=1 to max do
if (BaseItems[i,3]=itemID) and (BaseItems[i,10]=Maxlvl) then
inc(result, BaseItems[i,5]);
end;

[I]Добавлено через 2 минуты
кстати... рекомендации - называй переменные своими именами... ибо через неделю ты сам не разберешся в своем же скрипте %)
я про то что у тебя EnchantLevel так же Maxlvl ну и в этом духе..

alexteam
16.09.2009, 14:31
функции, если грубо = переменные


if func1(params1) < func2(params2) then

равносильно

value1 := func1(params1);
value2 := func2(params2);
if func1(params1) < func2(params2) then

вторая конструкция рекомендуеться к использванию если вызываемая функция содержит циклы либо какието сложные расчеты а функция ее вызывающая использует целевую несколько раз. (ибо лучше пожертвовать памятью чем цп)

TAMBIK
23.09.2009, 16:49
var
ItemBase:array[1..100] of integer;// создали массив
objectID:integer;
i: integer;

procedure Init; //Вызывается при включении скрипта
begin
end;
// при приходе пакета
begin
if FromServer and (pck[1]=#$21) and (ReadD(12)= itemID) then begin
// при условии
if условие then
// записать objectID в массив
objectID:=ReadD(8);
for i:=1 to 100 do begin
if (ItemBase[i] == 0) then begin
// как ЗАПИСАТЬ ?
ItemBase[i]:= objectID; // да просто :)
Break; // прерываем дальнейший перебор массива.
end;
end;
end;
end;
как мне на примере этого скрипта
добавить функцию чтения из массива objectID
т.е находим ячейку с записью № 1 objectID
провожу действия какие мне надо с objectID
при выполнение определенного условия :
искать запись № 2 также провожу действия и т.д

alexteam
23.09.2009, 18:07
12й пост поправить

Function ObjIdInArray(value:integer):integer;
var
i : integer;
begin
i := 0;
result := -1;
while (i < itemcount) do
begin
if itemarray[i] = value then
begin
result := i;
exit;
end;

inc(i);
end;
end;


использовать
var
itempos : integer;
begin
SearchItemPos := 0;

itempos := ObjIdInArray(itemobjectid, startpos);//получаем номер ячейки в массиве итемаррай с указаным обжектайди

if itempos <> -1 then //если номер ячейки не равен -1 т.е. ячейка была найдена
begin
blablabla с itemobjectid
end;

end;

pascalpwnz
24.09.2009, 21:32
а проще просто брать из массива
запись 1
запись 2
и т.д как это сделать?

эээм... бртаь из массива ? ну


begin

for i:=1 to 100 do
begin
if mas[i]=... then // i - номер записи
...
end;

end.

TAMBIK
25.09.2009, 10:17
мая твая не панимает...

брать запись не с чем не сравнивать и использовать.
записи последовательно должны использоваться.
когда мне надо я использую запись 1
потом запись 2
потом запись 3
и т.д

pascalpwnz
25.09.2009, 16:36
Ну так обращайся к записи по номеру mas[1] , mas[2] , mas[3] и делай что надо...

TAMBIK
16.10.2009, 10:35
BaseItems[i,1]:=ReadH(j);
BaseItems[i,2]:=ReadD(j);
BaseItems[i,3]:=ReadD(j); //ItemID
BaseItems[i,4]:=ReadD(j);
BaseItems[i,5]:=ReadD(j); //Amount:
j:=j+4;
BaseItems[i,6]:=ReadH(j);
BaseItems[i,7]:=ReadH(j);
BaseItems[i,8]:=ReadH(j);
BaseItems[i,9]:=ReadD(j);
BaseItems[i,10]:=ReadH(j);//EnchantLevel

в массиве есть
1. несколько одинаковых предметов
2. несколько разных предметов
с разными уровнями заточки.
Как найти минимально заточеный предмет для 1 случая и для 2 ?

alexteam
16.10.2009, 11:52
Function GetMinEnchantedItemByItemId(itemid : integer):integer;
var
i, MinFound : integer;
begin
minfound := $ffff;
result := -1;
i := 0;
while i < колличесвоэлементоввмасивеBaseItems do
begin
if (BaseItems[i,3] = itemid) and (BaseItems[i,10] < MinFound) then
begin
MinFound := BaseItems[i,10];
result := i;
end;
inc(i);
end;
end;

поиск минимально заточеного предмета по итемайди.
var
index : integer;
begin
index := GetMinEnchantedItemByItemId(itemid);
if index >= 0 then
begin
//используем BaseItems[index,1..10]
end;
end;
.... BaseItems[index,10] ?

TAMBIK
16.10.2009, 13:52
alexteam
спасибо !

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

alexteam
16.10.2009, 15:10
.... BaseItems[index,10] ?