Games-Crossword-Puzzle
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
lib/Games/Crossword/Puzzle.pm view on Meta::CPAN
use strict;
use warnings;
package Games::Crossword::Puzzle 0.004;
# ABSTRACT: six letters for "reusable unit of code"
#pod =head1 SYNOPSIS
#pod
#pod my $puzzle = Games::Crossword::Puzzle->from_file('nyt-sunday.puz');
#pod
#pod for my $row ($puzzle->rows) {
#pod for my $cell (@$row) {
#pod die "Nope, not completed properly"
#pod if $cell->value and (not $cell->guess) || $cell->guess ne $cell->value;
#pod }
#pod }
#pod
#pod =head1 DESCRIPTION
#pod
#pod The F<.PUZ> file format is used by many crossword programs and, more
#pod importantly, is offered by many newspapers. It servers as both a puzzle and a
#pod "saved game," storing the grid, the answers, the clues, and guesses.
#pod
#pod Games::Crossword::Puzzle reads F<.PUZ> files and produces
#pod Games::Crossword::Puzzle objects.
#pod
#pod A puzzle is a rectangular grid of L<Games::Crossword::Puzzle::Cell> objects.
#pod
#pod =cut
use Carp ();
use Games::Crossword::Puzzle::Cell;
#pod =method from_file
#pod
#pod my $puzzle = Games::Crossword::Puzzle->from_file($filename);
#pod
#pod This method reads in a puzzle file and returns a puzzle object. It will raise
#pod an exception if the file does not appear to be a valid puzzle file.
#pod
#pod =cut
sub from_file {
my ($class, $filename) = @_;
my $self = bless {} => $class;
open my $fh, $filename or die "couldn't open file: $!";
seek $fh, 2, 0;
read $fh, (my $magic), 12;
die "file is not a valid puzzle" unless $magic eq "ACROSS&DOWN\0";
{
seek $fh, 0x2C, 0;
read $fh, (my $size), 2;
$self->{width} = ord substr $size, 0, 1;
$self->{height} = ord substr $size, 1, 1;
}
seek $fh, 0x34, 0;
read $fh, (my $solution), $self->height * $self->width;
read $fh, (my $guess), $self->height * $self->width;
seek $fh, 0x2E, 0;
read $fh, (my $clues), 2;
$clues = unpack 'v2', $clues;
seek $fh, 0x34 + 2 * $self->height * $self->width, 0;
$self->{title} = $self->_read_nul_string($fh);
$self->{author} = $self->_read_nul_string($fh);
$self->{copyright} = $self->_read_nul_string($fh);
my @clues;
for (1 .. $clues) {
my $clue = $self->_read_nul_string($fh);
push @clues, $clue;
}
$self->{notes} = $self->_read_nul_string($fh);
my $tables = $self->_read_tables($fh);
$self->__build_grid(\$solution, \$guess, \@clues, $tables);
return $self;
}
sub _read_tables {
my ($self, $fh) = @_;
my %return;
while (! eof $fh) {
read($fh, my $front, 8) or die "error reading table: $!";
my ($title, $len, $ck) = unpack "A4SS", $front;
read($fh, my $data, $len) or die "error reading table $title: $!";
read($fh, my $nul, 1) or die "error reading table $title: $!";
die "data for $title table not nul-terminated" unless $nul eq "\0";
$return{ $title } = $data;
}
return \%return;
view all matches for this distributionview release on metacpan - search on metacpan
( run in 1.000 second using v1.00-cache-2.02-grep-82fe00e-cpan-1925d2aa809 )