If and else statements in zmud.

by Unknown

Back to Mechanic's Corner.

Unknown2006-02-18 22:26:15
So I know zMUD can do if statements with #if, but can it do if else, else if etc.? I have not been able to find any such thing. Remaking my Lusternia system from scratch and going for mostly automated but having lots of huge #if statements as the most obvious way to do it would probably lag the system and I'm wishing there was some else stuff somewhere...
Soll2006-02-18 22:41:00
#if (condition) {then} {else}
Unknown2006-02-18 22:44:46
Thanks dood. Still, that only goes two ways, I was hoping to make a really long list of if, else, else, else, else, on into eternity until I ran out of afflictions.
Unknown2006-02-18 22:48:25
Nest them.
Soll2006-02-18 22:57:38
Example.

CODE

#if (@caneatherbs) {#if (@stupid) {outb pennyroyal;eat pennyroyal} {#if (@slick) {outb calamus;eat calamus}}}}
Unknown2006-02-18 23:39:36
QUOTE(Soll @ Feb 18 2006, 10:57 PM) 259966

Example.

CODE

#if (@caneatherbs) {#if (@stupid) {outb pennyroyal;eat pennyroyal} {#if (@slick) {outb calamus;eat calamus}}}}

Wouldn't the above example try to eat both pennyroyal and calamus at once if you had both? And what's nesting?
Soll2006-02-19 00:17:12
Nesting is setting #IFs inside each other, as I did there.


No, that would not eat both pennyroyal and calamus. The 'if (@slick) {outb calamus;eat calamus}' would only fire if not stupid. It works as follows:

#if (@caneatherbs) {IF CAN: #if (@stupid) {IF STUPID: outb pennyroyal;eat pennyroyal} {IF NOT STUPID: #if (@slick) {IF SLICK: outb calamus;eat calamus}}}}


Totally not your fault, but I wanna f---ing kill you right now. Blargh. I just typed up a totally awesome new thread, copied it because it failed to post initially, went to redo the thread and came across this. Then my keys started acting up so I had to copy some of your post, over-writing my awesome and long post. Grrr. My beautifully failed thread: This.
Unknown2006-02-19 00:50:32
QUOTE(Soll @ Feb 19 2006, 12:17 AM) 259996

Nesting is setting #IFs inside each other, as I did there.
No, that would not eat both pennyroyal and calamus. The 'if (@slick) {outb calamus;eat calamus}' would only fire if not stupid. It works as follows:

#if (@caneatherbs) {IF CAN: #if (@stupid) {IF STUPID: outb pennyroyal;eat pennyroyal} {IF NOT STUPID: #if (@slick) {IF SLICK: outb calamus;eat calamus}}}}
Totally not your fault, but I wanna f---ing kill you right now. Blargh. I just typed up a totally awesome new thread, copied it because it failed to post initially, went to redo the thread and came across this. Then my keys started acting up so I had to copy some of your post, over-writing my awesome and long post. Grrr. My beautifully failed thread: This.
Well if it makes you feel better I gave you some feedback kiss.gif And thanks so much for telling me this, sounds good and hopefully it won't be laggy by much.
Murphy2006-02-19 05:15:37
mine works like that, my cure_herb alias is really long, basically it goes #IF (@stupid = 1) {pennyroyal} {#If (@slick = 1) {calamus} {#IF (@blind = 1) {myrtle}}}} or however many brakcets. It will go through and work excatly the same as heaps of elseifs would...go test it
Laysus2006-02-20 01:15:36
Mine's spangly and doesn't use ifs.

Go go spangly case statements!

...just to show off:

CODE

#var SACP 1
#var NSC %subregex(%item(%sort(@salveafflictions),1),"\\a+","")
#while (%ismember(@NSC,@nonregencures)=0 & !@regenbalance & @SACP<38) {#add SACP 1;#var NSC %subregex(%item(%sort(@salveafflictions),@SACP),"\\a+","")}
#if (@nsc!=0 & @nsc<38) {#case %left(%item(%sort(@salveafflictions),@SACP),3) {regengut} {regenhead} {mendhead} {mendhead} {regengut} {regenchest} {regenchest} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {mendlegs} {mendlegs} {regenarms} {regenarms} {regenarms} {regenarms} {mendarms} {mendarms} {regengut} {regenchest} {lin} {lin} {lin} {lin} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {regenarms} {regenarms} {regenarms} {regenarms} {regenhead} {regenhead}} {#noop}
Shryke2006-02-20 01:40:33
What the hell is that laysus? Could you explain it to me? Looks very simple and very complicated at the same time
Laysus2006-02-20 02:01:41
Most of the prioritising is in the reflexes rather than the alias.

I have a db variable for each medium of curing, such as salveaffs_possible. This has the afflictions listed with number counterparts for priorities.

