SafeGuide -- quickly identify the locations most suitable for your level

zarqon

Well-known member
[size=+1]SafeGuide 1.3[/size]

There have been a few times in my runs when I finish up all my available quests, and I haven't been using a stat familiar, and I'm stuck. I can't get any more quests until I level up. So, I need to know where I can adventure for a while to level up for maximum stat gain, but without getting beaten down (funny how "beaten down" and "beaten up" mean the same thing).

Wouldn't it be nice, thought I, if there were a script that would just tell you where the best areas were for your level?

Yes, yes it would. So I decided to write such a script, and the result is what you have here. SafeGuide will list the combat locations that are closest to your level, allowing you to make more educated choices about where you can go in these stuck situations.

What does it do?
Displays nearby (in terms of safemox) locations in a convenient, easy-to-read format.

Details
No really, that's all it does.

Oh, it does use the "threshold" script setting also used by Checklist, First Things First, BBB, and any other scripts designed to work with it. That setting can be found in your vars_myname.txt file.

How to use it:
  • Download Safe.ash to your scripts directory.
  • Download ZLib if you yet haven't.
  • Run the script using mafia by a) selecting it from the scripts menu, or b) typing "call safe" in the CLI window. I find the CLI method to be handier.

Changelog
12.04.08 - ver. 1.0 posted.
12.15.08 - ver. 1.1 changes: faster method of populating location map using new to_location(int) ASH function. Small optimization to get_safemox(). Added version check (previously had the function but forgot to call it!)
6.14.09 - ver. 1.2 changes: moved some functions out -- now requires ZLib.
7.25.09 - ver. 1.3 changes: compatible with the new ZLib.
 

Attachments

  • Safe.ash
    2.2 KB · Views: 309
Last edited:

dj_d

Member
I feel like a broken record, but... thank you! I was planning to write this and you saved me the hassle. :) Can't wait to try it.
 

asturia

Minion
Is it possible the script doesn't work anymore with the latest daily builds?
update: version of kolmafia doesn't matter.
Here is a debug log:
Code:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      KoLmafia r6570, Windows XP, Java 1.6.0_10
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Please note: do not post these logs in the KoLmafia thread. If 
 you would like us to look at the log, please instead email logs 
 to [email]holatuwol@hotmail.com[/email] using the subject "KoLmafia Debug Log" 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Timestamp: Mon Dec 15 15:44:39 CET 2008
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


Unexpected error, debug log printed.
class java.lang.NullPointerException: null
java.lang.NullPointerException
	at net.sourceforge.kolmafia.textui.RuntimeLibrary.get_monsters(RuntimeLibrary.java:2978)
	at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at net.sourceforge.kolmafia.textui.parsetree.LibraryFunction.execute(LibraryFunction.java:119)
	at net.sourceforge.kolmafia.textui.parsetree.FunctionCall.execute(FunctionCall.java:157)
	at net.sourceforge.kolmafia.textui.parsetree.Assignment.execute(Assignment.java:89)
	at net.sourceforge.kolmafia.textui.parsetree.Scope.execute(Scope.java:353)
	at net.sourceforge.kolmafia.textui.parsetree.UserDefinedFunction.execute(UserDefinedFunction.java:125)
	at net.sourceforge.kolmafia.textui.parsetree.FunctionCall.execute(FunctionCall.java:157)
	at net.sourceforge.kolmafia.textui.parsetree.Assignment.execute(Assignment.java:89)
	at net.sourceforge.kolmafia.textui.parsetree.Scope.execute(Scope.java:353)
	at net.sourceforge.kolmafia.textui.parsetree.UserDefinedFunction.execute(UserDefinedFunction.java:125)
	at net.sourceforge.kolmafia.textui.parsetree.FunctionCall.execute(FunctionCall.java:157)
	at net.sourceforge.kolmafia.textui.parsetree.Scope.execute(Scope.java:353)
	at net.sourceforge.kolmafia.textui.parsetree.Conditional.execute(Conditional.java:88)
	at net.sourceforge.kolmafia.textui.parsetree.If.execute(If.java:67)
	at net.sourceforge.kolmafia.textui.parsetree.Scope.execute(Scope.java:353)
	at net.sourceforge.kolmafia.textui.parsetree.Loop.execute(Loop.java:57)
	at net.sourceforge.kolmafia.textui.parsetree.ForEachLoop.executeSlice(ForEachLoop.java:130)
	at net.sourceforge.kolmafia.textui.parsetree.ForEachLoop.execute(ForEachLoop.java:96)
	at net.sourceforge.kolmafia.textui.parsetree.Scope.execute(Scope.java:353)
	at net.sourceforge.kolmafia.textui.parsetree.Loop.execute(Loop.java:57)
	at net.sourceforge.kolmafia.textui.parsetree.ForEachLoop.executeSlice(ForEachLoop.java:130)
	at net.sourceforge.kolmafia.textui.parsetree.ForEachLoop.execute(ForEachLoop.java:96)
	at net.sourceforge.kolmafia.textui.parsetree.Scope.execute(Scope.java:353)
	at net.sourceforge.kolmafia.textui.parsetree.UserDefinedFunction.execute(UserDefinedFunction.java:125)
	at net.sourceforge.kolmafia.textui.Interpreter.executeScope(Interpreter.java:240)
	at net.sourceforge.kolmafia.textui.Interpreter.execute(Interpreter.java:185)
	at net.sourceforge.kolmafia.textui.Interpreter.execute(Interpreter.java:178)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeScriptCommand(KoLmafiaCLI.java:3766)
	at net.sourceforge.kolmafia.KoLmafiaCLI.access$200(KoLmafiaCLI.java:137)
	at net.sourceforge.kolmafia.KoLmafiaCLI$Call.run(KoLmafiaCLI.java:1769)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeCommand(KoLmafiaCLI.java:545)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:444)
	at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.handleQueue(CommandDisplayFrame.java:312)
	at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.run(CommandDisplayFrame.java:293)
 

