simplifying script

asturia

Minion
Is there a way I can simplify this script?:
Code:
void mayfly()
{
	if ( get_property("mayfly_active") == "false")
	{
		if (equipped_item ($slot[acc1]) == $item[mayfly necklace])
		{
			cli_execute("remove mayfly bait necklace");
			equip($slot[acc1],$item [natty blue ascot]);
		}
		if (equipped_item ($slot[acc2]) == $item[mayfly necklace])
		{
			cli_execute("remove mayfly bait necklace");
			equip($slot[acc2],$item [natty blue ascot]);
		}
		if (equipped_item ($slot[acc3]) == $item[mayfly necklace])
		{
			cli_execute("remove mayfly bait necklace");
			equip($slot[acc3],$item [natty blue ascot]);
		}
	}
}
 

Bale

Minion
I can't tell you how many times I've wished for a multi-branching data structure in ash.

I'd program that as:

Code:
void mayfly()
{
	if ( get_property("mayfly_active") == "false")
	{
		slot mayslot = $slot[acc3];
		if (equipped_item ($slot[acc1]) == $item[mayfly necklace])
			mayslot = $slot[acc1];
		else if (equipped_item ($slot[acc2]) == $item[mayfly necklace])
			mayslot = $slot[acc2];
		cli_execute("remove mayfly bait necklace");
		equip(mayslot,$item [natty blue ascot]);
	}
}

Is that simplified enough for your taste? At least it doesn't have as many redundant lines to accomplish the same thing for each case.
 

Bale

Minion
It just occured to me that I could have made that MUCH simpler. Allow me to try again:

Code:
void mayfly()
{
	if ( get_property("mayfly_active") == "false")
	{
		cli_execute("remove mayfly bait necklace");
		equip($item [natty blue ascot]);
	}
}
 
Last edited by a moderator:

zarqon

Well-known member
This is the fewest characters I'm able to do it in. :)

PHP:
void mayfly() {
   if (!to_boolean(get_property("mayfly_active"))) 
      cli_execute("remove mayfly bait necklace; equip natty blue ascot");
}
 

asturia

Minion
It just occured to me that I could have made that MUCH simpler. Allow me to try again:

Code:
void mayfly()
{
	if ( get_property("mayfly_active") == "false")
	{
		cli_execute("remove mayfly bait necklace");
		equip($item [natty blue ascot]);
	}
}
I came up with this solution too, but the script doesn't equip the Natty blue ascot if you already have 1 equipped. Same problem with your script Zarqon.
I want to swap my Mayfly necklace for a second ascot after I'm not able to use the skill from the necklace (already have a script in place to verify this).
So I came up with the script in the original post.
Bale, your first script works beautifull, I will use that for now.
 
Last edited:

zarqon

Well-known member
Try this:

PHP:
void mayfly() { 
   if (!to_boolean(get_property("mayfly_active")))  
      cli_execute("remove mayfly bait necklace; inv_equip.php?pwd&which=2&action=equip&whichitem=2392"); 
}

And that is a 'q' in my name. :)
 

asturia

Minion
Try this:

PHP:
void mayfly() { 
   if (!to_boolean(get_property("mayfly_active")))  
      cli_execute("remove mayfly bait necklace; inv_equip.php?pwd&which=2&action=equip&whichitem=2392"); 
}

And that is a 'q' in my name. :)
Same result. It doesn't equip the second ascot.
What I want to achieve is this.
Equipment before:
Code:
Monster bait
Natty blue ascott
Mayfly necklace
and after the script
Code:
Monster bait
Natty blue ascott
Natty blue ascott.

The accessory's are not always in that order.
The first script Bale posted works fine.
I have no idea why the script you posted doesn't work.Maybe it's a bug in kolmafia?
 

Bale

Minion
I'm glad I left that first script there instead of simply replacing it or else I'd have lost this round to zarqon (that's a Q).

Could you tell me if this works?
Code:
void mayfly() {  
	if (get_property("mayfly_active") == "false") {
		cli_execute("remove mayfly bait necklace");
		visit_url("inv_equip.php?pwd&which=2&action=equip&whichitem=2392");
	}
}

Yeah zarqon, I could save a few more characters, but I don't like to run extraneous data type conversions or sacrifice clarity. :p

I came up with this solution too, but the script doesn't equip the Natty blue ascot if you already have 1 equipped. Same problem with your script Zarqon.
That sounds like a bug. It should be reported.
 
Last edited:

zarqon

Well-known member
Bale, your latest code (which to me is equally clear but admittedly a ms or two faster to run... I just like having data in the proper type), is an identical solution to the one I posted, which asturia claimed didn't work. I thought that perhaps sidestepping mafia functions and going directly to the KoL link (which works fine in the relay browser) would solve the issue. I'm confused as to why it wouldn't. I might play with it a bit more when I get home from work.

Regardless, it would be ideal if equip(item) would allow multi-equipping accessories/weapons that allow it as long as there is an empty slot, so I'm glad the report was submitted.

And regardless, I cede this round to Bale. Where are scores posted? :)
 

Bale

Minion
I know it was the same. I was hoping that making it explicitly a visit_url might work around whatever weirdness was causing it to not work. It was a desperate attempt.

And yeah, that extra ms is pretty pointless, that's mostly just a stylistic difference. I cede brevity to you and only won because of a bug in mafia.
 

zarqon

Well-known member
Bale, if you submit a feature request for a "case" or "switch" operator in ASH I would totally back you up. :)
 

Bale

Minion
Bale, if you submit a feature request for a "case" or "switch" operator in ASH I would totally back you up. :)
Gosh it would be grand. What syntax should we encourage? Since ash is built with Java, perhaps we should use that as our basis. Java uses the following syntax.

