ID:161289
 
var/i = lt.Insert("punch forward","kick reverse","punch reverse")
if(lt.Find(i))src<<"hoo"


My goal with this is, that punch forward, kick reverse and punch reverse have to be called after each other, but that it doesn't really matter in what possition it is in the list.

My question is, is that code good for my goal?
If not, could someone please give me it, or give me pointers?

Thank you for your time,

Rick
Sokkiejjj wrote:
My goal with this is, that punch forward, kick reverse and punch reverse have to be called after each other, but that it doesn't really matter in what possition it is in the list.

If you're trying to call things based on their text names, look up the call() proc in the DM Reference (F1 in DM). If you want a list of things to call, and you want to call everything in the list, loop through it and use call() in each iteration. Example:

mob
var/list/attack_sequence

verb
Set_Sequence() // Just a way to demonstrate various orders
var/i = input(src, "What sequence would you like?") in list(1,2,3)

switch(i)
if(1)
attack_sequence = list("punch","kick","jump")
if(2)
attack_sequence = list("jump", "punch", "kick")
if(3)
attack_sequence = list("kick", "jump", "punch")

Run_Sequence()
if(attack_sequence)
for(var/attack in attack_sequence)
if(hascall(src, attack))
call(src, attack)()
else
src << "You don't know how to '[attack]'!"
else
src << "Set a sequence first."

src << "<hr>" // divide messages

proc
punch()
src << "You punch."
kick()
src << "You kick."
jump()
src << "You jump."
In response to Kuraudo S.
I meant that those things may be like this:
mob/var/tmp/list/lt = list("punch 1","punch 2","punch 3" \
,"punch 4","punch 9","punch 2","punch 4","punch 1" \
,"punch 12")
var/i = lt.Insert("punch 2","punch 4","punch 1")
if(lt.Find(i))src<<"hoo"


It has to find punch 2, punch 4 and punch 1 in order.
But it doesn't matter if punch 2, punch 4 and punch 1 are in the start, middle or end of the list.

How do I do that?
In response to Sokkiejjj
Sokkiejjj wrote:
It has to find punch 2, punch 4 and punch 1 in order.
But it doesn't matter if punch 2, punch 4 and punch 1 are in the start, middle or end of the list.

I'm still not entirely sure what you mean, but I think that this snippet might demonstrate what you're talking about. It searches for a kick first, then a punch, then a jump, no matter what sequence you set it to.
mob
var/list/attack_sequence

verb
Set_Sequence() // Just a way to demonstrate various orders
var/i = input(src, "What sequence would you like?") in list(1,2,3)

switch(i)
if(1)
attack_sequence = list("punch","kick","jump")
if(2)
attack_sequence = list("jump", "punch", "kick")
if(3)
attack_sequence = list("kick", "jump", "punch")

Run_Fixed_Sequence()
if(attack_sequence)
var/found = ("kick" in attack_sequence)
if(found)
src << "You kick"
else
src << "No kick found!"

found = ("punch" in attack_sequence)
if(found)
src << "You punch"
else
src << "No punch found!"

found = ("jump" in attack_sequence)
if(found)
src << "You jump"
else
src << "No jump found!"

else
src << "Set a sequence first."

src << "<hr>" // divide messages
In response to Kuraudo S.
I appreciate your dire help, lol.
I'll try to explain it better.

Example:
I kick 1 the log and it gets added to lt list.
I kick 7 the log and it gets added to lt list.
I punch 3 the log and it gets added to lt list.

Note: the numbers behind the punches/kicks do not mean on what position it is in the list.

Now, while I've hit the log with kick 8, kick 12, kick 5, punch 5, punch 8, kick 1, kick 7, punch 3, kick 2 and punch 3.

Row: kick 8, kick 12, kick 5, punch 5, punch 8, kick 1, kick 7, punch 3, kick 2 and punch 3

Now I want to search for kick 1, kick 7 and punch 3, to combine a combo exp gain.

My goal is to search for those, put they've to be exactly kick 1, kick 7 and punch 3, but it doesn't matter where they're in the list, aslong kick 1, kick 7 and punch 3 are in order

I hope I made it clear now, and I am really sorry if I didn't and mess up your time. =/
In response to Sokkiejjj
I made a proc for you.
mob/verb/test()
var/pos = find_seq(list("kick 1", "kick 7", "punch 3"),list("kick 8", "kick 12", "kick 5", "punch 5", "punch 8", "kick 1", "kick 7", "punch 3", "kick 2", "punch 3"))
if(pos)
usr << "Found! Position: [pos]"
else
usr << "Not found"

