1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Path::Tiny qw/ path /;
7
8use Test::More tests => 1;
9use Test::Differences qw/ eq_or_diff /;
10use FC_Solve::Paths qw/
11    $FC_SOLVE_EXE
12    bin_board
13    is_freecell_only
14    normalize_lf
15    /;
16
17use Games::Solitaire::Verify::VariantsMap ();
18use FC_Solve::DeltaStater::FccFingerPrint ();
19
20sub _canonicalize_board_string_columns
21{
22    my $s = shift;
23    return $s =~
24        s#((?:^:[^\n]*\n)+)#join"",sort { $a cmp $b} split/^/ms, $1#emrs;
25}
26my $zero_fc_variant =
27    Games::Solitaire::Verify::VariantsMap->new->get_variant_by_id('freecell');
28
29$zero_fc_variant->num_freecells(0);
30
31sub mytest
32{
33    my $DEAL_IDX = shift;
34
35    my $maxlen   = 0;
36    my $board_fn = bin_board("$DEAL_IDX.board");
37    my $delta    = FC_Solve::DeltaStater::FccFingerPrint->new(
38        {
39            variant        => 'custom',
40            variant_params => $zero_fc_variant,
41            init_state_str => normalize_lf(
42                      "Foundations: H-0 C-0 D-0 S-0\n"
43                    . "Freecells:\n"
44                    . ( path($board_fn)->slurp_raw() =~ s/^/: /gmrs )
45            ),
46        }
47    );
48
49    my $was_printed = '';
50    my $count       = 0;
51    open my $exe_fh,
52qq#$FC_SOLVE_EXE -l tfts --freecells-num 0 -sam -sel -c -p -t -mi 3000000 ${board_fn} |#;
53    while ( my $l = <$exe_fh> )
54    {
55        if ( $l =~ /\AFoundations:/ )
56        {
57            while ( ( my $m = <$exe_fh> ) =~ /\S/ )
58            {
59                $l .= $m;
60            }
61            $delta->set_derived(
62                {
63                    state_str => normalize_lf($l),
64                }
65            );
66            my $state_str = $delta->_derived_state->to_string;
67            my $encoded   = $delta->encode_composite();
68            die if @$encoded != 2;
69
70            # say "gotencoded=<@$encoded>";
71            $was_printed = 1;
72            my $this_len = length $encoded->[1];
73            if ( $this_len > 7 )
74            {
75                $DB::single = 1;
76                die "exceeded len in deal $DEAL_IDX";
77            }
78            if ( $state_str !~ m#^:[^\n]*? A[CDHS]\n#ms )
79            {
80                my $round_trip_state;
81                eval { $round_trip_state = $delta->decode($encoded); };
82                if ( my $err = $@ )
83                {
84                    print "error <$err> when processing <$state_str>.";
85                    die $err;
86                }
87                my $round_trip_str = $round_trip_state->to_string();
88                die "mismatch $round_trip_str vs $state_str\n."
89                    if _canonicalize_board_string_columns($round_trip_str) ne
90                    _canonicalize_board_string_columns($state_str);
91            }
92
93            $maxlen = $this_len if $this_len > $maxlen;
94        }
95    }
96    return cmp_ok( $maxlen, '<=', 7, "maxlen for deal = $DEAL_IDX" );
97}
98
99{
100SKIP:
101    {
102        if ( is_freecell_only() )
103        {
104            Test::More::skip(
105                "freecells hard coded to 4 - we need zero freecells", 1 );
106        }
107
108        # TEST
109        mytest(164);
110    }
111}
112__END__
113
114=head1 COPYRIGHT AND LICENSE
115
116This file is part of Freecell Solver. It is subject to the license terms in
117the COPYING.txt file found in the top-level directory of this distribution
118and at http://fc-solve.shlomifish.org/docs/distro/COPYING.html . No part of
119Freecell Solver, including this file, may be copied, modified, propagated,
120or distributed except according to the terms contained in the COPYING file.
121
122Copyright (c) 2011 Shlomi Fish
123
124=cut
125