PDA

View Full Version : ascend_HC.ash (Work in Progress)



StDoodle
05-10-2010, 06:08 AM
Please note that very little of this script has been written, and even less is being made available. For now, this if a discussion reference thread & a place to upload scripts for testing. Thanks!

Winterbay
05-10-2010, 06:34 AM
Question: Will these be adapted to work under bad moon as well or only "normal" hardcore?
Just asking since if they are not BM-friendly I'll have to wait a while to help test them :)

StDoodle
05-10-2010, 06:44 AM
My current plan is something useful for skill-farming in HCNP. While I'd like to extend it beyond that, it will be an even longer time coming. Of course, if I win the lottery, the timetable would change. ;)

Deathless Assassin
05-10-2010, 08:52 AM
I'll be doing the pirates tomorrow, would it help if I downloaded them pirate part and tried to give it a run? Would aHC_LIB.ash be the only other required script?

Bale
05-10-2010, 09:10 AM
void farm_pirate_insults(int goal) {
while (total_pirate_insults() < goal) {
adventure(1, $location[Barrrney's Barrr]);
}
}

Little things like that will cause you trouble if you run out of adventures. Don't forget to check for && my_adventures() > 0


void open_belowdecks() {

while (! contains_text(visit_url("cove.php"), "snarfblat=160")) {
adventure(1, $location[poop deck]);
}

}That's incredibly inefficient in terms of server hits.
Check for if(get_property("lastEncounter") != "It's Always Swordfish")


void open_belowdecks() {
while (get_property("lastEncounter") != "It's Always Swordfish" && my_adventures() > 0) {
adventure(1, $location[poop deck]);
}
}

Just for the record, I prefer...


int total_pirate_insults() {
int total;
for i from 1 to 8
if(get_property("lastPirateInsult"+i) == "true")
total = total + 1;
return total;
}

StDoodle
05-10-2010, 05:15 PM
Re: my_adventures()

I plan on having wrapper functions for these that do such checking, but I'm not sure. This thing is totally just "bear bones just-got-started" stuff, but I had an offer to test something and had to put it somewhere.

Re: lastEncounter

Oh geez, that's what I wanted and didn't realize it existed. Thank you! (It will also help with the hidden city part that I was getting an offer to test... ugh, the server hits on that one!)

Bale
05-10-2010, 10:08 PM
Regarding the level 11 and 12 quests, are you planning to start from ground ZERO? Or are you going to ask zarqon to adapt his scripts as a starting point. Incidently the Hidden City is one of the few quests I automate. I've got this really nice script I use for it that I've adapted from zarqon. Take a look at it. It'll teach you a lot about how to handle the quest. You don't need to use regexes to search the map since mafia keeps that information in properties. It'll save you server hits if you use get_property("hiddenCityLayout") instead.

Here's the script I adapted from zarqon. I made a few changes. Take a look at it:

StDoodle
05-10-2010, 10:38 PM
Oh jeebus I never noticed that pref. either. *Headdesk* Argh. It's been one heck of a couple weeks for me; I wanted to come up with my plan & basics before posting any of this, then I got a request the other day in /clan. I really don't know how I plan to approach much of this, yet. All I know is that I find the process interesting, where I no longer find actually playing KoL to be so. A lot of that is lack of real life time; if I could go for speed, I'd get interested in ascension again. But until then I'd like to get more skills, but just can't bring myself to do so manually. Scripting it, however, is at least interesting. I'm not sure at this point how much I plan to borrow from others and how much I plan to do completely from scratch. It really depends on how everything in the planning stages comes along, and how those plans get along with the existing scripts.

I realize a lot of what I have thus far is horrid, which is why I was so hesitant to release anything yet. Ah well, it will probably get better once I can afford food again.

Bale
05-10-2010, 11:19 PM
This was definitely pre-pre-pre-release. On the bright side, releasing this now is enabling you to learn from our criticisms. That's good, right?

PS. Good luck with eating. That tends to make things better.

SinginSally
05-12-2010, 08:56 PM
Hey StDoodle. Don't forget to check out Rinn's Quest scripts which is on the first page. You might be able to use that to get a bit of lift.

You can also steal some code from the 1-click-wossname most likely to automate several of the battlefield quests.

The MacGuffin quest is also already done for you, probably twice over (once by Rinn and once by zarqon).


Instead of reinventing the wheel, surely you can save a bunch of time by using those. Ive used the Rinns quest scripts for opening spookyraven and doing several aspects of the run. The macguffin one is also really really nice, because that one is a big pain in the butt. Heck, even if I WANTED to do it manually (which I have in bad moon!), Im too lazy to reread all the wiki stuff for the Hidden Pyramid anyways. Ive bungled that one too many times when doing it before Mafia days.

slyz
05-14-2010, 01:19 PM
I have been playing around with the idea of an ascension planning script, and more precisely a function that would return the number of turns needed to achieve a goal (an item, a noncombat adventure, a number of substats...) as well as update a player 'state' (stats, MP, HP, meat, important items etc...), depending on the available resources. It would be hard to take things like the queue into account, but it would be possible.

This might not be useful for you though, since I don't really know how much optimizing you would want your script to do.

Could you tell us a little more about the bigger picture you were considering? A linear script that plows through quests à la ascension.ash? What about MP/meat management?

Regarding fighting strategy, some kind of BatMan fork (once Zarqon releases it) would be very handy (to decide - before a fight and not during the fight - if you want to outmoxie, or maximize ML etc...).

heeheehee
05-14-2010, 03:10 PM
Doesn't that function appear in ZLib as the new form of has_goal()?

I'm pretty sure he provided an alias that displays all the locations from which you could get a goal and what your chances of getting it are.

Edit: Found a link. (http://kolmafia.us/showthread.php?2072-ZLib-Zarqon-s-useful-function-library&p=28442&viewfull=1#post28442)

slyz
05-14-2010, 03:39 PM
I was thinking of something that would give you the number of turns it would take, depending on apparition rate, combat rate modifiers, olfaction, +item skills and equip etc etc...

It would also give you the number of turns needed to find a particular noncombat/superlikely, or gather enough of an item (stars, pixels...), or reach a certain stat.

heeheehee
05-14-2010, 03:44 PM
I think that's a future goal for has_goal(), but it's probably waiting on a choiceadv.txt map that includes all the noncombats.

slyz
05-14-2010, 03:52 PM
has_goal() has goals!

One problem with the kind of things we can do with Mafia is that it's almost impossible to take the queue into account.

The best way to find out the average number of advs (and spread) getting reaching particular goal would take would be to do simulations, like RoyalTonberry does. I don't know if that's a good way to go in ASH.

StDoodle
05-14-2010, 04:59 PM
Just to let everyone know, I'll give more comprehensive responses next week, when I get internet back (using my phone right now, it's a PITA).

zarqon
05-19-2010, 06:31 AM
ZLib's has_goal() will eventually consider Olfaction and combat frequency, but I need to educate myself about that before implementing. As I'm terrifically occupied in RL these days, if someone beats me to it I will be pleased.

StDoodle
05-19-2010, 06:39 AM
As I'm terrifically occupied in RL these days, if someone beats me to it I will be pleased.

I'm having the same issue. So many things I want to get to... but I've barely had time for the things I NEED to get to. *sigh*

Bale
05-19-2010, 06:40 AM
ZLib's has_goal() will eventually consider Olfaction and combat frequency, but I need to educate myself about that before implementing.

Quick primer to how olfaction affects encounter frequency: It adds one additional copy of that monster to the zone and ignores adventure queue rejection for that monster. In other words, if a zone has 3 monsters with equal appearance, let's call them A, B and C then they all have a 33% frequency. If you sniff monster A, then the monsters in that zone are A, A, B and C. Now A has a 50% appearance rate and the other two have 25%. Pretty simple, eh?

Olfaction also changes queue rejection. If a monster is in the queue, then it will be rejected 75% of the time if it is not olfacted. Olfacted monsters are immune to this.

lostcalpolydude
05-19-2010, 07:03 AM
Three additional copies, actually. A, A, A, A, B, C. Using RT's numbers from the wiki (http://kol.coldfront.net/thekolwiki/index.php/On_the_trail) is better, though.

Bale
05-19-2010, 07:36 AM
Oh. Multiplies it by 4! Somehow I was wrong. Then A gets a frequency of 66% while the other two get 17% each. Damn that's powerful!

zarqon
05-19-2010, 08:47 AM
Olfaction, while not straightforward, isn't too hard to figure out from the Wiki. What I need to educate myself about is combat frequency. If someone is running +10% combats in a zone with 8 combats and 2 noncombats, what is their chance of encountering a combat? Is it additive (90%) or multiplicative (88%)?

Bale
05-19-2010, 09:10 AM
Additive, but number of non-combats and combats is irrelevant.

Each zone has a combat frequency which has nothing to do with the comparative quantity of combats and noncombats. Add the +10% to that.

e.g., the combat frequency in Sonofabeach is 10%. 10+10 = 20% combats.

zarqon
05-19-2010, 09:32 AM
So for zones with noncombats, a combat will occur

minmax((combats + 3*trailedmonsterexistsinzone) / noncombats + combat_rate_modifier(), 0, 1.0)

of the time?

I'd still have to figure out the math for the chance that you would encounter monster X in a particular zone. I wrote up a semi-quick formula but realized it was erroneously based on monsters being evenly distributed.

In the meantime, back on topic:

StDoodle, you've mentioned that certain of the quest/adventuring scripts published here are more casual -- they get the job done, but not optimally. As I understand it, this is one of the primary motivations for your project. If any of my scripts match that description, I'd appreciate your feedback on how they might be optimized. My playstyle is rather casual (I don't have time to play optimally), so I may not think of things while scripting that an optimized player would want the script to consider. I think it might be easier to optimize something casual than write something optimal from scratch, especially since many of these scripts have already gone through a fair amount of testing/debugging.

StDoodle
05-19-2010, 09:48 AM
First, I should mention that it's looking like I'm going to be busy for longer than expected. So this project as a whole is on a rather indefinite hold.

The goal -- once I get back to working on it -- is to come up with a framework of information tracking and break various tasks down into the smallest possible chunks, such that they can be reordered and optimized by others more easily. I'd like to come up with something that allows for other scripters to be able to plug-and-play using my scripts, without having to write most of the actual adventuring & quest-progress-checking. I don't intend to make a very "optimal" overall script myself; I'm hoping to come up with enough of the groundwork that better players than myself feel comfortable organizing what gets done & when. That's the goal, anyway. ;)

slyz
05-19-2010, 09:53 AM
You might want to have a look at this post (http://forums.kingdomofloathing.com/vb/showthread.php?t=180294) by Stupac in the KoL G-D forum.

Removing superlikelies, clover adventures and other special cases, the game:

1) first decides if you are going to have a combat or a noncombat.
For a zone with a base combat rate of 60%, you have a minmax((60 + combat_rate_modifier())/100.0, 0, 1.0) chance of getting a combat. Of course, it can be a little more complicated when you have skippable noncombats.

2) then decides which monster or which noncombat you will encounter, where monster appearance rate can be modified by Olfaction or by banishing (and where some zones already contain more than 1 occurrence of a specific monster).

Without considering special cases, the chance of encountering a specific monster will be:
combat_encounter_rate * number_of_occurrences_of_monster/total_number_of_occurrences

That would give you a straight-up average (or whatever it's called in stats), but calculating the variance would be a lot more difficult because it would require taking into account interaction with the queue.

Bale
05-19-2010, 09:56 AM
No. Relative numbers of combats and non-combats are irrelevant. It isn't changed by olfaction. First KoL rolls to see if there is a combat or noncombat. Then it rolls to see which encounter you get of that type. Combat rate is simply this:


float combat_rate(location whereto) {
float [monster] temp = appearance_rates(whereto);
return minmax(temp[$monster[none]] + combat_rate_modifier(), 0.0, 100.0)
}

Edit: It seems that slyz ninjaed me nicely, but I provided the function. :D

zarqon
05-19-2010, 05:33 PM
Ah, that simplifies matters a great deal. I'd been thinking it would be rather tricksy due to Olfaction altering all percentages but combat rate modifier altering one percentage individually, and the others as a group. But this is much simpler. I should be able to add that in fairly quickly.

@Doodle: I've been thinking a lot about algorithms for sorting and optimally ordering possibilities (for some reason...), so in case you're interested, here's how I would script it. It's basically identical to my approach to BatMan -- get all the information available, remove unavailable possibilities, then reduce your remaining possibilities to a single number, sort, and perform the top action. Then repeat.

First, start with the basic idea of my Hardcore Checklist script. All of the actions are in an external data file on the Map Manager which can be expanded and tweaked by anyone. Each action contains, at minimum, the condition that must be true, and what to do if it's not. Presently, it handles:


Adventuring somewhere until certain text appears on a certain page
Adventuring somewhere to get N of a lacking item, unless
- certain text is on a certain page
- you have a certain other item
- you have a certain familiar
- you have disabled the item's quest stream
Yeah, it has options to include a few optional quest streams (i.e. getting a maid, or pre-farming NS tower items), but your script should not hard-code the streams but allow for unlimited streams (covered below).


However, there's plenty that it lacks to be a complete ascension script (it doesn't unlock anything or make anything or use much of anything), or an optimized script. An optimal script should be able to weigh various options (i.e. optimize its actions). Checklist is entirely without decision-making abilities -- it's just a list, in order, of actions to do.

I envision something way cooler for this script. After an action is completed/verified (which could be acquiring an item, unlocking a quest, achieving a certain level, calling a script/function... -- this would all be in the data file -- I actually overloaded the data file format fairly cleverly in Checklist which is why I recommended it as a starting point), the script will rebuild the list of possible actions and perform the most optimal one. This is exactly what BatMan does to calculate combat options; since any number of things could have changed after completing an action, it recalculates (including rebuilding the list of possible actions) after every action.

How would your script build the list? Well, first, you'd painstakingly make a data file containing a list of very specific actions that need doing, akin to Checklist's data file but much more anal, and with three important structural changes: 1) eliminate the safemox field, since ZLib makes that information available quite accurately these days, 2) add a 'stream' field, and 3) add a 'prereq' field. The stream field would contain which quest stream(s) the action belongs to. All actions mandatory for ascension would be one such stream. Another would be a maid. Another (several, actually) would be the Nemesis quest. Another might be a Pagoda. Another would be the White Citadel quest. Another would be pre-farming NS tower items (these should be included in the main stream if you can identify them using your 'scope). You could even include the gnomish neverending NPC quest. But non-mandatory streams could be added in after the main stream was finished, and it wouldn't even be much of a hassle to add since they wouldn't need to be in order.

Why no order? Because the prereq field would simply point to which step must be completed before that action is available. The way I see it, almost every action will have a prereq. So when building the list of available options, if the prerequisite step had not yet been completed, the script would not add that action to the list of possible actions to consider (or, if the action cost nothing, it would just perform it automatically). This means that you would have an action "achieve level N" for every level, and then all of the steps that depend on that level being reached would include that as a prereq -- or they would chain off from there. Bonus: nearly all the hassle about whether you can or can't adventure somewhere would be part of the data file, rather than the script. Another bonus: the action list doesn't need to be in any specific order!

So now, you've built a list in memory of all actually possible actions that have not yet been done for the quest streams which your user has selected (somehow). Now to sort them based on turncount! Turn cost vs. turn profit.

The cost is easy -- once has_goal() accounts for Olfaction/frequency/item-yielding noncombats, you'll be able to pretty accurately predict the number of turns everything will take, and without too much difficulty. Don't include meat cost! Achieving the necessary meat for an action could be a prerequisite action, but don't include the meat as part of the cost, since all actions are necessary to complete your chosen streams, no matter what they cost.

The gain is the hard part to calculate. Stat gain is a big deal, but not for the obvious reason. The only thing it's good for is unlocking things, so it's not really a factor unless you can unlock things that give you more turns! (This is counterintuitive but true, since you have narrowed the field to only necessary actions which you will have to perform at some point.) The hardest part of this calculation will be figuring out whether going up a level would let you eat/drink something that gives you far more adventures than you could eat/drink otherwise. I'm not sure if EatDrink has any speculative abilities built-in, but if so, that would be excellent for this purpose -- compare your predicted food/drink gains at your present level to the predicted gains at the next level and then decide if achieving the next level is possible before eating/drinking. Huge chore, that, and in the meantime you may want to take a "run the actionsorter till only a handful of advs remain; call eatdrink; run the actionsorter again" approach.

After stat gain, there is item gain -- which again, usually counts for nothing except for items that gain you turns. Basically, consider food/item drops to be turns gained, although probably not at a 1:1 ratio. I'd probably add a special action to the list of available actions each iteration -- groceryshop. Basically, for each available zone that drops food/drink, what is the average turn gain per turn spent? Take the best of those, then figure out if turns gained >= turns spent + turns gainable from your current inventory.

After that, most actions won't gain you turns, so you should simply choose the action that gives you the smallest stat gain, since at that point you will actually be getting the largest percent of a level that you will ever get for it.

To sum up, this is the process that the actionsorter would perform after completing every action: iterate through the master list and remove actions already completed, perform free actions (from any stream!), remove actions from unselected quest streams, and remove actions that have unsatisfied prerequisite actions, in that order. Add a consumables-farming action to the list if appropriate. From the remaining actions, perform the highest turn-gaining action (food/drink earners, basically, possibly including leveling), or failing that, the lowest stat-gaining action. Rinse, repeat.

That's the angle I'd come from! :) Hopefully that gives you some food for thought if nothing else!

