FightOptimizer.ash

[quote author=fewyn link=topic=983.msg5124#msg5124 date=1184268570]
Sadly the latest SVN copy of mafia has completely broken the script :( (Revision: 4224)

I'm getting an error "Start greater than end and increment greater than 0"
[/quote]

Just noticed that myself and fixed it. There were a couple of situations (empty lists, etc) where the script would do a loop like "for i from 1 upto 0". ASH used to not execute the loop at all, now it throws an exception. No big deal, just had to add an extra if statement to get it back to the old behavior.

I've just posted FO 1.0.6 which has this fix and a bunch of other little stuff. Spading was improved, and I've added support for various important quest items -- rock/jam band flyers, molybdenum magnet, and it'll also use an anti-anti-antidote if you get poisoned during combat and have one available. It also reflects the recent TS/LTS change (no longer breaks noodles) and the NS13 Immaculate Seasoning change (no longer gives bonus damage).

Oh, and I went through and added most of the new NS13 items that give bonus melee or spell damage, and updated the items whose bonus changed. There are more item updates still to come.
 

Veracity

Developer
Staff member
[quote author=fewyn link=topic=983.msg5124#msg5124 date=1184268570]
Sadly the latest SVN copy of mafia has completely broken the script :( (Revision: 4224)

I'm getting an error "Start greater than end and increment greater than 0"[/quote]

Yeah.

That's the message you get if you say something like:

Code:
int start = 10, end = 1;

for i from start upto end
    <block>;

But you know, that loop will actually never start, since start is ALREADY greater than end. So, my infinite loop prevention is incorrect.

I'll revisit this. Sorry.
 
I've posted FightOptimizer 1.0.7. Changes:

  • [li]Outfits! Yes, it now takes into account outfit effects. I hadn't really bothered with this before because most players hardly ever went adventuring in a full outfit ... but with NS13 you have to spend a lot of time as a War Hippy and/or Frat Warrior, and each adds +15 damage.[/li]
    [li]Re-improved plinking yet again. (only for AUTOSPADE_AGGRESSIVELY)[/li]
    [li]Updating spading_hp_*.dat with the results of quite a bit of spading. It's now got pretty good coverage of most of the new monsters -- probably 90% or more, and most narrowed down to within 10-20 HP.[/li]
    [li]General improvement of Island Battlefield monsters. There is still a lot of guesswork involved here, but it seems that the HP of these monsters tends to be way above their Atk/Def, so I tried to make the script deal with that.[/li]
    [li]When fighting an unknown monster, it used to sometimes get stuck on attack/TS/LTS/etc strategies when those actions really had no chance of hitting. I've tried to finesse this a bit by having it adjust its ML estimate upward when it misses. Now it should start to realize that the monster is stronger than it thinks and adjust its strategy accordingly.[/li]

This new version needs KoLmafia rev 4235 or later. Because of a minor change in KoLmafia's file_to_map and map_to_file functions, the "spading_hp_min.dat" and "spading_hp_max.dat" files now MUST be placed in your "data" folder, rather than in your "scripts" folder.
 

holatuwol

Developer
[quote author=Harry Crimboween link=topic=983.msg5136#msg5136 date=1184467398]
Because of a minor change in KoLmafia's file_to_map and map_to_file functions, the "spading_hp_min.dat" and "spading_hp_max.dat" files now MUST be placed in your "data" folder, rather than in your "scripts" folder.
[/quote]

That was a mistake, should be fixed.
 
[quote author=holatuwol link=topic=983.msg5137#msg5137 date=1184468388]
That was a mistake, should be fixed.
[/quote]

Yup, verified that it works with the files in the scripts folder again. Thanks!

I've just posted FO 1.0.8, which fixes a major bug: I mixed up a ==/!= when I added the antidote code, so it was never updating the strategy during the fight. That's fixed now. Also, something I hadn't noticed up til now: SSG/Rigatoni no longer uses Myst as your hit stat for staves/chefstaves -- it's back to Muscle. The script now does that correctly, and I filed a bug in Mafia to get that fixed everywhere else too.
 

hairball

New member
I tried using this script as a level 14 disco bandit. With 221 (buffed) moxie I should have been able to do just about anything and win the battles (giant's castle) but it kept telling me it couldn't find a winning strategy. I switched to "Attack with weapon" and used my turns that way instead.

Any clue what could be the problem?
 

hippymon

Member
How does it work? It keeps saying "please input a value for string round/encounter/page strings and I have NO clue what to put in there.
 

muffins

Member
[quote author=hippymon link=topic=983.msg5201#msg5201 date=1185156358]
How does it work? It keeps saying "please input a value for string round/encounter/page strings and I have NO clue what to put in there.
[/quote]

Are you using it as a Custom Combat Script, or calling it from the scripts menu? :eek:

Try using "consult fightoptimizer.ash" as your "default" custom combat script (replace attack or whatever you currently have in there), and it should work.
 
[quote author=hairball link=topic=983.msg5192#msg5192 date=1185055808]

I tried using this script as a level 14 disco bandit.  With 221 (buffed) moxie I should have been able to do just about anything and win the battles (giant's castle) but it kept telling me it couldn't find a winning strategy.  I switched to "Attack with weapon" and used my turns that way instead.  

Any clue what could be the problem?
[/quote]

Short answer: you can fix this by modifying the monster_hit_percentage routine and commenting out the "return 1.0;" line so that it actually does the full computation.

Long answer: Right now FO doesn't assume that you're ever safe from attack ... it assumes the monster will hit you every round. This is kind of a compromise in its logic. I originally wrote the script with full monster hit calculation (obviously, since it's still there!). But I found that it would sometimes perform too optimistically, figuring that you're "safe enough" when in fact a single lucky hit by the monster might wipe you out. In any single battle that usually wouldn't happen. But when I ran it for 200+ turns a day, with a lot of +ML, I found that it happened often enough to be annoying. (For example, as a Moxie class I could usually avoid getting hit when fighting suits of armor in the Haunted Gallery. But man, that 6% of the time when they did connect would kill me in one blow.) Cranking up the monster_hit_percentage to 100% made it pessimistic enough to fix that.

But that might have been an overcorrection. I've noticed similar issues -- sometimes it'll waste MP casting Entangling Noodles when I know my Moxie is high enough that it doesn't really need to. Kind of annoying in a HC run.

I think what I'd really like to do is somewhere in the middle: have the battle simulator assume that you're going to get hit ONCE at 100% likelihood, and then do the rest of the rounds using the actual moxie-based monster hit percentage. Assuming a single hit lets it try to deal with the chance of a single monster critical hit without being way too pessimistic -- after all, the odds of a single monster critical is around 6%, but two monster criticals in a row is only 0.3%, and three in a row is just .02%. With that change it'll still strive to keep your HP above the necessary minimum level to survive a single hit, but after that it can whack away at the monster with impunity.
 

hairball

New member
[quote author=Harry Crimboween link=topic=983.msg5225#msg5225 date=1185302453]


Short answer: you can fix this by modifying the monster_hit_percentage routine and commenting out the "return 1.0;" line so that it actually does the full computation.

Long answer: Right now FO doesn't assume that you're ever safe from attack ... it assumes the monster will hit you every round. This is kind of a compromise in its logic. I originally wrote the script with full monster hit calculation (obviously, since it's still there!). <snip>
[/quote]

That makes sense. :) Actually I think my problem was that I was using a bottle-rocket crossbow. When I switched to a cerebral crossbow the script chose "attack" most of the time.
 
[quote author=hairball link=topic=983.msg5233#msg5233 date=1185330963]
That makes sense. :)   Actually I think my problem was that I was using a bottle-rocket crossbow.  When I switched to a cerebral crossbow the script chose "attack" most of the time.  
[/quote]

That could also have something to do with it ... brand-new items can be difficult because sometimes either KoLmafia doesn't know their power, or it doesn't know that it's a ranged weapon, or something similar like that. That usually gets resolved in a couple of days if you're running from SVN though.

Also, the cerebral crossbow is a little stronger (roughly the same weapon power, but with +9 elemental damage) so maybe the simulator finished in fewer rounds, i.e. before it figured the monster would kill you.
 

fewyn

Administrator
Staff member
Looks like the latest build 4557 has broken this again :(

Undefined reference 'replace_string' (FightOptimizer.ash, line 2480)
Consult script 'FightOptimizer.ash' not found.
 
[quote author=fewyn link=topic=983.msg5305#msg5305 date=1185828613]
Looks like the latest build 4557 has broken this again :(

Undefined reference 'replace_string' (FightOptimizer.ash, line 2480)
Consult script 'FightOptimizer.ash' not found.
[/quote]

It looks like there's some stuff happening in ASH - a few new types for string manipulation and regex handling. I don't know if replace_string was intentionally dropped or if it will be coming back ... until we hear for sure, here's an equivalent function that you can paste into the "Workarounds" section of the script:

Code:
string replace_string(string s, string a, string b) {
	int i = index_of(s, a);
	while (i >= 0) {
		s = substring(s,0,i) + b + substring(s,i+length(a));
		i = index_of(s, a, i+length(b));
	}
	return s;
}




Okay, with 4568 replace_string is back, but all the prototypes for most combat actions have changed to return a buffer instead of a string. This breaks things badly, giving the message:

"Cannot store buffer in PAGE of type string (FightOptimizer.ash, line [all over the place])"

There's no one-line workaround, but to get it working temporarily you can change things like "throw_item(foo)" to "to_string(throw_item(foo))". You'll need to change the calls for throw_item(), throw_items(), attack(), steal(), and replace_string() at least ... there may be others.

If any devs are watching this, automatic type coercion from buffer to string (and vice-versa) would be nice. :)
 

holatuwol

Developer
[quote author=Harry Crimboween link=topic=983.msg5306#msg5306 date=1185842353]
automatic type coercion from buffer to string
[/quote]

Done.


[quote author=Harry Crimboween link=topic=983.msg5306#msg5306 date=1185842353]
(and vice-versa)
[/quote]

This ... is a little more complicated. If I were to do this, I'd probably just get rid of the buffer type and make all strings work like buffers.
 
[quote author=holatuwol link=topic=983.msg5312#msg5312 date=1185926780]
This ... is a little more complicated.  If I were to do this, I'd probably just get rid of the buffer type and make all strings work like buffers.
[/quote]

Fair enough. At least the one direction works. :)
 

izchak

Member
I'd just like to thank Harry for writing this script, its extremely useful!
I'd also like to thank all those who've helped make it possible, including hola, veracity, et al.

I have encountered a rather strange issue, though. Well, its not really a critical problem, but it appears to be a bug. (I'm doing casual ascensions, so a misoptimization of a few meat is trivial, but for someone in hardcore, with less resources, it could be the difference between winning and losing a battle.)
FightOptimizer strategy: Entangling Noodles, Shieldbutt (95 meat)
Round 1: izchak casts ENTANGLING NOODLES!
Round 1: skeletal sommelier takes 132 damage.
You did 162 damage with your Entangling Noodles. (p=0,t=162)
FightOptimizer adjusted strategy: Minor Ray of Something, Shieldbutt (20 meat)
Round 2: izchak casts MINOR RAY OF SOMETHING!
Round 2: skeletal sommelier takes 88 damage.
You did 118 damage with your Minor Ray of Something. (p=33,t=280)
FightOptimizer adjusted strategy: Minor Ray of Something (15 meat)
Round 3: izchak casts MINOR RAY OF SOMETHING!
Round 3: skeletal sommelier takes 177 damage.
You gain 116 Meat
You acquire an item: dusty bottle of Merlot
You acquire an item: dusty bottle of Marsala
You acquire an item: dusty bottle of Muscat
You acquire an item: disintegrating cork
You gain 21 Strongness
You gain 37 Magicalness
You gain 10 Cheek
You did 207 damage with your Minor Ray of Something. (p=33,t=487)
I've emboldened the relevant parts, the reported damage from mafia, and the reported damage from FO. In most combats, FO appears to be under the impression that I'm doing about 30 damage more than I actually am.
(FWIW: I'm using mafia build 4539)
Oh, and the 132 damage from my entangling noodles is correct, its my wizard attacking with his built in attack, AND the plastic pumpkins bucket attack, hitting for perfect elemental damage against a sommeliers hot damage weakness.

I can provide more detailed logs, if you desire.
It's possible that my new wizard familiar is causing some of these issues, although it isn't immediately obvious how or why, mafia is getting the accurate count of damage, even factoring in the damage done by my wizards attacks AND the damage done with my pumpkin bucket. From where I'm standing, it looks like FO is adding an extra 30 damage, although I dont know where.

I also have a suggestion or two, although I realize implementing them is potentially tricky...


  • [li]Spheres and sauceror spells. These reduce running costs significantly, and in many instances, make sauceror spells cheaper than the alternatives (butts), especially as a sauceror.[/li]
    [li]Sauceror spell combos, especially wave of sauce. If (somehow) we KNOW that the next spell will be of the right element, and a wave of sauce wont one-shot a monster, its worth using a wave combo, since you usually come out with more MP than you came in with.[/li]
    [li]Delevel spading with the wizard familiar. Is it possible to spade out the wizards delevelling with this script, with the appropriate AUTOSPADE_AGGRESSIVE settings set, known ML, and already spaded monsters?[br]Otherwise, tracking down the exact amount of delevelling going on will be rather tricky...[/li]

Oh, and a final BTW, I made this small modification to my FO, I found it useful:
Code:
int[item] plink_damage;
plink_damage[$item[spices]] = 1;
plink_damage[$item[turtle totem]] = 1;
plink_damage[$item[seal tooth]] = 1;
plink_damage[$item[spectre scepter]] = 4;
foreach i in plink_damage {
	if (item_amount(i) > 1) {
		if(plink == $item[none]) {
			plink = i; plink2 = i; 
		} else if( plink_damage[i] > plink_damage[plink]) {
			plink = i; plink2 = i;
		}
	} else if (item_amount(i) > 0) {
		if (plink == $item[none])
			plink = i;
		else
			plink2 = i;
	}
}
The Spectre scepter does more than 4 damage when it does damage, but between 4 different attacks, with 2 of them doing damage, I approximated 4 to being close enough.
Ideally, I'd like to add the toy mercenary in there, but I don't know how to add to the current meat cost of the battle, since the mercenary takes a known amount of meat per use...
 

raorn

Member
What about 31337 scrolls? It should have preference over 64735 scroll if you have at least one OR Orc Chasm quest is completed.

UPD: Sorry, I see the code. Great script, thanks!
UPD2: But it doesn't check if Orc Chasm quest completed. Is it possible at all?
 

fewyn

Administrator
Staff member
Anyone actually working on this anymore? As of late I can't even get it to work at all it just locks up when I use it in my CCS.
 
Top