proc
find_seq(var/list/l,var/list/L)
var/pos
while(L.Find(l[1],pos+1,0))
pos=L.Find(l[1],pos+1,0)
if(pos > L.len-l.len+1)
return 0
var/i
for(i=0,i<l.len && l[1+i]==L[pos+i],i++)
if(i==l.len-1)
return pos
return 0
In response to Jemai1
I think I could improve on that proc:
proc
find_seq(var/list/sequence,var/list/L)
var/pos=L.Find(sequence[1])
if(pos)
if(L.len<(sequence.len+pos))return FALSE
sequence-=sequence[1]
var/position
for(position=1;position<=sequence.len;position++)
if(sequence[position] != L[pos+position])
return FALSE
return pos
else
return FALSE
In response to Sokkiejjj
Sokkiejjj wrote:
I meant that those things may be like this:
> mob/var/tmp/list/lt = list("punch 1","punch 2","punch 3" \
> ,"punch 4","punch 9","punch 2","punch 4","punch 1" \
> ,"punch 12")
> var/i = lt.Insert("punch 2","punch 4","punch 1")
> if(lt.Find(i))src<<"hoo"
>

It has to find punch 2, punch 4 and punch 1 in order.
But it doesn't matter if punch 2, punch 4 and punch 1 are in the start, middle or end of the list.

How do I do that?

I take it you haven't actually looked up how to use Insert(). The format you have there is okay for Add(), but Insert() needs a number. The first argument to Insert() has to be the index where the values will be inserted.

The code you've put up there suggests you're trying to use the Insert() proc as a way of finding items in a list. That can't work, since Insert() is for changing a list, not searching it.

As for finding a sequence of numbers in a list, I'll give you a fairly straightforward search algorithm. Think about how you would go about finding the sequence yourself: You'd probably look for "punch 2" somewhere in the list, then see if the next item matches. This, then, is how you'd go about finding a sequence in a list:

proc/FindSequence(list/haystack, list/needle, start=1, end=0)
var/i,j,len
len = haystack.len - needle.len + 1
if(end <= 0 || end > len) end = len + 1
for(i=start, i<end, ++i)
if(haystack[i] != needle[1]) continue
for(j=1, j<needle.len, ++j)
if(haystack[i+j] != needle[j+1]) break
// match found?
if(j >= needle.len) return i
return 0


Using the built-in Find() proc, you could actually skip to the point you want in the list:

proc/FindSequence(list/haystack, list/needle, start=1, end=0)
var/i,j,len
len = haystack.len - needle.len + 1
if(end <= 0 || end > len) end = len + 1
i = haystack.Find(needle[1], start, end)
while(i)
for(j=1, j<needle.len, ++j)
if(haystack[i+j] != needle[j+1]) break
// match found?
if(j >= needle.len) return i
// no match
i = haystack.Find(needle[1], i+1, end)
return 0


Another option you have is the Boyer-Moore search, which is good if you're searching a large list; it performs even better when you're searching for a longer item. This is a modified Boyer-Moore algorithm that will find a sequence of strings in a BYOND list:

proc/FindSequenceBM(list/haystack, list/needle, start=1, end=0)
var/i,j,k,len
len = haystack.len - needle.len + 1
if(end <= 0 || end > len) end = len + 1
// make a copy of the search sequence so we can associate values with it
// this method won't work if the haystack/needle lists contain raw numbers.
var/list/offset = new
for(i=needle.len, i>0, --i)
if(isnull(offset[needle[i]]))
offset[needle[i]] = needle.len - i
/*
Now do the search; the Boyer-Moore search starts at the end of the possible
match and works backwards, using the associated values we worked out as a
number of positions to skip ahead by.
*/

i = start + needle.len + 1
j = needle.len
k = i
end -= needle.len
while(i < end)
if(haystack[i] == needle[j])
// match found?
if(--j <= 0) return i
--i
continue
// find amount to skip ahead
var/off = offset[haystack[i]]
if(isnull(off)) off = needle.len
else if(!off) off = 1
// always skip ahead at least 1 unit from last position
i = max(i+off, k+1)
j = needle.len
k = i
return 0


I implemented a Boyer-Moore variant in my Blankless program, because it's a good algorithm for searching large blocks quickly. Whether it will serve you quite as well, I'm not sure; for your purposes probably the simpler sort will do.

Lummox JR