It's list based, and when I get something, it adds %db(@affs_possible,)) to that list.

I also have lists with the numbers of priorities for various afflictions, such as the @nonregencures there.

Then what the code does is this...

CODE

#var SACP 1


This resets the number in the list at which the alias looks (SACP = salve aff curing position)

CODE

#var NSC %subregex(%item(%sort(@salveafflictions),1),"\\a+","")


This sets the variable "NSC" (number salve curing) equal to the three digit priority at the start of the first entry in the relevant affliction list.

CODE

#while (%ismember(@NSC,@nonregencures)=0 & !@regenbalance & @SACP<38) {#add SACP 1;#var NSC %subregex(%item(%sort(@salveafflictions),@SACP),"\\a+","")}


This runs the NSC through failsafes to make sure nothing else is going to mess it up. If it's a cure that it can't pull off at the moment, it adds one to SACP, and say, reads the second item in the list instead of the first. This goes on until it finds an affliction that can be cured.

CODE

#if (@nsc!=0 & @nsc<38) {#case %left(%item(%sort(@salveafflictions),@SACP),3) {regengut} {regenhead} {mendhead} {mendhead} {regengut} {regenchest} {regenchest} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {mendlegs} {mendlegs} {regenarms} {regenarms} {regenarms} {regenarms} {mendarms} {mendarms} {regengut} {regenchest} {lin} {lin} {lin} {lin} {regenlegs} {regenlegs} {regenlegs} {regenlegs} {regenarms} {regenarms} {regenarms} {regenarms} {regenhead} {regenhead}} {#noop}


This then checks that the priority number pulled off is in the acceptable range (it might not be if there's, say, slitthroat, which uses 999 and is cured somewhere else that goes through before these cures). It feeds the number through a case statement, so it goes to the relevant response (i.e. if the priority number pulled out was 005, it goes to the fifth possible response)

It's somewhat an eccentric way of doing it, but I like it, and theoretically, case statements should be faster than if statements, although I don't know how much Zmud handles it. It's also fairly easy to adjust priorities and add new things to it.

If you can see any way to improve it without changing it drastically, lemme know.

Edit: I also use the lists to display what I've got at the moment in a side window, just for failsafe purposes. Was useful, found out it was trying to cure omniphobia with wormwood that way earlier with just a glance at what I had. Yay.

Edit number 2: I may be wrong about how it works. I forget these things, even when I write them.

Edit number 3: Looking back at it, I think I was likely quite insane to do it, but I love it so.
Unknown2006-02-20 12:11:15
That's really quite impressive, Laysus. I've done some very complex priority checking myself, in my Achaea system, but this is a totally new way to go about it that I hadn't considered. I'd post a snippet from my ACP, but then I'd have to explain it all over again. Heh.
Tiran2006-02-21 06:16:16
QUOTE(Laysus @ Feb 19 2006, 07:01 PM) 260461

It's somewhat an eccentric way of doing it, but I like it, and theoretically, case statements should be faster than if statements, although I don't know how much Zmud handles it. It's also fairly easy to adjust priorities and add new things to it.


This really depends actually. With more scripting languages, I imagine case statements are simply represented with nested if-else statements. Even in programming languages, it's a somewhat involved optimization to produce faster case statements in machine code. My love of case statements is that it makes things so easy to read, and like you say adjust priorities and make additions. Even if it doesn't save time in execution, the time saved in maintenance alone is worth it.
Daganev2006-02-21 06:55:26
Intersting, in all my programing classes I have been told to avoid cases because #ifs do them better.
Unknown2006-02-21 08:58:44
If with else surely can, but nested ifs probably means the program checks for every single one each time instead of avoiding some.
Unknown2006-02-21 11:59:12
Nested if's are ifs-with-else, Jello. And, if you code them properly, you can optimize which ones are evaluated every time versus which ones are only evaluated occasionally. Put the most commonly used affliction first, and the rest are checked much, much less because you'll stop at the first one you see as true.
Unknown2006-02-21 12:31:00
QUOTE(daganev @ Feb 21 2006, 06:55 AM) 260798

Intersting, in all my programing classes I have been told to avoid cases because #ifs do them better.


Case statements have specific uses for fall through. So you can have something match at one case and then automatically match every other subsequent case until a break occurs. Thats the main reason to use them. Plus they are much cleaner looking than complex if statements.

EDIT: The main reason a lot of people avoid them is that in 99% of languages what you can switch on is restricted to either a character or an integer or something like that. This results in having needless constant declaration to get switches over defined strings etc.
Unknown2006-02-22 23:53:51
Is there a does not equal equivalent in zmud? I figure it might help me if I could do "does not equal zero" stuff.
Laysus2006-02-23 01:26:08
try != tongue.gif