Skip to content

Instantly share code, notes, and snippets.

@miriku
Created October 31, 2015 18:26
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 miriku/dcd8d3e3a1506dd86edf to your computer and use it in GitHub Desktop.
Save miriku/dcd8d3e3a1506dd86edf to your computer and use it in GitHub Desktop.
$max_i = 1000000;
$db = 0; # debugging?
$dbf = 0; # debugging of fight function
# dragon array offsets
$r = 0;
$g = 1;
$b = 2;
@dragonValues = ( 6, 4, 2 );
sub score
{
( $deadDragons, $stoppedAt, $thisscore ) = @_;
$scoreString = $deadDragons . ":" . $stoppedAt;
$scores{$scoreString} += $thisscore;
$runs{$scoreString} += 1;
if( $db ) { print "Scoring! $scoreString gains $thisscore "; }
if( $db ) { print "(", $scores{$scoreString}, ",", $runs{$scoreString}, ")\n"; }
}
sub fightadragon
{
$d1active = 1;
$d2active = 1;
$d3active = 1;
( $dcolor, $wactive ) = @_;
# fight until death or cowardice
while( 1 )
{
# new roll, so reset fire results to 0
$fires = 0;
$shields = 0;
# roll dice
$w1 = int( rand( 6 ) );
$w2 = int( rand( 6 ) );
$w3 = int( rand( 6 ) );
$d1 = int( rand( 6 ) );
$d2 = int( rand( 6 ) );
$d3 = int( rand( 6 ) );
if( $dbf ) { print "Raw: $w1 $w2 $w3 $d1 $d2 $d3\n"; }
# assign hunter dice
if( $w1 < 3 ) { $w1 = "axe"; }
elsif( $w1 < 5 ) { $w1 = "shield"; }
else { $w1 = "fire"; }
if( $w2 < 3 ) { $w2 = "axe"; }
elsif( $w2 < 5 ) { $w2 = "shield"; }
else { $w2 = "fire"; }
if( $w3 < 3 ) { $w3 = "axe"; }
elsif( $w3 < 5 ) { $w3 = "shield"; }
else { $w3 = "fire"; }
# assign dragon dice
if( $dcolor eq "B" )
{
if( $d1 < 4 ) { $d1 = "dragon"; }
else { $d1 = "mountain"; }
if( $d2 < 4 ) { $d2 = "dragon"; }
else { $d2 = "mountain"; }
if( $d3 < 4 ) { $d3 = "dragon"; }
else { $d3 = "mountain"; }
}
if( $dcolor eq "G" )
{
if( $d1 < 4 ) { $d1 = "dragon"; }
elsif( $d1 < 5 ) { $d1 = "fire"; }
else { $d1 = "mountain"; }
if( $d2 < 4 ) { $d2 = "dragon"; }
elsif( $d2 < 5 ) { $d2 = "fire"; }
else { $d2 = "mountain"; }
if( $d3 < 4 ) { $d3 = "dragon"; }
elsif( $d3 < 5 ) { $d3 = "fire"; }
else { $d3 = "mountain"; }
}
if( $dcolor eq "R" )
{
if( $d1 < 4 ) { $d1 = "dragon"; }
else { $d1 = "fire"; }
if( $d2 < 4 ) { $d2 = "dragon"; }
else { $d2 = "fire"; }
if( $d3 < 4 ) { $d3 = "dragon"; }
else { $d3 = "fire"; }
}
# if the dice is dead, remove it
if( $wactive == 2 ) { $w3 = ""; }
if( $wactive == 1 ) { $w3 = $w2 = ""; }
if( $d1active == 0 ) { $d1 = ""; }
if( $d2active == 0 ) { $d2 = ""; }
if( $d3active == 0 ) { $d3 = ""; }
if( $dbf ) { print "Dragon $dcolor got w( $w1 $w2 $w3 ) d( $d1 $d2 $d3 )\n"; }
# count fires
if( $w1 eq "fire" ) { $fires++; }
if( $w2 eq "fire" ) { $fires++; }
if( $w3 eq "fire" ) { $fires++; }
if( $d1 eq "fire" ) { $fires++; }
if( $d2 eq "fire" ) { $fires++; }
if( $d3 eq "fire" ) { $fires++; }
# count shields
if( $w1 eq "shield" ) { $shields++; }
if( $w2 eq "shield" ) { $shields++; }
if( $w3 eq "shield" ) { $shields++; }
if( $dbf ) { print "$fires fires, $shields shields, from $wactive dice.\n"; }
if( $fires > $shields ) { $wactive -= ($fires-$shields); }
# if you're dead, stop
if( $wactive < 1 )
{
if( $dbf ) { print "URGH\n"; }
return 0;
}
# did you get an axe?
if( $w1 == "axe" || $w2 == "axe" || $w3 == "axe" )
{
if( $dbf ) { print "Got an axe.\n"; }
# then kill dragons
if( $d1 eq "dragon" ) { $d1active = 0; if( $dbf ) { print "Got head.\n"; } }
if( $d2 eq "dragon" ) { $d2active = 0; if( $dbf ) { print "Got wings.\n"; } }
if( $d3 eq "dragon" ) { $d3active = 0; if( $dbf ) { print "Got tail.\n"; } }
# dragon died?
if( $d1active == 0 && $d2active == 0 && $d3active == 0 )
{
if( $dbf ) { print "Dragon dead.\n"; }
return $wactive;
}
}
}
}
for( $i = 0; $i < $max_i; $i++ )
{
if( !$db ) { print "\r$i / $max_i"; }
if( $db ) { print "New run\n"; }
$datum = 0; # running score
$whitedice = 3;
$path = ""; # which dragons were fought to get here
@dragons = ( 1, 1, 1 ); # R G B
$dragonGoal = int( rand( 4 ) ) + 4;
$stopAtLife = int( rand( 2 ) ) + 1; # how many dice he requires to continue
if( $db ) { print "This guy wants $dragonGoal dragons and stops at $stopAtLife life\n"; }
# first we fight the first 3 dragons
$whitedice = fightadragon( "R", $whitedice );
$whitedice = fightadragon( "G", $whitedice );
$whitedice = fightadragon( "B", $whitedice );
if( $whitedice == 0 )
{
# died. next
if( $db ) { print "Died in first 3.\n"; }
# assign his loss to a random valid string
$path = "RGB";
while( length($path) < $dragonGoal )
{
if( 0 == $dragons[0] + $dragons[1] + $dragons[2] )
{
$dragons[0] = $dragons[1] = $dragons[2] = 1;
}
do{ $dragonToFight = int( rand( 3 ) ); }
while( $dragons[$dragonToFight] == 0 );
# convert dragon to string
if( $dragonToFight == 0 ) { $dragon = "R"; }
if( $dragonToFight == 1 ) { $dragon = "G"; }
if( $dragonToFight == 2 ) { $dragon = "B"; }
$dragons[$dragonToFight] = 0;
$path .= $dragon;
}
score( $path, $stopAtLife, 0 );
next;
}
# score the 3 start dragons
$datum = 12;
$path = "RGB";
# iterate! until death or dishonor
HUNT: while( true )
{
# is he aborting cause courage?
if( $stopAtLife >= $whitedice && length( $path ) > 3 )
{
if( $dba ) { print "no courage! (stops at $stopAtLife but has $whitedice life). done.\n"; }
score( $path, $stopAtLife, $datum );
last HUNT;
}
# is he finished?
if( length( $path ) == $dragonGoal )
{
if( $db ) { print "$path is our goal length ($dragonGoal). done.\n"; }
score( $path, $stopAtLife, $datum );
last HUNT;
}
# respawn dragons if needed
if( 0 == $dragons[0] + $dragons[1] + $dragons[2] )
{
$dragons[0] = $dragons[1] = $dragons[2] = 1;
}
# no? then fight a dragon
do{ $dragonToFight = int( rand( 3 ) ); }
while( $dragons[$dragonToFight] == 0 );
# convert dragon to string
if( $dragonToFight == 0 ) { $dragon = "R"; }
if( $dragonToFight == 1 ) { $dragon = "G"; }
if( $dragonToFight == 2 ) { $dragon = "B"; }
if( $db ) { print "Fighting a $dragon\n"; }
$whitedice = fightadragon( $dragon, $whitedice );
# lived?
if( $whitedice > 0 )
{
$datum += $dragonValues[ $dragonToFight ];
$path .= $dragon;
if( $db ) { print "He wins! $datum and $path so far\n"; }
$dragons[$dragonToFight] = 0;
}
# died
else
{
if( $db ) { print "dead\n"; }
score( $path.$dragon, $stopAtLife, 0 );
last HUNT;
}
}
}
if( $db ) { print "Done\n\n"; }
if( !$db ) { print "\n"; }
foreach $key ( sort( keys %scores ) )
{
print $key,",",($scores{$key}/$runs{$key}), "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment