Semi Rare adventuring

ckb

Minion
Staff member
I know Mafia will keep track of the Semi Rare counters from eating fortune cookies, but I do not know how to incorporate them into a script. I know I can get the string from get_property("relayCounters"), but I am not sure how to parse this, expecially if the the turncount is changing # of digits.

Is there a way to do this easily?

Thanks,

ckb
 

Veracity

Developer
Staff member
It's not quite as easy as I thought (in another response on the main forums) but my understanding is this:

That preference contains the currently active counters and an absolute "turn count" when they will go off.
Subtract your current turn count (relative to the beginning of this run) and that is how many turns before the counter expires.
I know how to get get this run's turn count within KoLmafia's Java code, but I've never looked at how to get it from ASH.

If you can get it, parse away.
If you can't, either it needs to be made available, or a better scripting interface to the counters needs to be made available, or both.
 
Scripting adventures isn't my thing anymore, but:

> ashref turn

int my_turncount( )
int turns_played( )
int turns_per_cast( skill )

> call C:\Documents and Settings\\Desktop\KOL\Kolmafia-Efilnikufecin\scripts\test.ash

30032
30032

test.ash contains:
Code:
print( my_turncount( ));
print( turns_played( ) );

My turn count this run: 30,032
My Lifetime turn count: 175,585

So that will get you this runs turn count, but as for the turn count in which a semi-rare will occur, I don't know.
 

ckb

Minion
Staff member
It is really easy to get the current turncount, with the function appropriately named my_turncount()

The real problem is the parsing... I have not used ASH in a long time (since way before NS13) and it looks like there was a bunch of string handling routines added.

using get_property, the string looks like:

6403\:Fortune Cookie\:fortune.gif\:6250\:Fortune Cookie\:fortune.gif\:6404\:Fortune Cookie\:fortune.gif

The problem is, how do I do the parsing, knowing it could be something shorter or longer with fewer or more digits?

ckb


Edit: thinking about this more, you can use the knowledge of your current turncount to determine the number of digits you should have, and use string_length() to verify... then extrat the numbers from the begining, middle and ends, but this seems WAY more complicated than it should be.
 
you need to use
int index_of( string source, string search )
and/or
int index_of( string source, string search, int startfrom )
to locate the positions of the : and \

Next, use
string substring( string source, int start, int end )
to extract what you want,

you will probably need to subtract or add 1 to the variables you stored the results of the index_of functions above in. use
void print( string )
for debugging till you get the expected results.

then store the result in an int for math style access.




alternately you could do in a script what I do manually:

I adventure in a location til I get the semi-rare, then go somewhere else for 160 adventures, then go to a semi rare location til I get it again, repeat constantly handling bounties during the 160.
 

ckb

Minion
Staff member
OK, I have it working. Its ugly and I can't really test it until I get more adventures and reset my fullness tomorrow, but its just a matter of polish now.

I'll post my script in the next day or so when I am sure it works.

ckb
 

ckb

Minion
Staff member
Well, after some testing, it mostly works sometimes. The problem is that the semi-rare counter forces a stop adventure, so scripting through invalid #s is not possible.

Example, I get a SR, adventure 20 times, then get 3 numbers from a fortune cookie: 50, 160, 255

I know semi-rares occur about every 160-190 turns, so I should hit the SR in 160 turns as this is the only valid counter. However, if I include something like "adventure( 160, location)" I will hit a stop after 50 adventures.

The counter WILL have expired, but it won't be the correct counter. Is there a way to disable the incorrect stop adventure for the counter that is too low?

ckb
 

kain

Member
I think if you eat two, and get a single matching number, then Mafia will know for sure what the correct counter is. I don't have any fullness to test with, though
 

gemelli

Member
Here's some basic, barely-functional ASH code to use as a starter for something more serious:

Code:
void main() {
	int turnsplayed=my_turncount();
	string foo=get_property("relayCounters");
	int bar=index_of(foo,":Fortune");
	if(bar==-1) print("Fortune cookie counter not found.");
	else {
		string result=substring(foo,0,bar);
		int resnum=to_int(result);
		int togo=resnum-turnsplayed;
		print("Semirare expected on turn "+result+", in "+togo+" turns.");
	}
}

Issues include:

  • [li]Will often fail when multiple counters are active[/li]
    [li]Will arbitrarily use the first value stored in the appropriate Mafia property when only one cookie has been consumed[/li]

But it's doing the trick for me in my Bad Moon runs, at least for the time being. Bad Moon limits my ability to test the multiple-counters active scenario, so for now that's all I can really do.
 
Top