User input

Is there an internal ( function internal is what I'm saying I guess ) method of prompting a user for input? I have been using the parameters of main() to get some input but I was hoping for a way to prompt from within my code as well. Any ideas?
 
I use a lot of scripts while I'm at the computer just because I like to play the game but I'm lazy enough (and content) just to sit and watch the script run to see what I get or what happens. I like to do a lot of administrative work with it too. So let's say I'm writing a script to give out prizes to my guildmates. I want a script that will randomly pick an item in my inventory (out of a previously established "prize selection" of say TPS, ToSS, Jeweled-eye wizard hat just as an example) but once the item is selected I want to type in the user name of the person. I'd like it to prompt me for a user name/id that I can choose on my own free will and enter it. Then I'd like it to loop again say for 3 times so that I can give out prizes to the top 3 guildmates of the week.

As another example:
A script that handles my full day's eating/drinking. I'd like to specify before eating that I want to eat chow meins that will boost my stats equally, but then when I get to drinking I'd like to focus on my class' main stat. Before each step, or maybe even early in the script, I'd like it to prompt for an input ( being able to output atleast a string of available answers would be awesome ) that would get parsed inside the code and not just handling it as a parameter to main().

I know a lot of this can be done via parameters to main() and seperating all of these scripts from one big into smaller ones each with their own main() could accomplish this, but I feel like this functionality would be amazing for future administrative tools.

Sorry I'd give you a more code-heavy example but I'm at work right now and shouldn't be working on this to begin with lol.
 

Nightmist

Member
Code:
#Heh yeah it's got a couple of flaws such as lack of item amount checks and such but the basic concept is there.

item [ int] PrizePool;
PrizePool[ 0] = $item[Tiny plastic sword];
PrizePool[ 1] = $item[Jewel-eyed wizard hat];
PrizePool[ 2] = $item[Tome of snowcone summoning];

void main( string Player)
{
 item ChosenItem = PrizePool[ random(3)];
 print( "send 1 "+ChosenItem+" to "+Player);
 print( "You have sent "+Player+" a "+ChosenItem);
}
Yeah I made it print the send command and it doesn't loop so you would really have to run it multiple times to get the intended "looped" result... but thats not my point, a major reason for a "ask for user input" command as far as I can tell is for when we want to alter that input while the script is running rather then running a single script multiple times or when you script in a prompt because something might happen while the script does something...

Although one could argue you can always use a series of "IF" to make "optimal" choices for the user but it lacks a judgement of "risk" when deciding what is "optimal" and a scripted "judgement" engine is rather clunky. Script != Script+Player Intelligence, script with user prompting == Script+Player Intelligence...

A code example of a "input( string message, TheInput)" command (This type of input effectively is a "void main( TheInput)" but it has a extra string at the start which is a message the prompt comes with, although that can be just substituted with a "print" and then a "input( TheInput)").
Code:
if( item_amount( $item[swindleblossom]) >= 2 && item_amount( $item[fraudwort]) >= 2 && item_amount( $item[shysterweed]) >= 2)
{
 input( "You currently have atleast 2 of each of the Doc Quest items, Do you wish to backfarm them? (true//false)", boolean Choice)
 if( Choice)
 {
 #Backfarm for the missing items for the Doc quest.
 }
}
 

Veloz

New member
has there been any progress on user input?

I can see plenty of functionality for this improvement.
 

holatuwol

Developer
Nope.  Given Java's focus problems, I can't see this as being useful rather than annoying.  The main issue, of course, is that if you're prompting early in a script, it's fine, but if you prompt after it's been running for awhile, a prompt just confuses the user because all of a sudden (usually they're chatting), all their controls are disabled.  And trust me, they're not going to be looking for a prompt, or suspecting a script -- they'll be reporting a bug in the mafia thread.

Now, if you *really* want this for your own use, you can, at your choosing, invoke ASH scripts from other ASH scripts using CLI_EXECUTE. If the main method of the other script wants parameters, KoLmafia will prompt you for them. However, I highly recommend not distributing these scripts unless you make it ABSOLUTELY CLEAR in your script description that it will prompt you IN THE MIDDLE OF RUNNING, POSSIBLY WHILE THE USER IS CHATTING.
 

Veloz

New member
I guess the difference is in utilization... I really don't care to chat much, I'm like the original poster of this thread, I like to watch the script run. As for prompting, I figure that there are times when I would want to make a decision, or enter a value for a script at the beginning of the run, rather than hard code it as a variable in the script.

For example, in a meatfarming script, ask how many turns to farm, or to activate different behavior modes in a script (like frugal or spendy mode, in which spendy would buy more expensive effect items like oyster eggs, etc.) Kind of like the way the item management module asks how many to use when using an item.

