]>
iEval git - nethack-naodash.git/blob - lib/NetHack/NAOdash.pm
1 package NetHack
::NAOdash
;
7 use parent qw
/Exporter/;
9 our $VERSION = '0.001';
10 our @EXPORT_OK = qw
/naodash_xlog naodash_user/;
11 our @EXPORT = @EXPORT_OK;
14 use List
::Util qw
/max min sum/;
15 use List
::MoreUtils qw
/uniq/;
16 use Text
::XLogfile qw
/parse_xlogline/;
20 $game{death
} eq 'ascended'
26 return unless won_game
%game;
27 $game{align0
} //= $game{align
};
28 "combo_$game{role}_$game{race}_$game{align0}"
33 my @achieves = qw
/bell gehennom candelabrum book invocation amulet endgame astral ascended luckstone sokoban medusa/;
34 map { $game{achieve
} & (1 << $_) ?
"achieve_$achieves[$_]" : () } 0 .. $#achieves
39 return unless won_game
%game;
40 my @conducts = qw
/foodless vegan vegetarian atheist weaponless pacifist illiterate polypileless polyselfless wishless artiwishless genocideless/;
41 map { $game{conduct
} & (1 << $_) ?
"conduct_$conducts[$_]" : () } 0 .. $#conducts
44 sub { # Unofficial conducts
46 return unless won_game
%game;
48 push @uconducts, 'survivor' if $game{deaths
} == 0;
49 push @uconducts, 'boneless' unless $game{flags
} & 32;
50 push @uconducts, 'minscore' if $game{points
} - 100 * ($game{maxlvl
} - 45) == 24_400
;
51 map { "uconduct_$_" } @uconducts
61 totalrealtime
=> sub {
67 sub make_attr_sub
($) { ## no critic (ProhibitSubroutinePrototypes)
71 return unless won_game
%game;
77 maxhp
=> make_attr_sub
'maxhp',
78 maxpoints
=> make_attr_sub
'points',
79 maxconducts
=> make_attr_sub
'nconducts',
83 minturns
=> make_attr_sub
'turns',
84 minrealtime
=> make_attr_sub
'realtime',
87 sub naodash_xlog
{ ## no critic (RequireArgUnpacking)
88 my ($xlog) = join '', @_;
89 my %number_subs = (%sum_subs, %max_subs, %min_subs);
92 my %numbers = map { $_ => [] } keys %number_subs;
94 for my $logline (split /\n/, $xlog) {
95 my %game = %{parse_xlogline
$logline};
97 delete $game{$_} if $game{$_} eq ''
99 next if $game{flags
} & 3; # flag 0x01 is wizard mode, 0x02 is explore mode
100 push @checks, $_->(%game) for @check_subs;
101 push @
{$numbers{$_}}, $number_subs{$_}->(%game) for keys %number_subs;
104 $numbers{$_} = sum @
{$numbers{$_}} for keys %sum_subs;
105 $numbers{$_} = max @
{$numbers{$_}} for keys %max_subs;
106 $numbers{$_} = min @
{$numbers{$_}} for keys %min_subs;
107 @checks = uniq
map { lc } @checks;
109 {checks
=> [sort @checks], numbers
=> \
%numbers}
112 my $ht = HTTP
::Tiny
->new(agent
=> "NetHack-NAOdash/$VERSION ");
116 my $ret = $ht->get("http://alt.org/nethack/player-all-xlog.php?player=$name");
117 die 'Error while retrieving xlogfile from alt.org: ' . $ret->{status
} . ' ' . $ret->{reason
} . "\n" unless $ret->{success
};
118 my ($xlog) = $ret->{content
} =~ m{<pre>(.*)</pre>}i;
119 die "No xlogfile found for user $name\n" unless defined $xlog;
130 NetHack::NAOdash - Analyze NetHack xlogfiles and extract statistics
134 use NetHack::NAOdash;
135 my $stats = naodash_user 'mgv'; # Retrieve and analyze mgv's xlogfile from alt.org
136 my @checks = @{$stats->{checks}}; # List of "achievements" obtained by mgv
137 my %checks = map { $_ => 1 } @checks;
138 say "mgv has ascended an orcish rogue" if $checks{combo_rog_orc_cha};
139 say "mgv has ascended an atheist character" if $checks{conduct_atheist};
140 my %numbers = %{$stats->{numbers}};
141 say "mgv has ascended $numbers{ascensions} out of $numbers{games} games";
142 say "mgv has spent $numbers{totalrealtime} seconds playing NetHack on NAO";
145 $stats = naodash_xlog read_file 'path/to/my/xlogfile';
146 %checks = map { $_ => 1 } @{$stats->{checks}};
147 say "I have ascended a survivor" if $checks{uconduct_survivor};
151 NetHack::NAOdash analyzes a NetHack xlogfile and reports statistics.
152 There are two types of statistics: B<checks>, which are flags
153 (booleans) and B<numbers> which are integers.
155 The B<checks> are tracked across all games. That is, a B<check> will
156 be true in the statistics if it is true in at least one game. Except
157 for B<checks> in the I<Achievements> category, only games that end in
158 an ascension are considered for awarding a B<check>.
160 The B<checks>, sorted by category, are:
164 =item B<Achievements>
166 These start with C<achieve_> and represent significant milestones in a
167 game. They are usually relevant only for users who never ascended, as
168 a game that ends in an ascension generally meets all of them.
170 achieve_sokoban achieve_luckstone achieve_medusa achieve_bell
171 achieve_gehennom achieve_candelabrum achieve_book achieve_invocation
172 achieve_amulet achieve_endgame achieve_astral achieve_ascended
174 =item B<Starting Combos>
176 These look like C<combo_role_race_alignment> and represent
177 role/race/alignment combinations in ascended games. The starting
178 alignment, not the alignment at the end of the game is considered. For
179 example, C<cav_gno_neu> is true if the user ascended at least one
184 These start with C<conduct_> and represent the 12 officially tracked
187 conduct_foodless conduct_vegan conduct_vegetarian
188 conduct_atheist conduct_weaponless conduct_pacifist
189 conduct_illiterate conduct_genocideless conduct_polypileless
190 conduct_polyselfless conduct_wishless conduct_artiwishless
192 =item B<Unofficial Conducts>
194 These start with C<uconduct_> and represent conducts that are not
195 officially tracked by the game.
197 uconduct_survivor uconduct_bones uconduct_minscore
205 =item B<totalrealtime>
207 The total time spent playing NetHack on NAO, in seconds.
211 The number of games played.
215 The number of games played that ended in an ascension.
219 The highest maxHP at the end of an ascension.
223 The highest score obtained at the end of an ascension.
227 The maximum number of conducts at the end of an ascension.
231 The minimum turns across ascended games.
235 The minimum realtime across ascended games, in seconds.
239 This module exports two functions:
243 =item B<naodash_xlog>(I<@lines>)
245 =item B<naodash_xlog>(I<$xlog>)
247 Takes the contents of an xlogfile and returns the results of the
248 analysis. The arguments are joined together then split by the newline
249 character, so they can be specified as a single string, as a list of
250 lines, or as a combination thereof.
252 The return value is of the following form:
254 { checks => ['achieve_sokoban', 'achieve_luckstone', ...],
255 numbers => {totalrealtime => 12345, games => 2, ...} }
257 In other words, C<< @{$result->{checks}} >> is an array of B<checks>
258 that are true and C<< %{$result->{numbers}} >> is a hash of
261 =item B<naodash_user>(I<$nao_username>)
263 Retrieves the xlogfile of a user from NAO and gives it to
264 B<naodash_xlog>. Dies if no xlogfile is found or if the server cannot
271 L<App::NAOdash>, L<App::Web::NAOdash>, L<http://alt.org/nethack/>
275 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
277 =head1 COPYRIGHT AND LICENSE
279 Copyright (C) 2015 by Marius Gavrilescu
281 This library is free software; you can redistribute it and/or modify
282 it under the same terms as Perl itself, either Perl version 5.20.2 or,
283 at your option, any later version of Perl 5 you may have available.
This page took 0.084402 seconds and 4 git commands to generate.