Scrabble Analysis with Perl

A while ago, I started playing lots of scrabble. The scrabble game in the Ubuntu repository (by Brian White) records all games in the file ~/.scrabble-games. The following perl script analyzes the file and creates statistics for your games.

#!/usr/bin/perl
 
use strict;
 
my $mode = shift @ARGV;
unless ( $mode ) {
        print "arg: (freq|gen|score|size)\n";
        exit;
}
 
chdir;  
open( LOG, '<scrabble-games' ) or die $!;
 
my $yourwords = 0; 
my ( %wfreq, %wscore );
my $numgames = 0;
 
while ( <LOG> ) {
        chomp;
        if ( m/^level #(\d); computer rack: "([A-Z]*)"; player rack: "([A-Z]*)"$/ ) {
                $numgames++;
        } 
        if ( m/My Words/ ) {
                $yourwords = 0;
        } elsif ( m/Your Words/ ) {
                $yourwords = 1;
        } elsif ( $yourwords ) {
                while ( m/[^a-z]([a-z]+)\((\d+)\)/g ) {
                        $wfreq{$1}++ if length $1 > 2;
                        $wscore{$1} = $2 if length $1 > 2;
                }
        }
}
close( LOG );
 
my @freq = sort { $wfreq{$a} <=> $wfreq{$b} } keys %wfreq;
my @size = sort { length $a <=> length $b } keys %wfreq;
my @score = sort { $wscore{$a} <=> $wscore{$b} } keys %wscore;  # TODO: no hash needed; calculate score from word and ignore bonuses
 
if ( $mode eq 'gen' ) {
        printf "No of games:\t%d\n", $numgames;
        printf "Longest:\t%s\n", join( ', ', &liststart( reverse @size ) );
        printf "Most used:\t%s\n", join( ', ', &liststart( reverse @freq ) );
        printf "Highest score:\t%s\n", join( ', ', &liststart( reverse @score ) );
} elsif ( $mode eq 'score' ) {
        for ( @score ) {
                printf "%d\t%s\n", $wscore{$_}, $_;
        }
} elsif ( $mode eq 'freq' ) {
        for ( @freq ) {
                printf "%d\t%s\n", $wfreq{$_}, $_;
        }
} elsif ( $mode eq 'size' ) {
        for ( @size ) {
                printf "%d\t%s\n", $wfreq{$_}, $_;
        }
}
 
sub liststart {
        my @t;
        for ( 1..5 ) {
                push @t, shift;
        }
        return @t;
}

Call it with one of the arguments freq (for most frequently used words), score (for best-scoring words), size (for longest words) or gen (for a summary). Note that only your words are counted, not your opponent’s.

Maybe Related?

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

FireStats iconAnvänder FireStats