Ultimately, you're the developer, and I respect your decision to avoid that route, but hopefully, now that you're scripting yourself, you might see a use for it... ;D
 

Darkness

New member
I have also come up against the wall that is no user input once the script is started.

The way I get around it is to use the script menu to call the script; this allows CLI commands to be entered while the script is running.
Using the SET command I can enter data into a script while it is running.
Print+wait can then be used as a pseudo prompt waiting for the set command.

Another way around this is to use data files that are periodically read by the script and edit them while the script is running, or use a main script that calls another script and edit the dam script while the script is running...

These solutions are often sub-part replacements for an input box.
 

Veloz

New member
Both your solution and the one that Hola described will work, but they're kludgey compared with a simple inline text input call. Since the rest of the app is so fantastic, I find it hard to believe that it's missing this basic functionality...
 

holatuwol

Developer
You'd need to find a real example where it's necessary. The hypothetical one provided by Nightmist shows me that it's possible you would use it if it were available, but I have yet to see a situation where you really want end-user input.
And by necessary, you're basically having to show a script that I can sympathize with that actually requires user input, and then show the example of how kludgey it is without it. If I find a cleaner way to do it than the kludge and it's still ugly, or if no cleaner way exists, I'll likely add textual input. The key point, however, is it has to be a scripting concept I can sympathize with, and that's not necessarily easy.
 

arrggg

Member
okay, I'll try:

Instead of having different scripts to pull my outfits from hagnks(which would work), I'd use this to pop up a prompt:
"Which outfit would you like to pull?"
"1. Knob Harem"
"2. Swashbuckleing"
"3. NS Killer"
"4. Hippy"
etc....

Then depending on the choice, it would check your inv, and then pull the outfit you need and put it on.
 

Veloz

New member
okay, now I'm confused as well... I have been racking my brain trying to come up with a good example for ya, Hola, but arrggg's post (and your response) has thrown a monkeywrench in my though process.

How exactly would you prompt for something at the beginning, according to the example arrggg laid out?

I apologize if this seems remedial or n00Bish, but hey, iyam what iyam... ;D
 

holatuwol

Developer
Err, it's not possible to provide a detailed prompt message, like in the example. However, ASH scripts always prompt for missing parameters to their 'main' method and specify the name of the variable being requested along with its type, so as long as you're using good coding style, and the scripts are for personal use, it'd be pretty obvious what the script wants. Thus suppose you put the following into 'outfit_pulls.ash' and you selected 'outfit_pulls.ash' from the script menu. It would then prompt you, saying it needed 'string outfit_to_pull'.

PHP:
void main( string outfit_to_pull )
{
	print( "I wanted to pull " + outfit_to_pull );
}
 

Veloz

New member
Okay, I have been giving this a lot of thought, and I am really going to try and give some relevant and useful examples here.