jasonharper

Developer
[quote author=asturia link=topic=2052.msg10461#msg10461 date=1229352055]
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
KoLmafia r6570, Windows XP, Java 1.6.0_10
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[/quote]
6570 is hardly the latest build; there's been one new Sea zone added since then, which is probably the source of your crash.
 

asturia

Minion
[quote author=jasonharper link=topic=2052.msg10463#msg10463 date=1229354611]
6570 is hardly the latest build; there's been one new Sea zone added since then, which is probably the source of your crash.
[/quote]
Same problem with the build I posted in the Daily build section, will test again later.
 

zarqon

Well-known member
I haven't had any problems, but a) I haven't called this script recently due to being in aftercore, and 2) I altered my version a while ago and didn't update here yet since they were functionally equivalent. So in case it works, try 1.1, it gets the list of locations differently and is a bit faster.
 

dj_d

Member
Itty bitty request: could you create a callable version of the function that returns just one location, so I can include safeguide in my goodnight script and burn my turns wherever it recommends? Something like cli_execute("adventure * "+to_string(SafeGuideBestPick()));

(If that's a pain, then I'll do it myself after crimbo (when I go back to ascending) and post the changes here.)

Thanks!
 

zarqon

Well-known member
That would be fine, except... checking if the selected area is available for adventuring would require a huge amount of non-modular code, and I am loathe to write such a thing. If you'd like to, you could probably start with the can_has_bounty() function of the bounty-hunting script.

What's more, sometimes the best choice purely from a safemox standpoint might not be your overall best choice. I'm thinking specifically of the menagerie areas, which seem to be right at the sticking points in my runs but are far from optimal drop-wise.

What I could do is add a function that called adv * on your best three picks. Hopefully one of them would be accessible. Is that OK?
 

dj_d

Member
Ah! I see your point. What about returning *all* the locations in a map with some sort of ranking? Maybe a "danger" score that's positive or negative, with 0 being the best location? Then I can sort by score, layer on some smarts about what drops are good, and iterate through the whole list until I find somewhere I can adventure.

PS: this may start to give you an idea of what my Big Project is. :)
 

dj_d

Member
You know what... I think I can just include it, and instead of calling main, call the requisite sub-functions to get what I want.

Just one more itty bitty request...

d[]?!? seriously? Do you never use search and replace? How about LocationList or something?!?

:)
 

zarqon

Well-known member
[quote author=dj_d link=topic=2052.msg10607#msg10607 date=1229839976]
d[]?!? seriously? Do you never use search and replace? How about LocationList or something?!?
[/quote]

Are you saying I'm too efficient? Because that's not going to make me change anything. :)

if you search/replace just search for "d[".

[quote author=dj_d link=topic=2052.msg10553#msg10553 date=1229715548]
What about returning *all* the locations in a map with some sort of ranking? Maybe a "danger" score that's positive or negative, with 0 being the best location?[/quote]

That's what it does with d[] -- it just doesn't return it. d[] ends up being a map, with safemox as the key (and therefore the sorting criterion), and a comma-delimited list of locations as the value. That map is built in the for loop in main(), so keep that in mind if you start dissecting.
 

dj_d

Member
I just finished LevelUp.ash, which I built on top of Safe.ash... I think you'll like it! I'll post it tomorrow.
 
Top