Code:
switch (n) {
    case 0: print("n was Zero"); break;
    case 1:
    case 3:
    case 5: print("n is an odd number"); break;
    case 2:
    case 4:
    case 6:
    case 8: print("n is an even number"); break;
    case 9: print("n is a perfect square"); break;
    default: print("The default output if \"n\" is not a case"); break;
}
That looks great to me. Of course it should support all data types available to ash. Of course it needs to support boolean conditionals as well. I'm not sure if Java support that, but how about this:

Code:
switch(true) {
	case(item_amount($item[scroll of drastic healing]) >0):
		use(1, $item[scroll of drastic healing]);
		break;
	case(use_oil && item_amount($item[scented massage oil]) >0):
		use(1, $item[scented massage oil]);
		break;
	case(use_herb && my_spleen_use() < spleen_limit() && (item_amount($item[medicinal herbs]) >0 || (my_meat() >=100 && my_primestat() == $stat[muscle])) ):
		use(1, $item[medicinal herbs]);
		break;
	case(have_skill( $skill[Cannelloni Cocoon] )):
		use_skill(1, $skill[Cannelloni Cocoon]);
}

I am so tired of "else if" statements! This is both clearer and easier to use.

So, Zarqon, do you like that? Any changes you'd like to make before a request is made? Of course this would be only a recommendation for the devs, but it can't hurt to tell them our ideal form for the operator.

EDIT: Argh, double-posted. Really slow machine here at work.
LOL! Double-posted a half hour apart! Wow, that must be the slowest machine EVER! ;)
 
Last edited:

zarqon

Well-known member
Wow, you're thinking of requesting more functionality than I thought. To my knowledge a switch/case statement only accepts a variable, i.e.

Code:
switch (variable) {
   case value1: commands
   case value2: commands
   case value3: commands
}

or

Code:
case (variable) of {
   value1: commands
   value2: commands
   value3: commands
}

It is a way to perform different commands based on the value of a single variable. You cannot pass a value (i.e. "true" in your example) because there is only one possibility -- that value.

But I can see the desirability of something like you are suggesting. Although I would say that is a separate thing.

So, 1) I would like a traditional switch command... i.e. Java's.

2) What might also be a nice command is "match", which looks similar but simply iterates through a list of boolean conditions paired with commands and executes the first match it comes to. i.e.

Code:
match {
   (condition) : commands
   (condition) : commands
   (condition) : commands
}

If a condition is met, it executes the commands after that condition and then exits the loop. If no condition is met, nothing happens.

Either or both of those would go a long way towards both beautifying and clarifying the if-else mess that we sometimes get into.

Bale said:
LOL! Double-posted a half hour apart! Wow, that must be the slowest machine EVER!

Haha, actually it hung while posting and I didn't notice it until later. I reloaded because I thought it hadn't posted, only to find two posts half an hour apart. Bizarre. Of course, the school I teach at is cheap and gives us like Pentium II's with 128MB of RAM running pirated copies of XP. :)
 
Last edited:

Veracity

Developer
Staff member
Ha ha. You are requesting a "cond" statement.

Code:
(let ((x (cond ((eq y 10)
		(do-this)
		(do-that)
		"Yowza")
	       ((< y 12)
		"Too small")
	       (t
		"Default"))))
  (print x))

Is that syntax acceptable? ;)
 
Last edited:

Bale

Minion
It is a way to perform different commands based on the value of a single variable. You cannot pass a value (i.e. "true" in your example) because there is only one possibility -- that value.
Oh? I guess you never saw that syntax before. Some languages allow that because the value (true) matches the condition if the condition is also true. It's kinda elegant in a back-door fashion. I would not mind if they were separate functions though.

Ha ha. You are requesting a "cond" statement.
Oh dear. It's been ages since I dared look at LISP and I don't really remember it anymore. I'm having trouble figuring out that syntax, but I think that contains all the functionality I'm hoping for. I'd just like a less confusing syntax like the ones that Z and I are hoping for. Somehow though I think you were joking. At least I hope you were joking.
 

Bale

Minion
Refined the syntax to make it more ash-like:

Code:
switch(n) {
   case(0)
      print("n was Zero");
   case(1)
   case(3)
   case(5)
      print("n is an odd number");
   case(2)
   case(4)
   case(6)
   case(8) {
      doeven();
      print("n is an even number");
   }
   case(9) {
      dosquare();
      print("n is a perfect square");
   }
   print("No case applies!");
}

Note that it no longer needs a break. Now if the contents of case match switch it will also match the next case, just like previous examples, but it ends the structure after it reaches an executable statement. This is similar to the way other controls strucutres work in ash so it suits my sense of athetics.

Also, it shouldn't matter if any switch() or case() contains a constant or a variable.

Code:
switch(n) {
   case(1)
   case(2)
   case(3)
      print("n is less than 4");
   case(4) {
      print("n is 4");
	  dothis();
   }
   print("n is greater than 4");
}

That syntax should naturally lead to this:

Code:
switch(true) {
   case(n < 0)
      print("n is negative");
   case(n == 0) {
      print("n is zero");
      dozero();
   }
   case(n == 1)
   case(n == 2)
   case(n == 3)
      print("n is less than 4");
   case(n == 4) {
      print("n is 4");
      dothis();
   }
   print("n is greater than 4");
}

Question: Would we be better off requiring break to end the flow? That way we would have more flexibility and could do things like this:

Code:
switch(n) {
   case(0)
      print("n was Zero");
   case(1)
      print("1");
   case(2)
      print("2");
   case(3)
      print("3");
      print("n is an odd number");
      break;
   case(2)
      print("2");
   case(4)
      print("4");
   case(6)
      print("6");
   case(8) {
      print("8");
      doeven();
      print("n is an even number");
      break;
   print("No case applies!");
}
 
Top