Silly mistakes?

Noremac

New member
Let me start by saying I have read the manual (twice) and I've looked at various finished scripts. I'm completely new to this particular type of programming so I've been trying to reverse engineer existing scripts without a full grasp of the basics.
As a result: Problems.

What this part (pasted below) is meant to do:
Decide which shot is best for your class
Decide which DB drink is best for your class
Replace bartender if it is missing
Create drinks
Drink drinks
Summon cocktail garnishes (x3)
Summon additional 2 if you have the skill

When I try to run it I am told that there are "Illegal amount of parameters for function drink at line 49".
If I add } } after the line "drink ( 19, booze2 );" I am then told that booze2 is an unknown variable. But I thought that would have been taken care of by "item booze2;" near the start.

Also: Is there perhaps a tutorial on how to use booleans, etc which would be suitable for their uses in ASH?

Any help would be greatly appreciated.

Code:
void drink()
{
item booze2;
item booze3;
	stat MainStat;
	if( my_class() == $class[turtle tamer] || my_class() == $class[seal clubber]) { MainStat = $stat[muscle]; }
 if( my_class() == $class[pastamancer] || my_class() == $class[sauceror]) { MainStat = $stat[mysticality]; }
 if( my_class() == $class[Disco Bandit] || my_class() == $class[accordion thief]) { MainStat = $stat[moxie]; }
	if (MainStat == $stat[moxie] ) 
		{
		booze2=$item[fine wine];
		}	
	if (MainStat == $stat[muscle] ) 
		{
		booze2=$item[shot of orange schnapps];	
		}	
	if (MainStat == $stat[mysticality] ) 
		{
		booze2=$item[shot of grapefruit schnapps];	
		}	
	
	if (MainStat == $stat[moxie] ) 
		{
		booze3=$item[perpendicular hula];
		}	
	if (MainStat == $stat[muscle] ) 
		{
		booze3=$item[slip 'n' slide];	
		}	
	if (MainStat == $stat[mysticality] ) 
		{
		booze3=$item[horizontal tango];	
		}	
//boolean have_bartender;
//have_bartender = false;
if( have_bartender() == true)
		{
		create ( 19, booze2 );
		drink ( 19, booze2 );
		}
 else 
 {
 buy (1, $item[bartender-in-the-box]);
 use(1, $item[bartender-in-the-box]);
 create( 19, booze2 );
drink ( 19, booze2 );
 }
  {
  if(have_skill($skill[Advanced Cocktailcrafting]))
    {
	cli_execute("outfit MP");
	cast_buff($skill[Advanced Cocktailcrafting], 3);
    }
  {
  if(have_skill($skill[Superhuman Cocktailcrafting]))
    {
	cli_execute("outfit MP");
	cast_buff($skill[Advanced Cocktailcrafting], 2);
    }
  if(have_skill($skill[Advanced Cocktailcrafting]))
    {
	cli_execute("outfit MP");
	 create( 1, booze3 );
    }	
}
 

macman104

Member
I'm going to guess that your issue is stemming from the fact that your own function that you've created "drink()" is already an boolean ASH command. I believe the word is "reserved", I think? Basically, I think when you try to run this, it looks and sees that you say:

drink(19, booze2), and it thinks that you are calling the function you are in: drink(), not the ASH command, drink(int, item). It looks, and says, gee, you are passing 2 parameters to drink, but you've defined drink as taking 0 parameters. If you were hoping to include this function in a larger script, I'd recommand renaming it to drinking() or what_to_drink(), or something that isn't already taken in the ASH structure.
 

Tirian

Member
I agree that your main problem is that your function has the same name as an ASH command. It sounds like maybe someday we'll be able to overloading functions so that you can have two functions with the same name but different signatures, but for the time being the function you write will completely write over the original function and you can't call it.

Also, FYI, there is a new function called my_primestat() that does the calculation that you're doing for MainStat. Also, you might enjoy playing with maps. Here's a sample of what you might do with them:

Code:
item [stat] drink1D;
drink1D[$stat[moxie]] = $item[fine wine];
drink1D[$stat[muscle]] = $item[shot of orange schnapps];
drink1D[$stat[mysticality]] = $item[shot of grapefruit schnapps];

item booze2 = drink1D[my_primestat()];

I'm not quite sure what you mean by using booleans in ASH. Can you talk about the sorts of things that you want to do?
 

Nightmist

Member
Indeed this is your problem, a extreme example of using function names mafia already uses is this: try this after turning debug logging on and running the below script ;)
Code:
void print( string Input)
{
 print( Input);
}
void main()
{
 print( "Stuff");
}
Yup it just loops... infinitely... The one thing that lets you call your own function to call itself... (In parsing time anyway so it doesnt do anything apart from stall). In short, try naming all your functions differently.
 

Noremac

New member
Gah...

How idiotic of me. I even renamed "booze" to "booze1" as I was worried that booze might be some kind of command. Then I go and do that with drink.

Thanks guys.

[quote author=Tirian link=topic=285.msg1484#msg1484 date=1152757672]

I'm not quite sure what you mean by using booleans in ASH. Can you talk about the sorts of things that you want to do?

[/quote]

I want to learn the basics from the ground up. Booleans were just one example.
I can make educated guesses by looking at existing scripts but that only helps if other people have used the commands that I'm trying to figure out.
I'm sure there must be tutorials out there but I was worried that they might contain a lot of information that isn't relevant to ASH so I would be wasting my time on them.



Quick question: Does Kolmafia already know that things like "have_bartender()" are booleans? So I only need to tell it that it is a boolean if I am making up my own?
e.g.
boolean have_bartender;
if( have_bartender() == true)

versus

if( have_bartender() == true)
 

Nightmist

Member
[quote author=Noremac link=topic=285.msg1506#msg1506 date=1152880333]
boolean have_bartender;
if( have_bartender() == true)

versus

if( have_bartender() == true)

[/quote]

-_- err... same things?
And the ash command
Code:
have_bartender()
RETURNS a boolean value. Minor difference between "being a boolean" and "returning a boolean value".
But if you ment
Code:
if( have_bartender())
will work then yes it will. However
Code:
boolean TheBoolean;
if( TheBoolean)
"TheBoolean" isnt defined a value so it is automatically assumed to be false. But say we do have a bartender then
Code:
boolean TheBoolean = have_bartender();
if( TheBoolean)
"TheBoolean" is defined a value and assuming we have a bartender then that value will be "true" so this code works.
 

Tirian

Member
[quote author=Noremac link=topic=285.msg1506#msg1506 date=1152880333]
I want to learn the basics from the ground up. Booleans were just one example.
I can make educated guesses by looking at existing scripts but that only helps if other people have used the commands that I'm trying to figure out.
I'm sure there must be tutorials out there but I was worried that they might contain a lot of information that isn't relevant to ASH so I would be wasting my time on them.
[/quote]

I've been thinking about this problem for the past few days. This repository does seem like a great resource for education, but it would require a tutorial that links from the manual to a subset of scripts here that clearly illustrate the use of the functionality. It would be a nice project.

Anyway, booleans. Here's an overview -- I don't know how much you already know, so the first part of this might be condescending. :)

A boolean variable is a variable that holds either the value "true" or "false". It was named in honor of George Boole, who was a great pioneer in the sorts of mathematical logic that would later be the foundation for computer science. That subfield is called "propositional calculus", which talks about how you can calculate with truth and falsehood in the same ways that you add or multiply numbers.

The three most primitive ways of combining boolean values are what pure mathematicians call conjunction, disjunction, and negation. Ordinary people call them AND, OR, and NOT, and they do what you think they would do. So you might say "true AND false equals false, true OR true equals true, and NOT false equals true." In some computer languages, those are even the words that are used, but in other languages (like ASH), the operators are && for AND, || for OR, and ! for NOT.

So you can use all this to write complex expressions that combine multiple boolean values. For instance, if you wanted to know if drinking a whiskey and soda was something that your character could do at this moment, you might write something like

Code:
item whiskey = $item[bottle of whiskey];
boolean mall_open = can_interact();
if ((have_bartender() && item_amount(whiskey) > 0) || mall_open)
{
  [...]
}

which will run the code in the middle if you have a bartender and some whiskey in your inventory, and will also run if you have access to the mall. Notice that the if statement is using three different sorts of booleans: mall_open is a boolean variable, have_bartender() is a function that returns a boolean value, and item_amount(whiskey)>0 is a mathematical operator that calculates a boolean value in the same way that 3 * 5 is a mathematical operator that calculates the number 15.

That might not be everything, but I think it's nearly enough that you'll be able to read other people's if statements.
 

Veracity

Developer
Staff member
[quote author=Noremac link=topic=285.msg1506#msg1506 date=1152880333]I'm sure there must be tutorials out there but I was worried that they might contain a lot of information that isn't relevant to ASH so I would be wasting my time on them.[/quote]
Well, on the KoLmafia User Manual page, there's a pointer to not only the ASH Reference, but also the ASH Tutorial...
 

Nightmist

Member
[quote author=Tirian link=topic=285.msg1509#msg1509 date=1152884482]
Code:
item whiskey = $item[bottle of whiskey];
boolean mall_open = can_interact();
if ((have_bartender() && item_amount(whiskey) > 0) || mall_open)
{
  [...]
}
[/quote]
0_o... you can do if's in that manner?? >> I did NOT know that... (The bracketing of the && statements) I guess the tutorial is semi-misleading by the last example code where in the "void main" there are 2 different if's (One for the AT && level 9 check and another for a SC || PM check).
 

Tirian

Member
Golly, ASH conditionals can do even neater things than that. Here's a quiz to take before reading the rest of my post: look over the following code and guess what will get printed, and then copy it into an ASH script and execute it to see if you're right.

Code:
boolean first()
{
	print("George");
	return true;
}

boolean middle()
{
	print("W.");
	return true;
}

void main()
{
	if (first() || middle())
	{
		print("Bush");
	}
}

You might think that it prints the name of America's 43rd president, but it actually prints the name of the 41st president. The reason is that the conditionals "short-circuit" in ASH, which means that after noticing that first() is true, ASH realizes that it doesn't need to execute middle() to know that the disjunction is going to be true, so middle() doesn't get executed. There is a similar short-circuit for conjunctions: when ASH evaluates (false && A()), it does not call A().

This allows you the flexibility to write neat code like this:

Code:
item gel = $item[super-spikey hair gel];
if (item_amount(gel) > 0 || buy(1, gel))
{
	use (1, gel);
}

This command will use the hair gel if either you originally had one or succeeded in buying one, but it won't try to buy if you already had one.
 
Top