| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Games::Cellulo::Game; | 
| 2 |  |  |  |  |  |  | $Games::Cellulo::Game::VERSION = '0.2_01'; | 
| 3 | 1 |  |  | 1 |  | 384 | use strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 53 |  | 
| 4 | 1 |  |  | 1 |  | 3 | use warnings FATAL => 'all'; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 35 |  | 
| 5 | 1 |  |  | 1 |  | 309 | use Games::Cellulo::Game::Screen; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 29 |  | 
| 6 | 1 |  |  | 1 |  | 534 | use Time::HiRes; | 
|  | 1 |  |  |  |  | 1112 |  | 
|  | 1 |  |  |  |  | 11 |  | 
| 7 | 1 |  |  | 1 |  | 534 | use Games::Cellulo::Game::Particle; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 32 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 | 1 |  |  | 1 |  | 6 | use Moo; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 10 | 1 |  |  | 1 |  | 903 | use MooX::Options; | 
|  | 1 |  |  |  |  | 20202 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | has screen => ( is => 'lazy', handles => [qw/ grid /] ); | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | option sleep_time => ( | 
| 15 |  |  |  |  |  |  | is => 'ro', | 
| 16 |  |  |  |  |  |  | format => 's', | 
| 17 |  |  |  |  |  |  | required => 0, | 
| 18 |  |  |  |  |  |  | doc => 'time to sleep between frames', | 
| 19 |  |  |  |  |  |  | default => sub { .03 }, | 
| 20 |  |  |  |  |  |  | ); | 
| 21 |  |  |  |  |  |  | option num_particles => ( | 
| 22 |  |  |  |  |  |  | is => 'ro', | 
| 23 |  |  |  |  |  |  | format => 'i', | 
| 24 |  |  |  |  |  |  | default => sub { 500 }, | 
| 25 |  |  |  |  |  |  | doc => "number of onscreen particles", | 
| 26 |  |  |  |  |  |  | ); | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | option meld => ( | 
| 29 |  |  |  |  |  |  | is => 'ro', | 
| 30 |  |  |  |  |  |  | doc => 'particles should turn in to each other when stuck' | 
| 31 |  |  |  |  |  |  | ); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | has screen_args => ( | 
| 34 |  |  |  |  |  |  | is => 'ro', | 
| 35 |  |  |  |  |  |  | default => sub { +{} }, | 
| 36 |  |  |  |  |  |  | ); | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | has particles => ( | 
| 39 |  |  |  |  |  |  | is => 'rw', | 
| 40 |  |  |  |  |  |  | default => sub { [] }, | 
| 41 |  |  |  |  |  |  | ); | 
| 42 |  |  |  |  |  |  | sub _rand_dir { | 
| 43 | 0 |  |  | 0 |  |  | int( rand(3) ) - 1; | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  | sub _build_screen { | 
| 46 | 0 |  |  | 0 |  |  | Games::Cellulo::Game::Screen->new( shift->screen_args ) | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | sub randx { | 
| 50 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 51 | 0 |  |  |  |  |  | my $cols = $self->screen->cols; | 
| 52 | 0 |  |  |  |  |  | int( rand( $cols )  ); | 
| 53 |  |  |  |  |  |  | } | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | sub randy { | 
| 56 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 57 | 0 |  |  |  |  |  | my $rows = $self->screen->rows; | 
| 58 | 0 |  |  |  |  |  | int( rand( $rows )  ); | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | sub init { | 
| 63 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 64 | 0 |  |  |  |  |  | my $rows = $self->screen->rows; | 
| 65 | 0 |  |  |  |  |  | my $cols = $self->screen->cols; | 
| 66 | 0 |  |  |  |  |  | $self->screen->clrscr; | 
| 67 | 0 |  |  |  |  |  | my $grid = $self->screen->grid; | 
| 68 | 0 |  |  |  |  |  | my @particles; | 
| 69 | 0 |  |  |  |  |  | for ( 1 .. $self->num_particles ) { | 
| 70 | 0 |  |  |  |  |  | my $randy = $self->randy; | 
| 71 | 0 |  |  |  |  |  | my $randx = $self->randx; | 
| 72 | 0 | 0 |  |  |  |  | next if $grid->[$randy][$randx]; | 
| 73 | 0 |  |  |  |  |  | $grid->[$randy][$randx] = Games::Cellulo::Game::Particle->new( | 
| 74 |  |  |  |  |  |  | rows => $rows, | 
| 75 |  |  |  |  |  |  | cols => $cols, | 
| 76 |  |  |  |  |  |  | x    => $randx, | 
| 77 |  |  |  |  |  |  | y    => $randy, | 
| 78 |  |  |  |  |  |  | type => int( rand(4) + 1 ), | 
| 79 |  |  |  |  |  |  | ); | 
| 80 | 0 |  |  |  |  |  | push( @particles, $grid->[$randy][$randx] ); | 
| 81 |  |  |  |  |  |  | } | 
| 82 | 0 |  |  |  |  |  | $self->particles( \@particles ); | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  | my $_moves = 0; | 
| 85 | 0 |  |  | 0 | 0 |  | sub moves{ $_moves } | 
| 86 |  |  |  |  |  |  | sub play { | 
| 87 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 88 | 0 |  |  |  |  |  | my $_scr = $self->screen; | 
| 89 | 0 |  |  |  |  |  | my $sleep_time = $self->sleep_time; | 
| 90 | 0 |  |  |  |  |  | while( !$_scr->key_pressed ) { | 
| 91 | 0 |  |  |  |  |  | $self->draw; | 
| 92 | 0 |  |  |  |  |  | Time::HiRes::sleep $sleep_time; | 
| 93 | 0 |  |  |  |  |  | $_moves++; | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | sub draw_grid { | 
| 98 | 0 |  |  | 0 | 0 |  | my $self   = shift; | 
| 99 | 0 |  |  |  |  |  | my $screen = $self->screen; | 
| 100 | 0 |  |  |  |  |  | my $grid   = $self->screen->grid; | 
| 101 |  |  |  |  |  |  | #    $self->screen->clrscr; | 
| 102 | 0 |  |  |  |  |  | my $rows = $screen->rows; | 
| 103 | 0 |  |  |  |  |  | my @str; | 
| 104 | 0 |  |  |  |  |  | $screen->at(0,0); | 
| 105 | 0 |  |  |  |  |  | for ( 0 .. $rows - 1 ) { | 
| 106 | 0 | 0 |  |  |  |  | push @str, map { $_ ? $_->char : " " } @{ $grid->[$_] }; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | } | 
| 108 | 0 |  |  |  |  |  | print @str; | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | my $_move = sub { | 
| 112 |  |  |  |  |  |  | my ( $p, $wantx, $wanty, $grid ) = @_; | 
| 113 |  |  |  |  |  |  | $grid->[$wanty][$wantx] = $p; | 
| 114 |  |  |  |  |  |  | $grid->[ $p->y ][ $p->x ] = undef; | 
| 115 |  |  |  |  |  |  | $p->x($wantx); | 
| 116 |  |  |  |  |  |  | $p->y($wanty); | 
| 117 |  |  |  |  |  |  | }; | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | sub move_particles { | 
| 120 | 0 |  |  | 0 | 0 |  | my $self  = shift; | 
| 121 | 0 |  |  |  |  |  | my $screen = $self->screen; | 
| 122 | 0 |  |  |  |  |  | my $grid  = $screen->grid; | 
| 123 | 0 |  |  |  |  |  | for ( @{ $self->particles } ) { | 
|  | 0 |  |  |  |  |  |  | 
| 124 | 0 |  |  |  |  |  | my $wantx = $screen->xpos( $_->x + $_->xdir ); | 
| 125 | 0 |  |  |  |  |  | my $wanty = $screen->ypos( $_->y + $_->ydir ); | 
| 126 | 0 | 0 |  |  |  |  | unless ( $grid->[$wanty][$wantx] ) { | 
| 127 | 0 |  |  |  |  |  | $_move->( $_, $wantx, $wanty, $grid ); | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  | else { | 
| 130 | 0 |  |  |  |  |  | my $avoid_dir = $_->avoid_dir; | 
| 131 | 0 | 0 |  |  |  |  | next unless $avoid_dir; | 
| 132 | 0 |  |  |  |  |  | my $avoid_dir_string = join ',' => @$avoid_dir; | 
| 133 | 0 |  |  |  |  |  | $_->num_avoid_tries($_->num_avoid_tries+1); | 
| 134 | 0 |  |  |  |  |  | $_->tries_in_direction->{$avoid_dir_string}++; | 
| 135 | 0 |  |  |  |  |  | $wantx = $screen->xpos( $_->x + $avoid_dir->[0] ); | 
| 136 | 0 |  |  |  |  |  | $wanty = $screen->ypos( $_->y + $avoid_dir->[1] ); | 
| 137 | 0 | 0 | 0 |  |  |  | unless ( $grid->[$wanty][$wantx] ) { | 
| 138 | 0 |  |  |  |  |  | $_move->( $_, $wantx, $wanty, $grid ); | 
| 139 | 0 |  |  |  |  |  | $_->successes_in_direction->{$avoid_dir_string}++; | 
| 140 | 0 |  |  |  |  |  | $_->num_successes( $_->num_successes+1 ); | 
| 141 |  |  |  |  |  |  | } elsif( $self->meld ) { | 
| 142 |  |  |  |  |  |  | $_->type( $grid->[$wanty][$wantx]->type ); | 
| 143 |  |  |  |  |  |  | $_->clear_xdir; | 
| 144 |  |  |  |  |  |  | $_->clear_ydir; | 
| 145 |  |  |  |  |  |  | $_->clear_char; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  | } | 
| 148 |  |  |  |  |  |  | } | 
| 149 |  |  |  |  |  |  | } | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | sub draw { | 
| 152 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 153 |  |  |  |  |  |  | #   $self->screen->at(0,0); | 
| 154 | 0 |  |  |  |  |  | $self->move_particles; | 
| 155 |  |  |  |  |  |  | #    $self->screen->reset_grid; | 
| 156 | 0 |  |  |  |  |  | $self->draw_grid; | 
| 157 |  |  |  |  |  |  | } | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | 1; | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | __END__ |