-----

tl;dr: Everyone! You can buy your own submarine! (http://www.ivccorp.com/sspricing.html)

Rinn
05-19-2010, 06:30 PM
Let's make this list, most of the code to do individual tasks is sitting around on the forum somewhere. We can split it up into manageable chunks, this is too much work for a single person anyway.

heeheehee
05-19-2010, 11:09 PM
once has_goal() accounts for item-yielding noncombats

Yeah, I should finish up that choiceadv.txt map that I've sorta been working on...

zarqon
05-20-2010, 05:03 AM
Perhaps once the action format is decided, people could claim and then post individual levels/quests, with the proper prereq's all in place. Plug 'n' play!

heeheehee
05-20-2010, 05:26 AM
Perhaps...



// Various functions made by people would go here.
string[string] decide() {
// Decide to do stuff here. Return a function to call, and its parameters.
// Index would be the function, according to this rough template.
}
void main() {
while(true) {
string[string] temp = decide();
foreach s in temp
call s(temp[s]);
// Note that we'd get out of this infinite loop by having decide() return
// "abort" (parameter being something like "Turn rundown completed!")
// at some point, since "exit" doesn't work with call. A bit sloppy, I know.
// Unless, of course, you want to work in something for
}
}

slyz
05-21-2010, 01:22 PM
I would like to see things that can be done for whatever goal the script is going for: for example, I would like to use my llama for 2 gongs, then my sandworm for 2 aguas (if I'm doing something that allows me to use a stat familiar).

This wouldn't be in the master list of things to be done, but would be considered once the goal is decided, and the script starts deciding what to do exactly to reach it.

As goals, I would see: reach a stat (or level), get specific items, kill a specific monster, or get a noncombat adventure. Once the goal is decided, either by following a sort of user-scripted list or by making real decisions, a set of buffs to run, a familiar to use, and a combat strategy are decided and the script can finally adventure.

With all this, a 'meat per adventure' total can be computed, with the cost of MP and the expected output of combats (how much MP/HP was spent, meat lost/won), and the set of buffs and/or combat strategy can be derived.

zarqon
05-24-2010, 05:10 AM
The idea of including familiar-item farming (and using, in the case of gongs/absinthe, etc) is excellent, particularly since it usually gains turns. Ideally it would be sensitive to both familiar type and the is_100_run setting. For example, if a goal isestimated to take more than 6 turns to complete, the script could use an absinthe beforehand (and trust a counterScript to handle the !pipe farming).

An important goal type would be to visit a page in search of specific text, which would often be used as a prerequisite. There may also need to be handling for calling internal ASH functions, in case we come across something that can't be performed as one of the predefined actions.