X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=SCX%2FTrack.pm;h=6c4b6447cf41f0afd99c55b7f3cd2cfd4abe8239;hb=0bc768df52ed78631f048762071a3333e1030af5;hp=09db4b708690c753f4b2e9f549fb893c8c1745ce;hpb=041b40ba9d04693394c1472224cbb4285a0280c3;p=slotcarman.git diff --git a/SCX/Track.pm b/SCX/Track.pm index 09db4b7..6c4b644 100644 --- a/SCX/Track.pm +++ b/SCX/Track.pm @@ -14,11 +14,14 @@ our $SEMAPHORE_STEP = 1000; sub new { my ($class, $args) = @_; - my $self; - - $self->{gui} = $args->{gui} or croak; - $self->{race_running} = 0; - $self->{lap_counting_up} = 1; + my $self = { + gui => $args->{gui}, + race_running => 0, + lap_counting_up => 1, + round => 0, + now => 0, + qualification_setup => -100, + }; bless $self, $class; @@ -28,23 +31,34 @@ sub new { id => $i, track => $self, }); - $self->car($i)->set_order($i); } + $self->print_rounds; + $self->{gui}->time(undef); + $self->{gui}->best_lap(undef, undef); + return $self; } sub car { return shift->{cars}->[shift]; } sub race_start { - my ($self) = @_; + my ($self, $time) = @_; - return if $self->{race_running} || $self->{start_in_progress}; - $self->{race_running} = 0; - $self->{start_in_progress} = 1; - $self->{semaphore} = 0; - $self->{gui}->show_semaphore(0); - Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); + return if $self->{race_running} || $self->{start_in_progress} + || $self->{qualification_running}; + + if ($time - $self->{qualification_setup} < 1) { + $self->{qualification_running} = 1; + } else { + $self->{round} = 0; + $self->{race_running} = 0; + $self->{start_in_progress} = 1; + $self->{semaphore} = 0; + $self->{gui}->show_semaphore(0); + Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); + } + $self->print_rounds; } sub semaphore_step { @@ -64,7 +78,7 @@ sub semaphore_step { $self->{race_running_since} = gettimeofday; $self->{start_in_progress} = undef; $self->{gui}->show_semaphore(0); - Glib::Timeout->add(3*$SEMAPHORE_STEP, \&semaphore_step, $self); + Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); } else { $self->{gui}->show_semaphore(undef); $self->{semaphore} = undef; @@ -79,35 +93,75 @@ sub race_end { } sub race_setup { - my ($self, $rounds) = @_; + my ($self, $rounds, $time) = @_; - if ($rounds) { - $self->{gui}->rounds('0/' . $rounds); - $self->{race_rounds} = $rounds; + if ($time - $self->{qualification_setup} < 1) { + $self->{round} = 0; } else { - $self->{gui}->rounds('0'); - $self->{race_rounds} = 0; + if ($rounds) { + $self->{race_rounds} = $rounds; + } else { + $self->{race_rounds} = 0; + } } + + $self->{round} = 0; + $self->print_rounds; $self->{best_lap} = undef; $self->{gui}->show_semaphore(undef); $self->{race_running} = 0; + $self->{qualification_running} = 0; $self->{start_in_progress} = 0; $self->{gui}->time(undef); $self->{gui}->best_lap(undef); +} + +sub reset { + my ($self) = @_; + + $self->{race_running} = 0; + $self->{qualification_running} = 0; + $self->{start_in_progress} = 0; + $self->{race_finishing} = 0; + $self->{best_lap} = undef; + $self->{round} = 0; + + $self->print_rounds; + $self->{gui}->best_lap(undef); + $self->{gui}->time(undef); for my $car (0..5) { $self->car($car)->reset; - $self->car($car)->set_order($car); } } +sub print_rounds { + my ($self) = @_; + + my $msg; + if ($self->{qualification_running} + || $self->{now} - $self->{qualification_setup} < 1) { + $msg = 'Qualification: ' . $self->{race_rounds} + . ($self->{race_rounds} == 1 ? ' round' : ' rounds'); + } elsif ($self->{race_rounds}) { + $msg = $self->{round} . '/' . $self->{race_rounds}; + } else { + $msg = $self->{round}; + } + + $self->{gui}->rounds($msg); +} + sub check_best_lap { my ($self, $time, $who) = @_; return if !defined $time || $time == 0; +# print "Check_best_lap $time $who vs ", +# defined $self->{best_lap} ? $self->{best_lap} : 'undef', +# "\n"; if (!defined $self->{best_lap} || $time < $self->{best_lap}) { $self->{best_lap} = $time; @@ -117,33 +171,142 @@ sub check_best_lap { return 0; } -sub qualification_start { - my ($self) = @_; +sub qualification_setup { + my ($self, $rounds, $cars, $time) = @_; return if $self->{qualification_running}; + for my $car (0..5) { $self->car($car)->set_lap(undef); $self->car($car)->set_laptime(undef); } - $self->{qualification_running} = 1; - $self->{gui}->lap('Qualification'); + $self->{qualification_setup} = $time; + $self->{race_rounds} = $rounds; + $self->{qualification_cars} = $cars; $self->{gui}->time(undef); $self->{gui}->best_lap(undef); + $self->print_rounds; } sub packet_received { my ($self, $time) = @_; + $self->{now} = $time; + if ($self->{race_running}) { - $self->gui->time($time - $self->{race_running_since}); + $self->{gui}->time($time - $self->{race_running_since}); } } sub recalc_order { + my ($self, $now) = @_; + + return if !$self->{race_running}; + + my @laps; + my @times; + for my $id (0..5) { + $laps[$id] = $self->car($id)->{lap} // -1; + $times[$id] = $self->car($id)->{first_finish_time} // $now; + } + + my @new_order = sort { + $laps[$b] <=> $laps[$a] + || + $times[$a] <=> $times[$b] + || + $a <=> $b; + } (0..5); + + my $lap_max = $laps[$new_order[0]]; + my $lap_max_changed = 0; + if (defined $lap_max && defined $self->{round} + && $lap_max != $self->{round}) { + $self->{round} = $lap_max; + $lap_max_changed = 1; + $self->print_rounds; + } + + if ($self->{round} && $self->{race_rounds} + && $self->{round} > $self->{race_rounds}) { + $self->{race_finishing} = 1; + } + + for my $id (0..5) { + my $car = $new_order[$id]; + if ($self->car($car)->{order} != $id) { + $self->car($car)->set_order($id); + } + } + return ($lap_max_changed, $lap_max, $times[$new_order[0]]); +} + +sub recalc_qual_order { my ($self) = @_; - # FIXME: Implement me + return if !$self->{qualification_running}; + + my @times; + for my $id (0..5) { + $times[$id] = $self->car($id)->{best_lap}; + if (!defined $times[$id] || $times[$id] <= 0) { + $times[$id] = 999_999; + } + } + + my @new_order = sort { + $times[$a] <=> $times[$b] + || + $a <=> $b; + } (0..5); + + my $best_time = $times[$new_order[0]]; + + for my $id (0..5) { + my $car = $new_order[$id]; + if ($self->car($car)->{order} != $id) { + $self->car($car)->set_order($id); + } + } + return ($times[$new_order[0]]); +} + +sub finish_line { + my ($self, $time, $regular, @cars) = @_; + + my %processed; + my $was_processed; + + for my $car (@cars) { + if ($self->car($car)->finish_line($time, $regular)) { + $processed{$car} = 1; + $was_processed = 1; + } + } + + return if !$was_processed; + + if ($self->{qualification_running}) { + my ($best) = $self->recalc_qual_order; + for my $car (0..5) { + $self->car($car)->recalc_qual_distance($best); + } + return; + } + + my ($lap_max_changed, $lap_max, $time_min) + = $self->recalc_order($time); + + for my $car (0..5) { + if ($processed{$car}) { + $self->car($car)->recalc_distance( + $lap_max, $time_min, $self->{race_finishing}, + ); + } elsif ($lap_max_changed) { + $self->car($car)->greyout_distance; + } + } } 1;