Acme-Siteswap

 view release on metacpan or  search on metacpan

lib/Acme/Siteswap.pm  view on Meta::CPAN


=cut

sub valid {
    my $self = shift;
    my $pattern = $self->{pattern};

    my @throws;
    eval { @throws = _pattern_to_throws($pattern) };
    if ($@) {
        $self->{error} = $@;
        return 0;
    }

    # Check that the numbers / throws == # of balls
    my $total = 0;
    for my $t (@throws) {
        if (ref $t eq 'ARRAY') {
            foreach my $m_t (@$t) {
                $total += $m_t;
            }
        }
        else {
            $total += $t;
        }
    }

    my $avg = $total / @throws;
    unless ($avg == $self->{balls}) {
        $self->{error} = "sum of throws / # of throws does not equal # of balls!";
        return 0;
    }
	
    return $self->_check_timing(@throws);
}

sub _check_timing {
    my ($self, @throws) = @_;
    
    # foreach non-zero throw, mark where the ball will next be

lib/Acme/Siteswap.pm  view on Meta::CPAN

        
        foreach my $throw (@subthrows) {
            next if $throws[$i] == 0;
            my $next_thrown = ($i + $throw) % scalar @throws;
            $feeds[$next_thrown]++;
        }
    }

    for my $i (0 .. $#throws) {
        if ($feeds[$i] != $throw_map[$i]) {
            $self->{error} = "Multiple throws would land at the same time.";
            return 0;
        }
    }
    return 1;
}

=head2 error

Returns an error message or empty string.

=cut

sub error { $_[0]->{error} || '' }

sub _pattern_to_throws {
    my $pattern = shift;

    my @throw_set = ();

    while ($pattern =~ m/
			# next block of non-multiplex throws
			(?: \G (\d+) ) 
			# or the next multiplex throw

t/siteswaps.t  view on Meta::CPAN

sub test_siteswaps {
    my $patterns = shift;
    for my $test (@$patterns) {
        my $siteswap = Acme::Siteswap->new(
            pattern => $test->{pattern},
            balls => $test->{balls},
        );
        if ($test->{valid}) {
            ok $siteswap->valid, "'$test->{pattern}' is valid";
            if (!$siteswap->valid) {
                diag $siteswap->error;
            }
        }
        else {
            ok !$siteswap->valid, "'$test->{pattern}' is invalid";
            like $siteswap->error, $test->{reason}, 'reason is correct';
        }
    }
}



( run in 0.371 second using v1.01-cache-2.11-cpan-0d8aa00de5b )