From: Jan "Yenya" Kasprzak Date: Sun, 12 Dec 2010 21:27:07 +0000 (+0100) Subject: First implementation of qualification. X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=slotcarman.git;a=commitdiff_plain;h=8709f4aa800632f00a54eeb2c85e20b38fe9f6fa First implementation of qualification. --- diff --git a/SCX/Car.pm b/SCX/Car.pm index 3f2b7a3..683a2cc 100644 --- a/SCX/Car.pm +++ b/SCX/Car.pm @@ -128,20 +128,18 @@ sub set_laptime { $self->gui->set_laptime($self->{order}, $lap_time); - if (defined $lap_time) { - if ($lap_time > 1.0 && !$self->{in_pit_lane} - && (!defined $self->{best_lap} - || $self->{best_lap} > $lap_time - )) { - - $self->{best_lap} = $lap_time; - my $global = $self->{track}->check_best_lap($lap_time, - $self->{driver} - ); - $self->gui->set_best_lap($self->{order}, $lap_time, - $global); - } - } + return if !defined $lap_time || $lap_time <= 1.0 + || $self->{in_pit_lane}; + + return if $self->{finished}; + + return if defined $self->{best_lap} && $self->{best_lap} <= $lap_time; + + $self->{best_lap} = $lap_time; + my $global = $self->{track}->check_best_lap($lap_time, + $self->{driver}); + + $self->gui->set_best_lap($self->{order}, $lap_time, $global); } sub set_driver { @@ -246,6 +244,12 @@ sub finish_line { if ($self->track->{race_running}) { $self->set_lap($self->{lap} + 1); + } elsif ($self->track->{qualification_running} && !$self->{finished}) { + $self->set_lap($self->{lap} + 1); + if ($self->{lap} > $self->track->{race_rounds}) { + $self->{finished} = 1; + $self->print_state; + } } return 1; @@ -283,6 +287,26 @@ sub recalc_distance { } } +sub recalc_qual_distance { + my ($self, $time_first) = @_; + + return if !defined $self->{best_lap} || $self->{best_lap} <= 0; + + $self->{total_time} = undef; + $self->{time_diff} = undef; + $self->{grey_diff} = undef; + $self->{lap_diff} = undef; + + if ($self->{best_lap} == $time_first) { + $self->{total_time} = $self->{best_lap}; + } else { + $self->{time_diff} = $self->{best_lap} - $time_first; + } + + $self->gui->set_distance($self->{order}, $self->{total_time}, + $self->{lap_diff}, $self->{time_diff}, $self->{grey_diff}); +} + sub greyout_distance { my ($self) = @_; diff --git a/SCX/Reader.pm b/SCX/Reader.pm index 5422a4b..0106476 100644 --- a/SCX/Reader.pm +++ b/SCX/Reader.pm @@ -260,7 +260,7 @@ sub race_setup_packet { + ($bytes[3] & 0x0F); $self->log_cmd('race_setup', $rounds); - $self->track->race_setup($rounds); + $self->track->race_setup($rounds, $self->{last_read_time}); return $msg; } @@ -306,12 +306,17 @@ sub qualification_packet { if $bytes[0] & 0xF0 || $bytes[1] & 0xF0 || $bytes[2] & 0xF0 - || $bytes[3] > 5 + || $bytes[3] > 6 || $bytes[4] != 0xFF || $bytes[5] != 0xFF; - $self->log_cmd('qualification_start'); - $self->track->qualification_start; + my $rounds = ($bytes[0] & 0x0F) * 256 + + ($bytes[1] & 0x0F) * 16 + + ($bytes[2] & 0x0F); + my $cars = $bytes[3]; + $self->log_cmd('qualification_start', $rounds, $cars); + $self->track->qualification_setup($rounds, $cars, + $self->{last_read_time}); return $msg; } @@ -347,7 +352,7 @@ sub race_start_packet { || $bytes[5] != 0xAA; $self->log_cmd('race_start'); - $self->track->race_start; + $self->track->race_start($self->{last_read_time}); return $msg; } diff --git a/SCX/Track.pm b/SCX/Track.pm index fcf6b80..6c4b644 100644 --- a/SCX/Track.pm +++ b/SCX/Track.pm @@ -19,6 +19,8 @@ sub new { race_running => 0, lap_counting_up => 1, round => 0, + now => 0, + qualification_setup => -100, }; bless $self, $class; @@ -41,16 +43,22 @@ sub new { sub car { return shift->{cars}->[shift]; } sub race_start { - my ($self) = @_; + my ($self, $time) = @_; return if $self->{race_running} || $self->{start_in_progress} || $self->{qualification_running}; - $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); + + 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 { @@ -77,6 +85,7 @@ sub semaphore_step { } return FALSE; } + sub race_end { my ($self) = @_; @@ -84,20 +93,25 @@ sub race_end { } sub race_setup { - my ($self, $rounds) = @_; + my ($self, $rounds, $time) = @_; - $self->{round} = 0; - if ($rounds) { - $self->{race_rounds} = $rounds; + if ($time - $self->{qualification_setup} < 1) { + $self->{round} = 0; } else { - $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); @@ -108,6 +122,7 @@ 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; @@ -126,8 +141,10 @@ sub print_rounds { my ($self) = @_; my $msg; - if ($self->{qualification_running}) { - $msg = 'Qualification'; + 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 { @@ -154,24 +171,29 @@ 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}->rounds('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}); } @@ -220,6 +242,36 @@ sub recalc_order { return ($lap_max_changed, $lap_max, $times[$new_order[0]]); } +sub recalc_qual_order { + my ($self) = @_; + + 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) = @_; @@ -235,6 +287,14 @@ sub finish_line { 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);