Thread: Keys in Order
View Single Post
  #8  
Old 01-14-2014, 04:43 PM
100Zero100 100Zero100 is offline
Registered User
Join Date: Jul 2006
Posts: 31
100Zero100 is on a distinguished road
Quote:
Originally Posted by Chompy View Post
Your code could be optimized further though, instead of having to do a loop at every keystroke the player does.

Also, there's no ending the loop if there's a match as far I as I see. Could have been left out intentionally though, I dunno. Combo build ups maybe?
Could it? I can't think of a way that you could avoid looping over the matches on every keystroke. I figured it was a small deal though -- a loop of about 3-4 arrays on a keypress seemed minor, but I agree -- if it can be done better, it should be!

I intentionally left out the 'end' on match -- not to have "multiple" combos in 1 stroke, but because I figure if you do 1 combo now, you probably want to do another combo in like 5 seconds.. but I did assume he wanted to have some kind of "delay" period. I left that all for him to decide in the "// Code triggers" portion.

How could you not loop over the array on every keystroke? I'm actually interested in that. I mean sure you can loop over every 3-4 keys or you could loop every 0.5 seconds (using .pos()>=0 instead of .ends()) up to the reset delay (in the first format).

But I figured all of those would feel a lot less responsive (you finish your combo, 0.5s later the script triggers after you've pressed 3 other keys) and it wouldn't give it all that much in efficiency.

I mean one thing you can do is if you planned on having all of your "combos" to be EXACTLY 4 characters, you could do something like:

(in the second format):

NPC Code:
//#CLIENTSIDE
const resetTime = 2;
const codeLength = 4;
function onCreated() {
this.codes = {
"qwerty",
"asdf"
"zxcv",
"etc1"
};
this.text = "";
}
function onKeyPressed(keycode, key) {
this.text @= key;
temp.testCode = text.substring(text.length() - codeLength - 1, codeLength);
if (testCode in this.codes) {
// Code triggers
}

scheduleEvent(resetTime, "remove");
}
function onRemove() {
this.text = this.text.substring(1);
}



And that seems like a slight gain in efficiency (since the loop over the array still happens (that's how 'in' works!) but in a hardcoded and more efficient manner.

I suppose you could even change "const codeLength" into "this.codeLengths = {length1, length2};" and loop an amount of times equal to your code lengths in the same manner, to keep looping down. In that scenario, you'd also want to partition your "combos" by code size, that way the script would loop only over the code-lengths relevant to your current size (eg, this.codes.3 = {"asd", "etc"}; this.codes.4 = {"qwer", "lolz"}.

In theory though that is definitely a gain in efficiency if you had like 20-50 combos that were all 3, 4, or 5 characters. It reduces looping to 1-3 loops rather than 20-50, and then it would need to sub-loop (via 'in' - hardcoded - more efficient) for the difference.

Still, even in that scenario, with the gain of efficiency there, having to edit like 3 arrays every time you want to add a combo is, in my opinion, not worth that trade-off.

Keep in mind, the goal isn't always to make the crazily most efficient script of the year. Sometimes you just want the script to be so clean, precise, and simple that any-old beginner could pop in and add his combo to the list, or whatever.

I will definitely admit that there are multiple approaches from this angle, with trade-offs between efficiency and editability. I still stand by my original claim that doing it the other way (keeping track of the character's position in each combo) is much worse: you would need 3 arrays (1 for the combos, 1 zeros-array equal in size to the first, and 1 keeping track of the player's current progress in each combo).

Were you referencing a more efficient way then I mentioned? If so, I would love to learn it!
Reply With Quote