summaryrefslogtreecommitdiffstats
path: root/bin/smt_fusion
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-05-27 01:26:03 -0400
committerJesse Luehrs <doy@tozt.net>2014-05-27 01:26:03 -0400
commit59d18127c08f550775f7b608fbf759ad447d6a58 (patch)
tree97a833f1ee0861ec924e246241f3e6c55c36e2f6 /bin/smt_fusion
parenta6b29a0d67b261c52b79033c1f140502b27cf428 (diff)
downloadgames-smtnocturne-demons-59d18127c08f550775f7b608fbf759ad447d6a58.tar.gz
games-smtnocturne-demons-59d18127c08f550775f7b608fbf759ad447d6a58.zip
rename the script
i do want to expand this to not be entirely about fusions, so let's leave that open
Diffstat (limited to 'bin/smt_fusion')
-rw-r--r--bin/smt_fusion243
1 files changed, 0 insertions, 243 deletions
diff --git a/bin/smt_fusion b/bin/smt_fusion
deleted file mode 100644
index 292c807..0000000
--- a/bin/smt_fusion
+++ /dev/null
@@ -1,243 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-
-use Getopt::Long;
-use List::Util 'max', 'sum0';
-
-use Games::SMTNocturne::Demons;
-
-sub _demon { Games::SMTNocturne::Demons::demon(@_) }
-sub _demons_of_type { Games::SMTNocturne::Demons::demons_of_type(@_) }
-sub _fuse { Games::SMTNocturne::Demons::fuse(@_) }
-sub _fusions_for { Games::SMTNocturne::Demons::fusions_for(@_) }
-
-my $command = shift @ARGV;
-
-my ($max_level, $deathstones, $kagatsuchi, $bosses);
-GetOptions(
- "max_level=i" => \$max_level,
- "deathstones=i" => \$deathstones,
- "kagatsuchi=i" => \$kagatsuchi,
- "boss=s@" => \$bosses,
-) or die "couldn't parse options";
-$bosses = [ split(/,/, join(',', @$bosses)) ]
- if $bosses;
-
-my $options = {
- max_level => $max_level,
- deathstone => $deathstones,
- kagatsuchi => $kagatsuchi,
- bosses => $bosses,
-};
-
-if ($command !~ /^_/ && defined &$command) {
- { no strict 'refs'; &{ $command }(@ARGV) }
-}
-else {
- die "unknown command $command";
-}
-
-sub demon {
- my ($demon) = @_;
- print _demon($demon), "\n";
-}
-
-sub demons_of_type {
- my ($type) = @_;
- print join("\n", _demons_of_type($type)), "\n";
-}
-
-sub fuse {
- my ($demon1, $demon2, $sacrifice) = @_;
- print _fuse($demon1, $demon2, { sacrifice => $sacrifice, %$options }), "\n";
-}
-
-sub fusions_for {
- my ($demon) = @_;
- print join("\n", _fusions_for($demon, $options)), "\n";
-}
-
-sub min_level_for {
- my ($demon) = @_;
-
- my @fusions = _fusions_for($demon, $options);
- my $min_level = 99;
- my @min_level_fusions;
- for my $fusion (@fusions) {
- my $max_level = max(map { $_->level } $fusion->all_demons);
- if ($max_level < $min_level) {
- @min_level_fusions = ($fusion);
- $min_level = $max_level;
- }
- elsif ($max_level == $min_level) {
- push @min_level_fusions, $fusion;
- }
- }
- print "Level $min_level:\n";
- print join("\n", @min_level_fusions), "\n";
-}
-
-sub party_fusion {
- my @demons = @_;
-
- my $seen = _party_fusion_recursive_fuse(
- {
- map { $_ => _demon($_) } @demons
- },
- {
- map { $_ => _demon($_) } @demons
- },
- $deathstones,
- map { _demon($_) } @demons
- );
- my @found =
- sort { $a->level <=> $b->level }
- map { _demon($_) }
- keys %$seen;
- for my $demon (@found) {
- my $path = $seen->{$demon->name};
- if (ref($path) eq 'ARRAY') {
- print "$demon:\n";
- my ($fusion, $current) = @$path;
- print " $_\n" for _linearize_tree($current, $fusion);
- }
- else {
- print "$demon\n";
- }
- }
-}
-my $SEEN = {};
-sub _party_fusion_recursive_fuse {
- my ($seen, $current, $deathstones, @demons) = @_;
-
- return $seen if $SEEN->{join(';', @demons, ($deathstones || ''))}++;
-
- if (@demons > 1) {
- for my $demon1 (@demons) {
- for my $demon2 (grep { $_ ne $demon1 } @demons) {
- if ($deathstones) {
- for my $phase (0..8) {
- _check_fusion(
- $seen, $current, \@demons,
- $demon1, $demon2, undef,
- $deathstones, $phase
- );
- }
- }
- else {
- _check_fusion($seen, $current, \@demons, $demon1, $demon2);
- }
- for my $demon3 (grep { $_ ne $demon1 && $_ ne $demon2 } @demons) {
- _check_fusion(
- $seen, $current, \@demons, $demon1, $demon2, $demon3
- );
- }
- }
- }
- }
-
- return $seen;
-}
-sub _check_fusion {
- my ($seen, $current, $party, $demon1, $demon2, $sacrifice, $deathstones, $phase) = @_;
-
- my $fused = _fuse(
- $demon1, $demon2,
- {
- %$options,
- sacrifice => $sacrifice,
- deathstone => $deathstones,
- kagatsuchi => $phase,
- },
- );
- return unless $fused;
- return if defined $max_level && $fused->level > $max_level;
-
- my $new_current = { %$current };
-
- my $new_fusion = Games::SMTNocturne::Demons::Fusion->new(
- $options,
- $demon1, $demon2,
- ($sacrifice
- ? ($sacrifice)
- : ()),
- ($fused->type eq 'Fiend'
- ? ('<deathstone>', $phase)
- : ()),
- );
- if (my $old_fusion = $new_current->{$fused->name}) {
- my $old_max_level = _max_level($new_current, $old_fusion);
- my $new_max_level = _max_level($new_current, $new_fusion);
- if ($new_max_level < $old_max_level) {
- $new_current->{$fused->name} = $new_fusion;
- }
- else {
- my $old_demon_count = _demon_count($new_current, $old_fusion);
- my $new_demon_count = _demon_count($new_current, $new_fusion);
- if ($new_demon_count < $old_demon_count) {
- $new_current->{$fused->name} = $new_fusion;
- }
- }
- }
- else {
- $new_current->{$fused->name} = $new_fusion;
- }
- if (my $old = $seen->{$fused->name}) {
- my ($old_fusion, $old_current) = ref($old) eq 'ARRAY'
- ? @$old : ($old, undef);
- my $old_max_level = _max_level($old_current, $old_fusion);
- my $new_max_level = _max_level($new_current, $new_fusion);
- if ($new_max_level < $old_max_level) {
- $seen->{$fused->name} = [ $new_fusion, $new_current ];
- }
- else {
- my $old_demon_count = _demon_count($old_current, $old_fusion);
- my $new_demon_count = _demon_count($new_current, $new_fusion);
- if ($new_demon_count < $old_demon_count) {
- $seen->{$fused->name} = [ $new_fusion, $new_current ];
- }
- }
- }
- else {
- $seen->{$fused->name} = [ $new_fusion, $new_current ];
- }
-
- my @new_party = (
- $fused,
- grep {
- $_ ne $demon1 && $_ ne $demon2 && (!$sacrifice || $_ ne $sacrifice)
- } @$party
- );
- _party_fusion_recursive_fuse(
- $seen, $new_current,
- ($fused->type eq 'Fiend' ? $deathstones - 1 : $deathstones),
- @new_party
- );
-}
-sub _max_level {
- my ($seen, $fusion) = @_;
-
- return 0 if $fusion->isa('Games::SMTNocturne::Demons::Demon');
- return 1 + max(
- map { _max_level($seen, $seen->{$_->name}) } $fusion->all_demons
- );
-}
-sub _demon_count {
- my ($seen, $fusion) = @_;
-
- return 1 if $fusion->isa('Games::SMTNocturne::Demons::Demon');
- my @demons = $fusion->all_demons;
- return @demons + sum0(
- map { _demon_count($seen, $seen->{$_->name}) } @demons
- );
-}
-sub _linearize_tree {
- my ($seen, $fusion) = @_;
-
- return if $fusion->isa('Games::SMTNocturne::Demons::Demon');
- return (
- (map { _linearize_tree($seen, $seen->{$_->name}) } $fusion->all_demons),
- $fusion,
- );
-}