I can see a use for three distinct "user interaction" functions (I know Hola will hate me for even suggesting these, sorry... but I really am a fan of the tool, and I think these will truly enhance it's capabilities). I'll detail these now for complete clarity on my intentions:

Function Displays a modal dialog box with definable prompt text and... Usage
Inputan input box (returns the input to a variable)input("prompt text",variable)
Confirmyes/no buttons (returns boolean true/false)confirm("prompt text",variable)
Selecta drop-down selector (returns value set in comma delimited list)select("prompt text","choices,comma,delimited",variable)

So let's say you want to script out your entire day's worth of adventures in one script (ambitious, ain't it?!?), and you notice that today is a Moxie day, and you happen to have a moxie character. You'd want to maximize your adventuring to take advantage of that, right? Then you might want to do a little meatfarming, and maybe throw in a few turns ultra-rare hunting or other adventure waster.

Here I'm just going to make up some code... it's just off the cuff, and obviously not optimized, so don't laugh at my laughable coding skillz...

#EXAMPLE SCRIPT USING USEFUL USER INPUT
#start with breakfast, of course

cli_execute("breakfast");

#apply summoning gear for maximum MP
outfit("MaxMyst");

#get candyhearts (a wishful mod of my candyhearts script)
input("Enter Max MP cost for Candy Heart Summoning",sumMax);
confirm("Use beanbag chair to recover MP?",allowBB);
int candyCount = 0;
if(have_skill($skill[Summon Candy Heart])){
while(mp_cost($skill[Summon Candy Heart]) <= sumMax && mp_cost($skill[Summon Candy Heart]) < my_maxMP()){
#I'm just going to truncate the script here... no need get that verbose in this example
}
}

print("Summoned " + int_to_string(candyCount) + " Candy Hearts total.");

#Now check to see if user wants to do statfarming today
confirm("Do you want to do any statfarming today?",statFarm);
if(statFarm){
select("Optimize Statfarming for which stat?","Muscle,Mysticality,Moxie",statSelect);
#so here is where the script to statfarm would go, keying off of the statSelect variable
}

#get ready to meatfarm
outfit("meatfarming");
input("How many turns to meatfarm today?",meatAdv);
int advCount = 0;
while(advCount <= meatAdv){
#insert your meatfarming script here, it will iterate as long as the turn counter is less than or equal to the value you just specified above
advCount = (advCount + 1);
}

#decision gate! what to do with the rest of the day?
select("You have " + my_adventures() + " remaining today. What would you like to do?","Ultra-Rare Farm,End Script,Exit KolMafia",whatDo);

#switch/case statements would be useful here... does that exist in KoLMafia? Or more wishful thinking??
if(whatDo = "Ultra-Rare Farm"){
input("How many turns to burn uselessly attempting to farm for ultra-rares?",urfBurn);
#so here is where the completely useless ultra-rare farming script would go, only wasting the turns specified in urfBurn ;D
}

#I'm just guessing at how you would exit the script here
cli_execute("abort Script completed, thanks for playing! Returning to KoLMafia...");

#user chooses to exit this time
if(whatDo = "Exit KolMafia"){
confirm("Are you sure you wish to logoff from KoL and exit KoLMafia?",confirmExit);
if(confirmExit){
outfit("pajamas");
cli_execute("exit");
}
}

#END EXAMPLE SCRIPT

So I hope that my efforts to give a well-thought out, viable script example were successful.

I really think that adding user input will expand the utility of KoLMafia quite a bit... and I can't see how you would do all of the interactions with a kludge or workaround here.

Granted, it's less automated than the usual script, but it does account for more real-world variables like remaining turns for the day, stat-days, etc. Plus, people can be fickle... some days I just want to burn 20 or 30 turns on the slim chance of finding that elusive Baio or IDMG... ;D
 

macman104

Member
For an example, here's my script that I run after a I free the king to put things in my display case and such. I have a prompt at the beginning for shortAdd, if it's true, it runs only the shorter process in the script, and not the whole thing. I've attached it for you to see how it works. Depending on what the type you ask for, you might have a dropdown that has true/false or possibly one that has the different classes (if you prompt for a class type, etc.).

EDIT: This is an example to help show how prompting in main works, not something to show where input would be useful.
 

Attachments

  • DisplayAdd.ash
    7.4 KB · Views: 31

holatuwol

Developer
Your example sounds more like a task for several separate scripts than it does one script, because you're dividing tasks rather than showing how user input feeds into some workflow. So, while it's a cute idea, and while you likely put a lot of thought into it, it really looks like a task better suited to separate scripts rather than one combined script, and at that point, the prompting functionality without the custom messages already exists.
 

Veloz

New member
yeah, you could do it all with multiple scripts, but the point I am trying to make is that one script that forks (and maybe calls other scripts) is more user-friendly.

I'll leave it alone, as it seems that there is no swaying you, but I will say that if you build it, they will use it. I know I would.
 
The following code would allow a script user to fix a problem, then continue the script. It would be useful when error handling is required for the script to continue, and the script cannot be restarted unless you want excess buying of items needed for the day, or buffbot spamming (double buff requests) or other reasons you would not want to run a script twice. Maybe because it contains 3rd generation mushroom code, the reasons are endless.
uses the slightly modified proposed function: boolean confirm(string userprompt)
which would display a message box with yes and no buttons. Return true for yes, false for no.

choicefood is declared somewhere else in the script.
Code:
if(!eat(1, choicefood))
  {
  print("failed eating");
  cli_execute("relay");
  if(!confirm("Eating failed, Continue?"))
    {
     cli_execute("abort script terminated per user request");
    }
  }

The net effect is the script stops until the user makes a choice. The relay browser is started so the user can manually eat, then choose yes, and the script will continue where it left off. If the user chose no, then stop script execution leaving the relay browser running for them to do whatever they please.

doing it without the confirm function:

abortcheck.ash
Code:
void main(boolean continue)
{
  if(!continue)
    {
     cli_execute("abort script terminated per user request");
    }
}

Code:
if(!eat(1, choicefood))
  {
  print("failed eating");
  cli_execute("relay");
  Print("Eating failed, Continue?");
  cli_execute("call abortcheck.ash");
  }
Now I have a script called abortcheck.ash containing only 1 actual command. That seems such a waste. Also if the box that pops up covers the last line output in the cli, or the cli is minimized the user has no clue what happened.

As for input and select dialog boxes I think the choices should be made at the beginning of the script. I prefer to walk away from a running script. Coming back to find it only 2% completed, session timed out, and it waiting for me to select what kind of candy heart I want to send to the writer of the script today would just annoy me.

Edit: I should mention that most of my ash scripts are called by cli scripts which run them sequentially so I never see the opportunity to use kolmafia's already built-in continue.
 
Top