summaryrefslogtreecommitdiff
path: root/lib/GridFiller/Status.pm
blob: 4f55c6fca35ee87fcc1bb8cba5dde50ba4f83cd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package GridFiller::Status; 
use Moose;
use namespace::autoclean;
use List::Util qw(shuffle);
use List::MoreUtils qw(uniq);
use GridFiller::Types qw(WordListT GridStatusT);
use GridFiller::Constants ':all';
use Carp;
 
with 'MooseX::Log::Log4perl';
 
has words_to_use => (
    isa => WordListT,
    traits => ['Array'],
    handles => {
        has_next_word => 'count',
        get_next_word => 'shift',
    },
    is => 'rw',
    required => 1,
);
 
has grid_status => (
    isa => GridStatusT,
    is => 'rw',
    required => 1,
);
 
around BUILDARGS => sub {
    my ($orig$class$args@rest) = @_;
 
    if (exists $args->{words} && exists $args->{grid}) {
        $args->{words_to_use} = _munge_words_to_use(delete $args->{words});
        $args->{grid_status} = _munge_grid_status(delete $args->{grid});
    }
 
    return $class->$orig($args,@rest);
};
 
sub _munge_words_to_use {
    my $words=shift;
    # clone initial word list 
    return [ shuffle uniq @$words ];
}
 
sub _munge_grid_status {
    my $grid=shift;
    return [
            map {
                [
                    map {
                        $_ eq '*' ? $BLACK : $WHITE
                    @$_
                ]
            @$grid
    ];
}
 
sub place_word_at {
    my ($self$word$x$y$dir) = @_;
 
    $self->log->debug("Marking <$word> occupied at ${x}:${y} ($dir)");
 
    if ($dir == $HORIZONTAL) {
        for my $i (0..length($word)-1) {
            $self->_mark_occupied($x+$i,$y);
        }
    }
    elsif ($dir == $VERTICAL) {
        for my $i (0..length($word)-1) {
            $self->_mark_occupied($x,$y+$i);
        }
    }
    else {
        croak "What dir $dir?";
    }
}
 
sub _mark_occupied {
    my ($self,$x,$y) = @_;
 
    $self->grid_status->[$y][$x]=$NOTHING;
    return;
}
 
sub unfilled {
    my ($self) = @_;
 
    for my $row (@{$self->grid_status}) {
        for my $cell (@$row) {
            return 1 if $cell != $NOTHING;
        }
    }
    return 0;
}
 
{
my %symbols=(
    $NOTHING => ' ',
    $BLACK => 'X',
    $WHITE => 'O',
);
 
sub to_string {
    my ($self) = @_;
 
    my $rows = scalar @{$self->grid_status};
 
    my $str;
 
    for my $row (0..$rows-1) {
        for my $cell (@{$self->grid_status->[$row]}) {
            $str .= $symbols{$cell};
        }
        $str .= "\n";
    }
 
    return $str;
}
}
 
1;