The last do-finish-tournament fix was completely wrong, try to do it properly this...
authorSteinar H. Gunderson <sesse@samfundet.no>
Wed, 30 Mar 2005 02:31:03 +0000 (02:31 +0000)
committerSteinar H. Gunderson <sesse@samfundet.no>
Wed, 30 Mar 2005 02:31:03 +0000 (02:31 +0000)
html/do-finish-tournament.pl

index ec9edf4fa0d5b9b2a94b2473179839b74c5fa7b0..012ccb95b7470596c210a61ffe82cb1d68deef2b 100755 (executable)
@@ -44,15 +44,54 @@ if (!defined($last_sround)) {
 
 # Grab all the remaining groups; we order by the simple criteria:
 # 1. If player A has gone to group X and player B hasn't, player A is higher.
-# 2. If player A has higher max score than player B, player A is higher.
-my $scores = ccbs::db_fetch_all($dbh, 'SELECT player FROM scores WHERE tournament=? AND round < ? GROUP BY round,player ORDER BY round DESC,MAX(score) DESC',
-       $tournament, $last_sround);
-for my $s (@$scores) {
-       next if ($already_ordered{$s->{'player'}});
-       $dbh->do('INSERT INTO tournamentrankings (tournament, ranking, player, points) VALUES (?,?,?,?)',
-                       undef, $tournament, $ranking, $s->{'player'}, points_for_place($ranking));
-       $ranking++;
-       $already_ordered{$s->{'player'}} = 1;
+# 2. If player A has a higher ranking in his/her group than player B, player A is higher.
+# 3. If player A has higher max score than player B, player A is higher.
+
+# Basically, #2 makes this impossible to achieve in pure SQL. We just have
+# to fetch one and one group and make the best out of it. Fetch out all the
+# parallels (in sorted order) and grab all players in turn.
+
+my $qscores = $dbh->prepare('SELECT parallel,player,SUM(score) AS sum_score,MAX(score) AS max_score FROM scores WHERE tournament=? AND round=? GROUP BY parallel,player ORDER BY SUM(score) DESC');
+for my $r (reverse (1..($last_sround-1))) {
+       my @parallels = ();
+       my $num_players = 0;
+       
+       $qscores->execute($tournament, $r);
+
+       while (my $ref = $qscores->fetchrow_hashref()) {
+               my $p = $ref->{'parallel'};
+               if (!defined($parallels[$p])) {
+                       $parallels[$p] = [];
+               }
+
+               push @{$parallels[$p]}, {%$ref};
+               $num_players++;
+       }
+
+       my $place = 0;
+
+       # Grab players from the top until nobody's left
+       while ($num_players > 0) {
+               my @players_this_place = ();
+               for my $p (@parallels) {
+                       next if (!defined($p->[$place]));
+                       $num_players--;
+                       next if ($already_ordered{$p->[$place]->{'player'}});
+
+                       push @players_this_place, $p->[$place];
+               }
+
+               @players_this_place = sort { $b->{'max_score'} <=> $a->{'max_score'} } @players_this_place;
+
+               for my $s (@players_this_place) {
+                       $dbh->do('INSERT INTO tournamentrankings (tournament, ranking, player, points) VALUES (?,?,?,?)',
+                               undef, $tournament, $ranking, $s->{'player'}, points_for_place($ranking));
+                       $ranking++;
+                       $already_ordered{$s->{'player'}} = 1;
+               }
+
+               $place++;
+       }
 }
 
 $dbh->commit;