#!/usr/bin/perl -w
use strict;

# KOL queue/olfaction simulator
# Usage: ./queue.pl [-c] [N] [turns]
# -c = emulate Staff of the Cream of the Cream instead of On the Trail
# N = number of monsters in a zone (default 6)
# turns = turns to run simulation (default 10000000)

# Change these if you wish:
my $N = 6;			# castle, default
my $turns = 10000000;		# combats only

# Command line overrides them.
my $cream = 0;
if ($ARGV[0] eq '-c') {
    $cream = 1;
    shift;
}
$N = $ARGV[0] if $#ARGV >= 0;
$turns = $ARGV[1] if $#ARGV >= 1;

# Other variables:
my @q = (-1, -1, -1, -1, -1);
my $olfact = 0;			# turns left
my (@seen, @seen_trail);
my ($i, $m, $trailed);

sub pickmon {
    my @mons = (0..$N-1);
    if ($cream) {
	# Cream adds no extra copies of the monster??
	# push @mons, 0 if $olfact > 0;
    } else {
	# On the Trail adds 3 copies
	push @mons, 0, 0, 0 if $olfact > 0;
    }

    while (1) {
	# Select an encounter from the selection list.
	my $m = $mons[int(rand($#mons + 1))];

	# If it's olfacted (or creamed?), that's the encounter.
	if (($m == 0) && ($olfact > 0)) { return $m; }

	# If it's not in the combat queue, that's the encounter.
	if (! grep {$_ eq $m} @q) { return $m; }

	# If it's in the combat queue, 25% of the time, accept the encounter.
	return $m if (int(rand(4)) == 0);
    }
}

for ($i = 0; $i < $turns; $i++) {
    $m = pickmon();

    $seen[$m]++;
    $seen_trail[$m]++ if $olfact > 0;
    $trailed++ if $olfact > 0;

    # Sniff it, if it's our target, and we're not on the trail.
    if (($m == 0) && ($olfact <= 0)) { $olfact = 40; }

    $olfact-- if ($olfact > 0 && ! $cream);

    # Put monster in the queue and cycle it.
    $q[0] = $q[1];  $q[1] = $q[2];  $q[2] = $q[3];
    $q[3] = $q[4];  $q[4] = $m;
}

my $which = "On the Trail";
$which = "Staff of the Cream of the Cream" if $cream;
print "After $turns turns using $which,\n";
foreach $m (0..$N-1) {
    print "Saw $m: $seen[$m] ($seen_trail[$m] while on trail)\n";
}
print "On trail $trailed / $turns (" . 100*$trailed/$turns . "%) turns\n";
print "Target monster seen $seen_trail[0] / $trailed (" .
    100*$seen_trail[0]/$trailed . "%) while on trail\n";
print "Target monster seen $seen[0] / $turns (" .
    100*$seen[0]/$turns . "%) overall\n";
