Freecell-App

 view release on metacpan or  search on metacpan

lib/Freecell/App/Tableau.pm  view on Meta::CPAN

    $score -= grep !$self->[$_][1], 0 .. 7;          # -empty
    $score -= grep !$self->[$_][0], 0 .. 3;          # -free

    my $seq = 0;
    foreach my $c ( 0 .. 7 ) {    # +sum column sequence breaks
        next unless $z[$c] > 1;
        foreach my $r ( 1 .. ( $z[$c] - 1 ) ) {
            my $src0 = $self->[$c][$r];
            my $src1 = $self->[$c][ $r + 1 ];
            my $brk  = !opposite_colors( $src1, $src0 )
              || rank($src1) + 1 != rank($src0);
            if ($brk) {
                $score += $brk;              # algorithn 1
                $seq   += $src1 >= $src0;    # algorithm 2 - major seq break
            }
        }
    }
    [ $score, $score + $seq ];
}

__END__

=head1 NAME

Freecell::Tableau - Freecell layout.

=head1 VERSION

Version 0.01

=cut

our $VERSION = '0.01';

=head1 SYNOPSIS

The Tableau class manages the creation of the Tableau array from both input
gameno and the position key and token. 

    use Freecell::Tableau;

    my $tableau = Freecell::Tableau->new()->from_deal($gameno);

    -or-

    my $tableau = Freecell::Tableau->new()->from_token($key, $token);


=head1 EXPORT

none.

=head1 SUBROUTINES/METHODS

=head2 new()

Initializes the Tableau with 8 columns and 21 rows of 0's

    columns 0 .. 3 row 0 are the freecells
    columns 4 .. 7 row 0 are the homecells D, C, H, S
    columns 0 .. 7 rows 1 .. 20 are the cascades

=head2 from_token()

This creates a Tableau from the Key and Token built in C<to_token()>.

=head2 to_token()

The key for position is created with C<to_token()> which also creates a 
token array. The token array is needed to rebuild the Tableau from the key.
The key is the chr() of each integer in the Tableau. 

    card->key     A    2    3    4    5    6    7    8    9    T    J    Q    K
      ....0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101
    D 0100....    A    B    C    D    E    F    G    H    I    J    K    L    M
    C 0101....    Q    R    S    T    U    V    W    X    Y    Z    [    \    ]
    H 0110....    a    b    c    d    e    f    g    h    i    j    k    l    m
    S 0111....    q    r    s    t    u    v    w    x    y    z    {    |    }



=head2 from_string($str)

Given a C<new()> Tableau, it will take an input string from C<deal($gameno)> 
and populate the Tableau.
    
    TC -> 'C' -> '1' -> x31 <<4 -> ..01.... 
    +-> + 'T' -> ':' -> x3a &15 -> ....1010 
        + 64  ->        x40     -> .1...... 
        =                          01011010 = x5a ('Z')

=head2 to_string()

Creates a human readable string from Tableau.

=head2 from_deal($gameno)

Thanks to L<http://rosettacode.org/wiki/Deal_cards_for_FreeCell#Perl> 
this generates hands 1 to 1 million with a perl one-liner.

        return (($s = ($s * 214013 + 2531011) % 2**31) >> 16 );

=head2 play($move)

This will take a generated_nodelist entry and perform the move to create a
new Tableau state.

=head2 undo($node)

This will undo a call to C<play()>.

=head2 autoplay($node)

Append to the node all safe moves to home.

=head2 notation($node)

During backtrack, the notation is pushed onto the solution array.

=head2 generate_nodelist()

Creates a node for all valid plays of a given Tableau.

=head2 heuristic

The algorithm is simple.

=over 4

=item * Start with 64.

=item * Subtract the rank of all the top home cards.

=item * Subtract 1 for each empty freecell and empty column.

=item * Add 1 for each sequence break in the cascade
        e.g. 6C 5H 4S 2C KD QS TH has 3 sequence breaks,
        one major at 2C because the KD is greater than
        the 2C.

=back

=head2 helper subroutines

=over 4

=item * opposite_colors() - test if two cards are of opposite color

=item * rank() - return the rank of a card

=item * suit() - return the suit of a card

=item * to_card() - convert a numeric tableau card to a two character string

=back

=head2 getters and setters for two class variables

=over 4

=item * winxp_opt() - was the --win_xp option specified

=item * winxp_warn() - if not, is solution valid for XP

=back

=head1 AUTHOR

Shirl Hart, C<< <shirha at cpan.org> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-freecell-app at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Freecell-App>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Freecell::Tableau


You can also look for information at:

=over 4

=item * RT: CPAN's request tracker (report bugs here)

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Freecell-App>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Freecell-App>

=item * CPAN Ratings



( run in 3.076 seconds using v1.01-cache-2.11-cpan-df04353d9ac )