# Nethack Logparser V 1.02 # # By Robert Lund (robertl@pacificnet.net) # # This version runs under Win32. To run under Unix, change the clear_screen # function to call clear instead of cls # # Change the line that begins with $LOGFILE to point to the nethack Logfile # on your system, NOT the record file require 5; $LOGFILE = "d:/games/Nethack 3.2 NT/logfile"; # CHANGE THIS LINE!!!!! %chartypes = qw (P Priest A Archaelogist C Caveman W Wizard S Samurai H Healer T Tourist B Barbarian V Valkerie E Elf K Knight R Rogue); $SCORE = 0; $END_LEV = 1; $MAX_LEV = 2; $END_HP = 3; $DEATH = 5; $START = 6; $END = 7; $CHAR = 8; $SEX = 9; $NAME = 10; $DEATH = 11; $MAX_HP = 4; sub read_data() { undef @data; open (LOG, $LOGFILE) || die "Couldn't open $LOGFILE\n"; for () { next if /quit/; my @stuff = /\S+ (\d+) \d+ (-*\d+) (\d+) (-*\d+) (\d+) (\d+) (\d+) (\d+) \d+ (.)(.) (.*?),(.*)/; push @data, \@stuff; } } sub info_string(@) { sprintf ("%-8s %-3s %-5s %-7s %s\n", @_[$NAME], @_[$CHAR], @_[$END_LEV], @_[$SCORE], @_[$DEATH]); } sub dummy() { print "\nPress when done..."; my $dummy = } sub clear_screen() { system 'cls' } # CHANGE cls to clear if using UNIX!! sub print_top($$) { (my $how_many, my $what) = @_; my @idx; undef my @temp; if ($what =~ /all/i) { @temp = @data; } else { for $i (0 .. $#data) { next unless $data[$i][$CHAR] =~ /$what/; push @temp, $data[$i]; } } for $i (0 .. $#temp) { push @idx, $temp[$i][$SCORE]; } my @new = @temp[ reverse sort { $idx[$a] <=> $idx[$b] } 0 .. $#temp ]; clear_screen; for $i (0 .. --$how_many) { last unless $new[$i]; printf ("%2d) %s", $i + 1, info_string ( @{ $new[$i] })); } dummy } sub lethal() { undef my %deadly; undef my $answer; while ($answer < 1 || $answer > 100) { print "Show top how many lethal thingies? "; chomp ($answer = ); } for my $i (0 .. $#data) { $_ = $data[$i][$DEATH]; next unless /killed by/; s/ a //; s/ an //; s/killed by//; s/hallucinogen-distorted //; s/invisible //; $deadly{$_}++; } my @t = reverse sort { $deadly{$a} <=> $deadly{$b} } keys %deadly; clear_screen; for (0 .. --$answer) { printf ("%3s) %-20s %-5s\n", 1 + $_, $t[$_], $deadly{$t[$_]}); } dummy; } sub averages() { undef %schitt; undef %size; my $totgames = 0; my $tothp = my $totlev = 0; clear_screen; for $i (0 .. $#data) { ($score, $max_hp, $max_lev, $char) = @{$data[$i]}[$SCORE, $MAX_HP, $MAX_LEV, $CHAR]; $schitt{$char}{score} += $score; $schitt{$char}{maxhp} += $max_hp; $schitt{$char}{maxlv} += $max_lev; $totscore += $score; $tothp += $max_hp; $totlev += $max_lev; $totgames++; $size{$char}++; } printf("%-15s %-15s %-10s %-10s %-10s\n\n", "Character", "Av. Score", "Av. Maxhp", "Av. Maxlv", "Total Games"); for (reverse sort { $schitt{$a}{score} / $size{$a} <=> $schitt{$b}{score} / $size{$b} } qw (A B C E H K R S T V W)) { printf ("%-15s %-15s %-10s %-10s %-10d\n", $chartypes{$_}, int ($schitt{$_}{score} / $size{$_}), int ($schitt{$_}{maxhp} / $size{$_}), int ($schitt{$_}{maxlv} / $size{$_}), $size{$_}); } printf ("\n%-15s %-15s %-10s %-10s %-10d\n", "Total", int ($totscore / $totgames), int ($tothp / $totgames), int ($totlev / $totgames), $totgames); dummy } sub top_menu() { my $how_many = my $what = 0; my %good = qw (A 1 B 1 C 1 E 1 H 1 K 1 P 1 R 1 S 1 T 1 V 1 W 1 ALL 1); until ($how_many > 0 && $how_many < 100) { print "Show how many scores? "; chomp ($how_many = ); } until ($good{$what}) { print "For Which Class [ABCEHKPRSTVW|ALL]? "; chomp ($what = ); $what = uc $what; } print_top($how_many, $what); } sub main_menu() { while(1) { clear_screen; print "Welcome to the Nethack LogParser V1.02 by Robert Lund!\n\n"; print "\t1) Show top scores\n"; print "\t2) Show class averages\n"; print "\t3) Show Lethal Monsters\n"; print "\tq) Exit\n\n"; print "Your Choice ==> "; chomp ($answer = ); top_menu if $answer eq '1'; averages if $answer eq '2'; lethal if $answer eq '3'; exit if $answer =~ /q/i; } } read_data; main_menu