Skip to content

Instantly share code, notes, and snippets.

@hoelzro
Created June 16, 2016 04:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hoelzro/19573fbe0486fc6de0f3df0016639a05 to your computer and use it in GitHub Desktop.
Save hoelzro/19573fbe0486fc6de0f3df0016639a05 to your computer and use it in GitHub Desktop.
use v6;
use JSON::Fast;
# To use this script, point it at the PlayerMapData.txt for
# the corresponding save (make sure to back up your data first!)
# and tell the script how many bad entries you have in total.
# When the prompt comes up for how many bad entries you have, load
# the game and ask the cartographer, but don't hit enter until after
# you've quit to the main menu. Once the next prompt comes up, rinse
# and repeat.
# track the number of times we invoke the oracle, for fun
my $invocations = 0;
# let's keep a log of our decisions, just in case something
# catastrophic happens and we want to replay our decisions
my $*LOG;
sub ask-oracle($filename, $json, @nodes) {
$invocations++;
for @nodes -> (:$x, :$y, *%) {
$*LOG.say: "[$*PID] [$invocations] $x $y";
}
$*LOG.flush;
$json<nodes> = @nodes;
$filename.IO.spurt(to-json($json));
my $num-bad = prompt("How many entries are bad (don't hit enter until after you've gotten back to the main menu)? ").Int;
$*LOG.say: "[$*PID] [$invocations] $num-bad";
$*LOG.flush;
$num-bad
}
sub find-bad-nodes($filename, $json, @nodes, $num-bad) {
if $num-bad == 0 {
return ();
}
# Return all nodes if we know they're all bad
if $num-bad == @nodes {
return @nodes;
}
# Split the entries into two sublists
my $pivot = ceiling(@nodes / 2);
my @half = @nodes[0..^$pivot];
my @other-half = @nodes[$pivot..*];
my $num-half-bad = ask-oracle($filename, $json, @half);
my $num-other-half-bad = $num-bad - $num-half-bad;
my @bad-nodes;
# Recurse
@bad-nodes.append(find-bad-nodes($filename, $json, @half, $num-half-bad));
@bad-nodes.append(find-bad-nodes($filename, $json, @other-half, $num-other-half-bad));
@bad-nodes
}
sub MAIN(Str $filename, Int $num-bad) {
my $*LOG = open('bad-island-finder.log', :a);
my $pristine-contents = $filename.IO.slurp;
# Clean up the save file upon exit
LEAVE $filename.IO.spurt($pristine-contents);
my $json = from-json($pristine-contents);
my @bad-nodes = find-bad-nodes($filename, $json, $json<nodes>, $num-bad);
say "The bad map entries are:";
for @bad-nodes -> (:$x, :$y, *%) {
say " $x $y";
}
say "# trials: $invocations";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment