Lua: String.match/string.gsub — регистр для true/false

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

У меня есть очень специфический сценарий для MUD, в который я играю, чтобы помочь мне различать мобов и игроков, когда они находятся в комнате. Сам скрипт работает, но теперь я хочу добавить новый элемент, который будет проверять, находятся ли мои одногруппники в одной комнате. Это то, что у меня есть до сих пор:

function strends(s)
  if s:match("%u%w+ is here%.") or s:match("%u%w+ is fighting .-%.") or s:match("%u%w+ is sleeping here%.") then
    return true
  else
    return false
  end
end

Это отлично работает — он проверяет, есть ли в комнате имя в верхнем регистре, и возвращает информацию по запросу.

У меня есть таблица моих товарищей по группе, хотя мне может быть проще сделать это в виде строки и выполнить string.find. Проблема, с которой я сталкиваюсь, заключается в том, что она подходит для каждого из сценариев:

  1. Вернуть true, если в комнате есть игроки не из моей группы.
  2. Верните true, если это только игроки вне моей группы.
  3. Вернуть false, если кроме меня в комнате никого нет.

В первом сценарии он ДОЛЖЕН вернуть true, даже если в моей группе есть люди, а также люди вне моей группы. Но мои знания Lua недостаточно обширны, чтобы я мог решить эту проблему. Причина неначала string.matches заключается в том, что перед конкретной строкой может быть xx символов. Как мне подойти к этому или что я должен делать, чтобы достичь своей цели?

Редактировать: Исправлен сценарий 2, потому что произошла ошибка. Вот что обычно приходит при осмотре комнаты:

Сценарий 1:

(R) NonGroupMate is sleeping here.
(W)(R)(T) Groupmate is here.

Ожидаемый результат?

return true -- the function checks if there are people outside my group in the room.

Сценарий 2:

(D)(W) NonGroupMate is fighting a mob!
(T)(W) NonGroupMateTwo is here.

Ожидаемый результат?

return true

Сценарий 3:

(T) GroupMate is here.
(W) GroupMateTwo is sleeping here.
GroupMateThree is fighting a mob!

Ожидаемый результат?

return false

Я надеюсь, что это поможет немного прояснить ситуацию. Если вам нужно больше, пожалуйста, дайте мне знать.

Дополнительные разъяснения

Я не имел в виду какое-то недопонимание. Я думал, что все вышеперечисленное было необходимо, но я попытаюсь сломать его.

Когда я набираю «look» в MUD, я вижу что-то похожее на следующее:

Room name
  Room Desc
  [ Exits: <exits> ]
  NameOne is here.
  (G) NameTwo is here.
  (R)(W) NameThree is sleeping here.
  (W) NameFour is fighting a mob.

У меня уже есть триггеры для сопоставления элементов сразу после [ Exits: ], и триггер срабатывает без проблем. Он оценивает каждую строку, как и предполагалось, и пропускает ее через функцию strends().

Проблема, которую я пытаюсь решить, заключается в создании функции, в которой она оценивает строку и определяет, находится ли имя игрока в моей группе или нет. Если они ЕСТЬ в моей группе, strends() должно вернуть false (поскольку strends() возвращает информацию о том, есть ли в комнате игроки, которых мне следует избегать). Если они НЕ в моей группе, то нужно вернуть true.

Вот что мне трудно понять; как мне создать функцию для этого? Что бы я действительно хотел, чтобы функция делала, так это то, что когда она определяет, что игрок, не входящий в группу, находится в комнате, она ломается и игнорирует все другие результаты. Я думаю, что для того, чтобы это произошло, мне нужно будет ввести их в таблицу и выполнить итерацию, чтобы я мог сломаться в любой момент. То, что я /могу/ в итоге сделать, это настроить условную переменную, которая в начале устанавливается в false, а при установке в true всегда остается истинной.

Теперь это яснее? Если нет, то я не уверен, что еще я могу добавить к этому.

Обновить

Вывод look не является одной строкой. По сути, каждая строка обрабатывается индивидуально, начиная с персонажей в комнате. Например:

NameOne is here. -- This is processed by itself, gets passed through strends.
NameTwo is sleeping here. -- This is also processed through strends, by itself.
NameThree is here. -- Yet again it's processed individually through strends.

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


person Josh    schedule 09.05.2015    source источник
comment
Если ваш вопрос касается сопоставления с образцом, приведите примеры ввода ожидаемого результата с кодом. Непонятно, что вы имеете в виду под если в комнате есть игроки не из моей группы или другие ситуации.   -  person Yu Hao    schedule 09.05.2015
comment
Я предполагаю, что ваш вопрос заключается в том, что причина неначала string.matches заключается в том, что конкретная строка может иметь перед ней xx символов. но я тоже этого не понимаю.   -  person Yu Hao    schedule 09.05.2015
comment
Точно. Предыстория интересная и потенциально полезная, но на ясном примере вы бы уже получили 10 ответов.   -  person Blindy    schedule 09.05.2015
comment
Лично я чувствовал, что вся необходимая информация по существу там, но я также приведу пару примеров. Извини за это!   -  person Josh    schedule 09.05.2015
comment
(R) NonGroupMate is sleeping here. и (W)(R)(T) Groupmate is here. хранятся в двух строках или в одной строке?   -  person Yu Hao    schedule 09.05.2015
comment
Кстати, мы действительно ожидаем, что это минимальный, полный и проверяемый пример.   -  person Yu Hao    schedule 09.05.2015
comment
Я надеюсь, что я сделал это более ясным, что я ищу. Я был вокруг SO некоторое время, поэтому я старался максимально минимизировать его.   -  person Josh    schedule 09.05.2015


Ответы (1)


В следующем коде я предполагаю, что вывод «look» представляет собой единственную строку с именем look_out.

look_out = [[
Room name
  Room Desc
  [ Exits: <exits> ]
  NameOne is here.
  (G) NameTwo is here.
  (R)(W) NameThree is sleeping here.
  (W) NameFour is fighting a mob.
]]

group_member = {NameOne=true, NameTwo=true}

function has_non_group(look_out, group_member)
  for name in look_out:gmatch("(%u%w+) is ") do
    if not group_member[name] then 
       return true
    end
  end
  return false
end

print(has_non_group(look_out, group_member)) --  true

group_member.NameFour = true
group_member.NameThree = true
print(has_non_group(look_out, group_member)) --  false

Я предполагаю, что имена начинаются с заглавной буквы, а за ними следует «есть». Самый простой способ исключить участников группы — создать набор group_member. Если есть хотя бы 1 член, не являющийся членом группы, он вернет true и false в противном случае.

person ryanpattison    schedule 09.05.2015
comment
look не обрабатывается как полная строка. Я обновил пост, чтобы указать это. Тем не менее, это весьма полезно и будет рассматриваться как альтернатива, если мне придется идти по этому пути. Спасибо! - person Josh; 10.05.2015