Как сделать?
…
Помогите, плиз, понять многомерные массивы. Я, возможно, глупая, но я так и не поняла для чего они. Я читала в справке о них, но так и не поняла. Пожалуйста, объясните зачем они нужны? Как их использовать? Для чего нужны значения, что находятся вместо номеров ячеек? Как их использовать?
Хотя, возможно, я пока замахнулась на слишком сложную тему для себя, поэтому не могу пока понять, но всё же хотелось бы хоть немного понять многомерные массивы
Многомерные массивы полезны в случае, когда какое-либо значение нужно связать не с одним значением, а с несколькими.
Например, если описание какого-то предмета зависит только от порядкового номера предмета (м.б. от его названия?), то это одномерный массив.
Если описание предмета зависит не только от номера предмета, а еще и от локации, где игрок находится, то это уже двухмерный массив (в этом случае предмет с одним порядковым номером может иметь разное описание в зависимости от локации).
Другой пример - у нас есть двухмерная карта с координатами. Тогда содержимое каждой ячейки будет зависеть от 2х координат - это двухмерный массив (как таблица).
Если добавить еще одно измерение (например, содержимое _каждой_ ячейки карты зависит от координаты Z или от другого обязательного параметра), то это будет 3х-мерный массив.
Измерений может быть много, главный критерий создавать их или нет - это от скольких/каких _обязательных_ параметров зависит значение каждого элемента массива.
В QSP с этим немного проще, т.к. в пределах одного массива одна ячейка может зависеть от любого числа параметров (какие-то значения могут быть для 1го, другие для 2х, и т.д.)
Использовать это просто - нужно вместо одного значения-индекса массива, указать несколько через запятую.
Установка значения:
$описание[x,y]='это описание для ячейки x,y'
Использование значения:
pl $описание[x,y]
! другой немного странный пример:
if $локация[x,y]='крыша': pl 'Вы находитесь на крыше высокого здания'
Значение ячейки может зависеть от значений разных типов:
$описание[x,y,$value]='это описание для ячейки по переменным x,y,$value'
$описание['test', x]='это описание для ячейки "test",x'
Конечно, в качестве индексов можно использовать значения из других массивов (то есть, не просто переменные/константы).
ShadowX2,
На мой взгляд самый простой способ понять многомерный массив можно на примере шахматной доски.
Есть некая “Длина” и некая “Ширина”. В шахматах это буквы: A,B,C,D,E,F,G,H и цифры 1,2,3,4,5,6,7,8. Каждая ячейка может быть или черная или белая, и в каждой ячейке у тебя может был какая-то фигура или ячейка пустая.
Тогда, классическая форма многомерного шахматного массива в КуСПе будет выглядеть примерно так (Условно):
$Доска['A',1,'Фигура']=$ЛадьяБел[1]
$Доска['A',1,'Цвет']='Черный'
$Доска['B',1,'Фигура']=$КоньБел[1]
$Доска['B',1,'Цвет']='Белый'
$Доска['С',1,'Фигура']=$СлонБел['Черный']
$Доска['C',1,'Цвет']='Черный'
$Доска['D',1,'Фигура']=$ФерзьБел
$Доска['D',1,'Цвет']='Белый'
$Доска['E',1,'Фигура']=$КорольБел
$Доска['E',1,'Цвет']='Черный'
$Доска['F',1,'Фигура']=$СлонБел['Белый']
$Доска['F',1,'Цвет']='Белый'
$Доска['G',1,'Фигура']=$КоньБел[2]
$Доска['G',1,'Цвет']='Черный'
$Доска['H',1,'Фигура']=$ЛадьяБел[2]
$Доска['H',1,'Цвет']='Белый'
....
$Доска['A',8,'Фигура']=$ЛадьяЧерн[1]
$Доска['A',8,'Цвет']='Белый'
$Доска['B',8,'Фигура']=$КоньЧерн[1]
$Доска['B',8,'Цвет']='Черный'
$Доска['С',8,'Фигура']=$СлонЧерн['Белый']
$Доска['C',8,'Цвет']='Белый'
$Доска['D',8,'Фигура']=$ФерзьЧерн
$Доска['D',8,'Цвет']='Черный'
$Доска['E',8,'Фигура']=$КорольЧерн
$Доска['E',8,'Цвет']='Белый'
$Доска['F',8,'Фигура']=$СлонЧерн['Черный']
$Доска['F',8,'Цвет']='Черный'
$Доска['G',8,'Фигура']=$КоньЧерн[2]
$Доска['G',8,'Цвет']='Белый'
$Доска['H',8,'Фигура']=$ЛадьяЧерн[2]
$Доска['H',8,'Цвет']='Черный'
Лично я стараюсь не использовать многомереки без необходимости. А разбиваю их на понятные одномерные, так проще воспринимать код.
Но, например, если некий предмет способен “переезжать” с локации на локацию и в пределах локации менять свое положение и оставаться там, пока кто-то не переместит его на другую, то в таких случаях можно хранить положение предмета в двумерном массиве.
Опять таки, надо понимать, что и как хранить. Мне проще хранить местонахождение предмета в свойствах самого предмета, или через динамический массив, где индекс массива - код предмета, а значение - локация. При больших массивах данных я привык пользоваться индексами. Каждый предмет, локация, непись (при необходимости) имеет свой уникальный индекс и через этот индекс они связываются.
Обычно я делаю функции-прокладки, которые могут из общего массива данных найти нужное и в любом количестве. Например для “Снаряжения” - по ID “Владельца” найти все Снаряжение, которое принадлежит данному Владельцу.
Доброго времени суток. Такой странный вопрос по предметам, а конкретно по $SELOBJ… Есть ли возможность выделить предметом кодом, через тот же act к примеру, без прямого клика игроком на предмет в инвентаре, чтобы выделить этот самый предмет?
И макро вопрос, как проверить есть ли предмет в инвентаре, а то я что-то в документации не могу найти енто самое.
n3m0,
Чесслово, тут надо дождаться гуру. Реально, не сильно в теме.
Я попробовал пользоваться стандартным набором инвентаря и понял, что он меня совершенно не устраивает. По сути он пустой, оболочка - не более. Можно добавить-убрать и по сути всё. Ни количества, ни других свойств. И я решил, что если все свойства надо хранить отдельно - то нахрена использовать? Я написал свой, сначала было кривовато, но терпимо (Старый пример лежит несколько страниц назад. https://qsp.org/forum/23-kak-sdelat?page=425). А теперь можно применять к любому количеству “предметов” с совершенно разными “внутренними структурами”.
Как проверить, есть ли среди предметов предмет, содержащий такое-то слово — я вот таким кодом пользуюсь:
i=1
yes_its_here=0
:ii
$currentObjectName=$getObj(i)
if instr($currentObjectName,$findname):
yes_its_here=1
end
if i < countObj or i = countObj:
i+=1
jump'ii'
end
n3m0, событие выделения предмета, согласно вики, только по клику мышью. Какая задача стоит? Возможно, можно решить другим способом.
mkir,
этот код обычно и используют.
Если поддержка игры не предполагается на 5.7.0, можно написать его на настоящем цикле, так код будет работать быстрее.
! $findname
yes_its_here = 0
loop local i = 1 while i <= countobj step i += 1:
if instr($findname, $getobj(i):
yes_its_here = 1
jump 'loop_end'
end
end
:loop_end
Но если такой поиск происходит в игре постоянно и часто, более быстрый вариант — это хранить названия предметов в массиве и производить поиск с помощью регулярного выражения по массиву:
pos = arrcomp($objnames, '*\bмеч\b*') & ! найдёт позицию первого предмета, содержащего слово "меч"
yes_its_here = iif(pos = -1, 0, 1)
! $findname не содержит спецсимволов и знаков пунктуации
pos = arrcomp($objnames, '*\b<<$findname>>\b*')
yes_its_here = iif(pos = -1, 0, 1)
Аааа. Я тут запутался в логике вопросов ответов. Это не Марк спрашивал.
n3m0,
да, поясни, пожалуйста, чего ты хочешь добиться? Тебе нужно выделить предмет визуально?
Некоторые вопросы по работе с предметами освещены тут: https://aleksversus.github.io/howdo_faq/docs/howdo/contents/items/add_item. Для плееров последних версий немного неактуальна информация по замене предметов в определённой позиции.
Просто во время писанины кода вспомнил что в куспе есть инвентарь, и хотел вспомнить как и что делать, но вот возник вопрос, можно ли как-то выделить предмет в инвентаре кодом, не зависимо от того кликал на предмет сам игрок.
По ходе изучения возникла идея, если бы можно было выделять предмет кодом, без клика игрока, можно было бы это использовать в тех или иных ситуациях. Да это даст то же самое что и поиск циклом, но наверное было бы удобнее. Да идея абсурдная, просто вот такое вот возникло пока штудировал вики, только и всего.