Skip to content

Instantly share code, notes, and snippets.

@musiKk
Last active December 24, 2015 08:25
Show Gist options
  • Select an option

  • Save musiKk/7134d4c5b602eb392149 to your computer and use it in GitHub Desktop.

Select an option

Save musiKk/7134d4c5b602eb392149 to your computer and use it in GitHub Desktop.
AoC 23
#!/usr/bin/env perl
use strict;
use warnings;
use v5.20;
use List::Util qw/ min max /;
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
my $hard_mode = 1;
my @spells = (
# name , cost, timer, dmg, heal, armor, mana recharge
[ 'missile' , 53, 1, 4, 0, 0, 0 ],
[ 'drain' , 73, 1, 2, 2, 0, 0 ],
[ 'shield' , 113, 6, 0, 0, 7, 0 ],
[ 'poison' , 173, 6, 3, 0, 0, 0 ],
[ 'recharge', 229, 5, 0, 0, 0, 101 ]
);
my ($monster_hp, $monster_dmg) = (51, 9);
my ($hp, $mana) = (50, 500);
# my ($monster_hp, $monster_dmg) = (13, 8);
# my ($hp, $mana) = (10, 250);
# name -> spell
my %current_spells = ();
say recurse([ $hp, $mana ], [ $monster_hp, $monster_dmg ], \%current_spells, 0, 0);
sub recurse {
my ($me, $monster, $current_spells, $mana_spent, $depth) = @_;
my @manas_spent = ();
for my $spell (@spells) {
# copies for the recursion
my $new_me = [ @$me ];
my $new_monster = [ @$monster ];
my $new_current_spells = { map
{ $_ => [ @{$current_spells->{$_}} ] }
keys %$current_spells };
my $new_mana_spent = $mana_spent + $spell->[1];
# player turn
if ($hard_mode) {
$new_me->[0]--;
if ($new_me->[0] <= 0) {
next;
}
}
apply_spells($new_me, $new_monster, $new_current_spells, $depth);
next if exists $new_current_spells->{$spell->[0]};
next if $spell->[1] > $me->[1];
# msay($depth, Dumper($me) . ' v ' . $monster->[0] . ' active spells ' . join ', ', sort keys %$current_spells);
# msay($depth, 'player casts ' . $spell->[0]);
$new_me->[1] -= $spell->[1];
if ($spell->[0] eq 'missile' || $spell->[0] eq 'drain') {
$new_monster->[0] -= $spell->[3];
$new_me->[0] += $spell->[4];
} else {
$new_current_spells->{$spell->[0]} = [ @$spell ];
}
# msay($depth, 'current spells now ' . join ', ', sort keys %$new_current_spells);
if ($new_monster->[0] <= 0) {
# msay($depth, "win with mana spent $new_mana_spent");
push @manas_spent, $new_mana_spent;
next;
}
# monster turn
apply_spells($new_me, $new_monster, $new_current_spells, $depth);
if ($new_monster->[0] <= 0) {
# msay($depth, "win with mana spent $new_mana_spent");
push @manas_spent, $new_mana_spent;
next;
}
my $my_armor = exists $current_spells->{'shield'} ? 7 : 0;
my $monster_dmg = max(1, $new_monster->[1] - $my_armor);
$new_me->[0] -= $monster_dmg;
# msay($depth, "monster attacks for $monster_dmg (armor $my_armor, @{[$new_me->[0]]} remaining)");
if ($new_me->[0] <= 0) {
# msay($depth, "lost!");
next;
}
push @manas_spent, recurse($new_me, $new_monster, $new_current_spells, $new_mana_spent, $depth + 1);
}
return 100000 if 0 == scalar(@manas_spent);
return min(@manas_spent);
}
sub apply_spells {
my ($me, $monster, $current_spells, $depth) = @_;
for my $spell_name (keys %$current_spells) {
my $spell = $current_spells->{$spell_name};
# msay($depth, "using $spell_name dealing @{[$spell->[3]]} damage");
$monster->[0] -= $spell->[3];
$me->[1] += $spell->[6];
$spell->[2]--;
# my $description = 'MISSING DESCRIPTION';
# if ($spell_name eq 'missile') {
# $description = "Player casts magic missile, dealing @[{$spell->[3] damage";
# } elsif ($spell_name eq 'drain') {
# $description = "Player casts drain, dealing @[{$spell->[3]]} damage and healing @{[$spell->[4]]} hit points";
# } else {
# if ($spell_name eq 'shield') {
# $description = 'shield';
# } elsif ($spell_name eq 'poison') {
# $description = "poison deals @{[$spell->[3]]} damage";
# } elsif ($spell_name eq 'recharge') {
# $description = "recharge provides @{[$spell->[6]]} mana";
# }
# $description .= "; it's timer is now @{[$spell->[2]]}";
# }
# msay($depth, $description);
# msay($depth, $spell_name . ' wears off') if $spell->[2] <= 0;
delete $current_spells->{$spell_name} if $spell->[2] <= 0;
}
}
sub msay {
my ($depth, @list) = @_;
say '| 'x$depth, @list;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment