CounterChecker: Wormwood, Semi-rares, Dance Cards and more

slyz

Developer
I think the script is missing a break after line 344 (and perhaps a check to see if chapel_weapon() returns $item[none], but that is a separate issue that just happened to appear here).

I'm stumped as to why maximizing for "weapon, +offhand, +equip continuum transfunctioner" failed though.
 

Theraze

Active member
If you don't explicitly say 1 hand, it will pick the best possible that meets its request... which in your case was apparently the 2-handed skate board.
 

shazbot

Member
I've been throwing this idea around for a bit and decided to write it up and give it a test. The short explanation is, when you have a random adventure interrupt your wormwood adventure (dio de la muerte adventure, nemesis goon, turkey day) it can throw off your counter. CounterScript does not handle these, so I figured I'd put in shortcuts to prevent wasting adventures. But then I expanded it a bit and let you shortcut to stat gains if you do miss an adventure (with the ability to set the stat gain only for the last wormwood count). I'm weary to include the whole file, because I don't want to cause confusion, but below is the diff based off of the latest fireflower release (also included is my hack to get around my weird clan basement issue, you can ignore that if you want). It is a bit hacky, but I did a decent chunk of testing against it today-

Code:
539d538
<         string toRet = "";
544,545c543
<                       toRet = "not-a-pipe ";
<             break;
---
>                       return "not-a-pipe";
550,551c548
<                       toRet = "flask of Amontillado ";
<             break;
---
>                       return "flask of Amontillado";
558,559c555,561
<                       toRet = "S.T.L.T. ";
<             break;
---
>                       return "S.T.L.T.";
>               case contains_text(goal, "mus"):
>                       return "Muscle";
>               case contains_text(goal, "mox"):
>                       return "Moxie";
>               case contains_text(goal, "mys"):
>                       return "Mysticality";
564,565c566
<                       toRet = "fancy ball mask ";
<             break;
---
>                       return "fancy ball mask";
569,570c570
<                       toRet = "albatross necklace ";
<             break;
---
>                       return "albatross necklace";
574,583c574,576
<                       toRet = "Can-Can skirt ";
<             break;
<         }
<               switch {
<               case contains_text(goal, "mus"):
<                       return toRet + "Muscle";
<               case contains_text(goal, "mox"):
<                       return toRet + "Moxie";
<               case contains_text(goal, "mys"):
<                       return toRet + "Mysticality";
---
>                       return "Can-Can skirt";
>               default:
>                       abort("Invalid goal!");
585c578
<               return toRet;
---
>               return "";
593,595c586
<       } else {
<         if (turns == "9-5-1")
<             turns = "5-1";
---
>       } else
597d587
<     }
621,624d610
<         // Patch to fix weird visits to clan basement
<         while (contains_text(last_adventure, "basement"))
<             last_adventure = visit_url(to_url(l));
< 
631c617
<         }
---
>               }
641,706d626
< string wormwood_check_goal(string wwgoal, int turn) {
<     string[int] goals = split_string(wwgoal, " ");
<     string goal = goals[0];
<     string altGoal = "";
<     if (count(goals) >= 2)
<         altGoal = goals[1];
< 
<     if (turn > 5)
<         return goal;
<     if (turn > 1)
<         turn = 5;
< 
<       switch(goal) {
<       case "not-a-pipe":
<         if (turn == 5 && have_effect($effect[Spirit of Alph]) > 0)
<                       return goal;
<         if (turn == 1 && have_effect($effect[Feelin' Philosophical]) > 0)
<                       return goal;
<         goal = altGoal;
<         break;
<       case "flask of Amontillado":
<         if (turn == 5 && have_effect($effect[Rat-Faced]) > 0)
<                       return goal;
<         if (turn == 1 && have_effect($effect[Night Vision]) > 0)
<                       return goal;
<         goal = altGoal;
<         break;
<       case "S.T.L.T.":
<         if (turn == 5 && have_effect($effect[Bats in the Belfry]) > 0)
<                       return goal;
<         if (turn == 1 && have_effect($effect[No Vertigo]) > 0)
<                       return goal;
<         goal = altGoal;
<         break;
<       case "fancy ball mask":
<         if (turn == 5 && have_effect($effect[Spirit of Alph]) > 0)
<                       return goal;
<         if (turn == 1 && have_effect($effect[Dancing Prowess]) > 0)
<                       return goal;
<         goal = altGoal;
<         break;
<       case "albatross necklace":
<         if (turn == 5 && have_effect($effect[Rat-Faced]) > 0)
<                       return goal;
<         if (turn == 1 && have_effect($effect[Unusual Fashion Sense]) > 0)
<                       return goal;
<         goal = altGoal;
<         break;
<       case "Can-Can skirt":
<         if (turn == 5 && have_effect($effect[Bats in the Belfry]) > 0)
<                       return goal;
<         if (turn == 1 && have_effect($effect[Good with the Ladies]) > 0)
<                       return goal;
<         goal = altGoal;
<         break;
<     }
<     switch(goal) {
<       case "Muscle":
<       case "Moxie":
<       case "Mysticality":
<         return goal;
<       }
<       return "";
< 
< }
< 
725,730c645
<         string goal = wormwood_check_goal(wwgoal, left);
<         if (goal == "")
<             return true;
<         location loc = wormwood_location(goal, left);
<         print(goal + " " + loc);
<               return getChoiceAdv(to_do, loc, goal);
---
>               return getChoiceAdv(to_do, wormwood_location(wwgoal, left), wwgoal);
 

Theraze

Active member
I think the current CounterChecker should still work since the change to the Continuum Transfunctioner, but the 1 hand/offhand part of the maximize string can be removed now... this line should work better:
Code:
 string gear = "+weapon, +equip continuum transfunctioner";
 

Bale

Minion
I don't like that since the script could hurt the character's maximum HP or MP by unequipping a vital accessory. Also, MP regen is nice to have for that turn. I want to be sane about what to do with the character's accessory slots. I suppose I could check all accessories and look for one that does not benefit the character on this turn, but that would be a LOT of work. Here's my simplistic but helpful solution:


Released CounterChecker v1.4997

This is the continuum accessory release.
 
Last edited:

Winterbay

Active member
As a good script user I am now doing as asked and posting this output here:
Code:
[71] Tavern Cellar (row 3, col 1)
Encounter: drunken rat
Strategy:     M:\Mafia\ccs\PM.ccs [default]
Round 0: winterbay wins initiative!
You     lose 5 hit points
Monster: Drunken Rat, ATT: 10,     DEF: 10, HP: 8, Value: 525
Profit per round:                             Action                          Profit                          Damage                          Other                                      base; Li'l Xenomorph (0μ)                          0μ                          --                                                
    You will die in 334 rounds.
Your     attack will kill the monster in 1 rounds.
SpamAttack:     Monster HP is 8.0.
SpamAttack: You will     kill the monster in 1 rounds with your basic attack.
SpamAttack:     The monster will take more than 30 rounds to kill you.
SpamAttack:     Monster is weak. We are just going to bash its head in. It'll take 1     rounds.
Round 1: winterbay executes a macro!
Round 1:     winterbay attacks!
Round 2: drunken rat takes 13 damage.
Round 2:     winterbay wins the fight!
You gain 16 Meat
You acquire an item: rat     whisker
After Battle: Grot smiles on the inside. Unlike all other     life-forms, it's doing it literally, with its second set of jaws.
You     gain 5 Mysteriousness
You gain a Mysticality point!
You gain 2     Sarcasm
Look! You found 1 rat whisker (0μ)!
Expiring     counter, not fighting items.
MCD: none has     no known combats.
Checking counters now.
3     tasty tarts are is currently selling for 5348 meat each.
BaleCC_next =>     Haunted Pantry

BBB: Haunted Pantry contains a     nice semi-rare; not auto-eating cookie. Eat one manually if you want your     counterScript to handle it.
MCD: adjusting     to 10...
Resetting mind control device...
Mind control device     reset.

Visit to Manor1: Haunted Pantry in progress...

[72]     Haunted Pantry
Encounter: The Pilsbury Doughjerk
You acquire tasty     tart (3)

Something went wrong determing the best     semi-rare. Please copy-paste this output to     http://kolmafia.us/showthread.php?t=2519
scented massage oil     sells for 5499 meat.
SPF 451 lip balm sells for 1249 meat.
Mick's     IcyVapoHotness Inhaler sells for 17000 meat.
shrinking powder sells for     550 meat.
Please continue manually. Sorry for the bug

As you can see it got the semi-rare and then crashed when deciding on the next one. Or that's what I guess it did...
 

Bale

Minion
Huh? Thanks. That debug was put into the script a long time ago because someone was getting a puzzling error. This is the first time it has been reported since then. It's still pretty puzzling. I'll have to mull this over.
 

slyz

Developer
I don't really understand why so few semi-rare prices were checked. How was Counter Checker called in the first place?
 

slyz

Developer
I mean, why were so few semi-rare prices printed. The prices weren't exactly checked, the historical prices were used instead

This code:
PHP:
foreach locale, rare in semi_rare
	print(rare+" sells for "+historical_price(rare)+" meat.");
and this output:
Code:
scented massage oil sells for 5499 meat.
SPF 451 lip balm sells for 1249 meat.
Mick's IcyVapoHotness Inhaler sells for 17000 meat.
shrinking powder sells for 550 meat.
means that something tampered with semi_rare, and I don't see any code in CounterChecker that does that.

No "best" location was chosen because he probably couldn't adventure in any of these locations (Harem, Friars, Castle and Hidden City).

There was also no reason for mafia to call CounterChecker since no counter had run out (no "Checking counters now." message). My guess is that a custom betweenBattle script is using CounterChecker to set BaleCC_next, and the semi_rare map is reduced to only the semi-rares he wants to get in-run.
 
Last edited:

Bale

Minion
I haven't figured out much yet, but I can answer this:

There was also no reason for mafia to call CounterChecker since no counter had run out (no "Checking counters now." message). My guess is that a custom betweenBattle script is using CounterChecker to set BaleCC_next, and the semi_rare map is reduced to only the semi-rares he wants to get in-run.

tl;dr: checking after getting the SR is normal behavior for CC.

Long form: CounterChecker checks the price for the NEXT semi-rare. This is for coordination between CounterChecker & BestBetweenBattle so that the character won't need to eat a cookie if he's adventuring in the same zone that his best semi-rare will appear. If he leaves the zone BBB will eat the cookie.
 

slyz

Developer
There was also no reason for mafia to call CounterChecker since no counter had run out (no "Checking counters now." message).
There was a "Checking counters now." message in Winterbay's log, I missed it because it was before the BBB output. Oh well, I'm stumped too then.

I still think it's possible that Winterbay modified CounterChecker somehow to force it to get a certain set of SRs in-run, though :)
 

Winterbay

Active member
I have modified the map to look like below, but my modified hardcore map contains both distilled wine and tasty tarts so that should not be a problem as those places are always available.

Code:
if(can_interact())
{
	semi_rare[$location[Haunted Billiards Room]] = $item[cube of billiard chalk];
	semi_rare[$location[Menagerie 2]] = $item[irradiated pet snacks];
	semi_rare[$location[Outskirts of The Knob]] = $item[Knob Goblin lunchbox];
	semi_rare[$location[Limerick Dungeon]] = $item[cyclops eyedrops];
	semi_rare[$location[Sleazy Back Alley]] = $item[distilled fortified wine];
	semi_rare[$location[Haunted Pantry]] = $item[tasty tart];
	semi_rare[$location[Harem]] = $item[scented massage oil];
	semi_rare[$location[Haunted Kitchen]] = $item[freezerburned ice cube];
	semi_rare[$location[Haunted Library]] = $item[black eyedrops];
	semi_rare[$location[Goatlet]] = $item[can of spinach];
	semi_rare[$location[Ninja Snowmen]] = $item[bottle of antifreeze];
	semi_rare[$location[Orc Chasm]] = $item[ASCII shirt];
	semi_rare[$location[Battlefield (No Uniform)]] = $item[six-pack of New Cloaca-Cola];
	semi_rare[$location[Batrat and Ratbat Burrow]] = $item[Dogsgotnonoz pills];
	semi_rare[$location[Giant's Castle]] = $item[Mick's IcyVapoHotness Inhaler];
	semi_rare[$location[Guano Junction]] = $item[Eau de Guaneau];
	semi_rare[$location[Laboratory]] = $item[bottle of Mystic Shell];
	semi_rare[$location[Pre-Cyrpt Cemetary]] = $item[poltergeist-in-the-jar-o];
	semi_rare[$location[Post-Cyrpt Cemetary]] = $item[poltergeist-in-the-jar-o];
	semi_rare[$location[South of The Border]] = $item[donkey flipbook];
	semi_rare[$location[Pandamonium Slums]] = $item[SPF 451 lip balm];
	semi_rare[$location[Hidden City]] = $item[shrinking powder];
	semi_rare[$location[8-Bit Realm]] = $item[fire flower];
	semi_rare[$location[Spooky Forest]] = $item[fake blood];
	semi_rare[$location[Whitey's Grove]] = $item[bag of lard];
	semi_rare[$location[Hippy Camp]] = $item[teeny-tiny magic scroll];
	semi_rare[$location[Frat House]] = $item[bottle of rhinoceros hormones];
	semi_rare[$location[Pirate Cove]] = $item[bottle of pirate juice];
	semi_rare[$location[The Purple Light District]] = $item[lewd playing card];
	semi_rare[$location[Burnbarrel Blvd]] = $item[jar of squeeze];
	semi_rare[$location[Exposure Esplanade]] = $item[bowl of fishysoisse];
	semi_rare[$location[The Heap]] = $item[concentrated garbage juice];
	semi_rare[$location[The Ancient Hobo Burial Ground]] = $item[deadly lampshade];
	semi_rare[$location[Chapel]] = $item[pixel stopwatch];
}
else //Rares interesting in a hardcore run
{
	//semi_rare[$location[Outskirts of The Knob]] = $item[Knob Goblin lunchbox];
	semi_rare[$location[Sleazy Back Alley]] = $item[distilled fortified wine];	
	semi_rare[$location[Haunted Pantry]] = $item[tasty tart];	
	semi_rare[$location[Harem]] = $item[scented massage oil];
	semi_rare[$location[Giant's Castle]] = $item[Mick's IcyVapoHotness Inhaler];			
	semi_rare[$location[Hidden City]] = $item[shrinking powder];
}

Edit: Lunchbox commented out due to me running b-runs at the moment.
 

Theraze

Active member
Also, Winterbay, a better way to do the lunchbox thing is to throw a be_good check at the expensive_semi function... probably right here:
Code:
 foreach locale, rare in semi_rare {
  if(!canadv(locale)) continue;
  if(historical_age(rare) > 1 || historical_price(rare) == 0)
   mall_price(rare);
  rare_price = historical_price(rare) * ((rare_quant contains rare)? rare_quant[rare]: 1); 
  if(rare_price > expensive) {
   best = locale;
   expensive = rare_price;
  }
 }
turning it into this:
Code:
 foreach locale, rare in semi_rare {
  if(!canadv(locale) || !be_good(rare)) continue;
  if(historical_age(rare) > 1 || historical_price(rare) == 0)
   mall_price(rare);
  rare_price = historical_price(rare) * ((rare_quant contains rare)? rare_quant[rare]: 1); 
  if(rare_price > expensive) {
   best = locale;
   expensive = rare_price;
  }
 }
Note the change to the second line... we're importing zlib anyways, so we may as well make use of zlib's be_good function to check if the item is usable currently. In a non Beecore run, the item will be a possible choice. In a Beecore run, it will be skipped. Actually, I may leave that change on mine. :) Probably not a good one to put into the main source, since it's running based on what will sell best in the mall currently, but for personal use? It helps.

Edit: Any other changes you've made to your file... to skip acquisition of semirares you already have enough of, for example?
 

Winterbay

Active member
Nope, I've just set it to only consider the ones I'm interested in. Although I do have a multiplier added to inhalers and shrinking powders even though I'm not sure if those are actually useful.
 

Theraze

Active member
Not sure why it would reject the option of distilled then, since what you quoted us should have considered it to be valid.
 

Banana Lord

Member
CounterChecker seems to be doing odd things for me too:
Code:
Checking counters now.
Maximizing...
1 combinations checked, best score 2.0
3 bottles of distilled fortified wine are is currently selling for 7200 meat each.
Placing items into closet...
Transfer failed for ten-leaf clover (3)
Fortune Cookie counter expired. Last semirare found 179 turns ago (on turn 29594) in Outskirts of The Knob

EDIT: Never mind, mafia was just confused. For some reason it thought I had 3 clovers in my inventory when I had none.
 
Last edited:

Raven434

Member
When I open the version on the front page, it says 1.4996 is the version. I don't think I saw 1.4997 attached in any of the recent pages, or did I miss it?
 

Theraze

Active member
No it doesn't... when you download the version from the front page and open it, it says that 1.4997 is the version, released on 6/22/11. When you look at the changelog post, number 2, it says that 1.4996 was released on 2/16/11, over 4 months before. Post 406 had the change note for 1.4997, which realized that the CT was an accessory instead of being an offhand. But hey, that was all of one page back, I can understand why it was hard to find. ;)
 
Top