X-Git-Url: https://git.sesse.net/?p=ccbs;a=blobdiff_plain;f=html%2Fdo-start-round.pl;h=ff02c26a62a6d4b85582b52f8cce8e1ef1960afb;hp=2637076503eddb76584864307c6f6555323f4a92;hb=bb5fde29696b2b5bce9e4431c01fe9ec29f4207c;hpb=ea702e677702b5cbb22f819d8f0731715e887d03 diff --git a/html/do-start-round.pl b/html/do-start-round.pl index 2637076..ff02c26 100755 --- a/html/do-start-round.pl +++ b/html/do-start-round.pl @@ -4,6 +4,8 @@ use ccbs; use strict; use warnings; +ccbs::admin_only(); + my $dbh = ccbs::db_connect(); my $cgi = new CGI; @@ -19,40 +21,101 @@ $dbh->{AutoCommit} = 0; $dbh->do('INSERT INTO rounds (tournament, round, randomsongs, chosensongs, numqualifying) VALUES (?, ?, ?, ?, ?)', undef, $tournament, $round, $num_random, $num_chosen, $num_qual); -for my $i (1..$num_groups) { +if ($num_groups == 1) { $dbh->do('INSERT INTO groups (tournament, round, parallel) VALUES (?, ?, ?)', - undef, $tournament, $round, $i); + undef, $tournament, $round, 0); +} else { + for my $i (1..$num_groups) { + $dbh->do('INSERT INTO groups (tournament, round, parallel) VALUES (?, ?, ?)', + undef, $tournament, $round, $i); + } } # Seed people into groups (quite preliminary for now) my $people; if ($round == 1) { - $people = ccbs::db_fetch_all($dbh, 'SELECT * FROM players WHERE player IN ( SELECT player FROM tournamentparticipation WHERE tournament=? ) ORDER BY lower(nick)', + $people = ccbs::db_fetch_all($dbh, 'SELECT * FROM players WHERE player IN ( SELECT player FROM tournamentparticipation WHERE tournament=? ) ORDER BY random()', $tournament); } else { - die "Fix qualifying later"; + # First of all, check that there are no null values! + my $ref = $dbh->selectrow_hashref('SELECT COUNT(*) AS num_incomplete FROM scores WHERE tournament=? AND round=? AND (song IS NULL OR playmode IS NULL OR difficulty IS NULL OR chosen IS NULL or score IS NULL)', undef, $tournament, $round-1); + if ($ref->{'num_incomplete'} != 0) { + ccbs::user_error("Det er fortsatt $ref->{'num_incomplete'} sanger igjen i denne runden som ikke har alle data registrert."); + } + + # Find out how many people will go on from the _current_ group (ie. the one + # before the one we just inserted) + my $ref = $dbh->selectrow_hashref('SELECT numqualifying FROM rounds WHERE tournament=? AND round=?', + undef, $tournament, $round - 1); + my $num_qual_prev = $ref->{'numqualifying'}; + + # Get the total list of scores for each player in this round, and pick + # out the best N + $people = []; + my $q = $dbh->prepare('SELECT parallel,player,SUM(score)/SUM(CASE WHEN chosen THEN 10 ELSE feetrating END) AS score FROM scores NATURAL JOIN tournaments NATURAL JOIN max_single_feetrating WHERE tournament=? AND round=? GROUP BY parallel,player ORDER BY parallel, SUM(score) DESC'); + $q->execute($tournament, $round - 1); + + my ($parallel,$num_from_this_parallel); + + while (my $ref = $q->fetchrow_hashref()) { + if (!defined($parallel) || $parallel != $ref->{'parallel'}) { + $parallel = $ref->{'parallel'}; + $num_from_this_parallel = 0; + } + if ($num_from_this_parallel++ < $num_qual_prev) { + push @$people, {%$ref}; + } + } } -# Zigzag people to get the most fair groups possible -my $group = 1; -my $direction = 1; -my $position = 1; -for my $p (@$people) { - $dbh->do('INSERT INTO roundparticipation (tournament, round, parallel, player, position) VALUES (?, ?, ?, ?, ?)', undef, - $tournament, $round, $group, $p->{'player'}, $position); +if ($num_groups == 1) { + # Everybody's in the same group + my @speople = sort { $a->{'score'} <=> $b->{'score'} } @$people; - if ($group + $direction < 1 || $group + $direction > $num_groups) { - $direction = -$direction; + my $position = 1; + for my $p (@speople) { + $dbh->do('INSERT INTO roundparticipation (tournament, round, parallel, player, position) VALUES (?, ?, ?, ?, ?)', undef, + $tournament, $round, 0, $p->{'player'}, $position); $position++; - } else { - $group += $direction; + } +} else { + # Zigzag people to get the most fair groups possible + my @speople = sort { $b->{'score'} <=> $a->{'score'} } @$people; + + my @ngroups = (); + for my $g (1..$num_groups) { + push @ngroups, []; + } + + my $group = 0; + my $direction = 1; + for my $p (@speople) { + push @{$ngroups[$group]}, $p->{'player'}; + if ($group + $direction < 0 || $group + $direction >= $num_groups) { + $direction = -$direction; + } else { + $group += $direction; + } + } + + $group = 1; + for my $g (@ngroups) { + my @gpeople = reverse @$g; + for my $position (0..$#gpeople) { + $dbh->do('INSERT INTO roundparticipation (tournament, round, parallel, player, position) VALUES (?, ?, ?, ?, ?)', undef, + $tournament, $round, $group, $gpeople[$position], $position + 1); + } + $group++; } } -# Pick random songs for the groups +# Pick random songs for the groups (don't pick challenge-only songs; slightly +# clumsy, should we have used an IN subquery instead?) for my $g (1..$num_groups) { + my $gg = ($num_groups == 1) ? 0 : $g; + for my $s (1..$num_random) { - my $ref = $dbh->selectrow_hashref('SELECT * FROM machinesongs WHERE song NOT IN ( SELECT song FROM randomsongsused ) AND machine=( SELECT machine FROM tournaments WHERE tournament=? ) ORDER BY random() LIMIT 1', + my $ref = $dbh->selectrow_hashref('SELECT * FROM machinesongs NATURAL JOIN songratings WHERE song NOT IN ( SELECT song FROM randomsongsused ) AND machine=( SELECT machine FROM tournaments WHERE tournament=? ) AND playmode=\'single\' AND difficulty=\'expert\' ORDER BY random() LIMIT 1', undef, $tournament); if (!defined($ref)) { ccbs::user_error('Det er ikke flere sanger igjen i sangvelgeren!'); @@ -60,18 +123,20 @@ for my $g (1..$num_groups) { $dbh->do('INSERT INTO randomsongsused (song) VALUES (?)', undef, $ref->{'song'}); $dbh->do('INSERT INTO roundrandomsongs (tournament, round, parallel, song) VALUES (?,?,?,?)', - undef, $tournament, $round, $g, $ref->{'song'}); + undef, $tournament, $round, $gg, $ref->{'song'}); - $dbh->do('INSERT INTO scores SELECT tournament,round,parallel,player,?,?,NULL,NULL,\'f\',NULL FROM roundparticipation WHERE tournament=? AND round=? AND parallel=?', undef, - $s, $ref->{'song'}, $tournament, $round, $g); + $dbh->do('INSERT INTO scores SELECT tournament,round,parallel,player,?,?,\'single\',\'expert\',\'f\',NULL FROM roundparticipation WHERE tournament=? AND round=? AND parallel=?', undef, + $s, $ref->{'song'}, $tournament, $round, $gg); } } # Add empty "score" records for the chosen songs. for my $g (1..$num_groups) { + my $gg = ($num_groups == 1) ? 0 : $g; + for my $s (1..$num_chosen) { - $dbh->do('INSERT INTO scores SELECT tournament,round,parallel,player,?,NULL,NULL,NULL,\'t\',NULL FROM roundparticipation WHERE tournament=? AND round=? AND parallel=?', undef, - $s + $num_random, $tournament, $round, $g); + $dbh->do('INSERT INTO scores SELECT tournament,round,parallel,player,?,NULL,\'single\',\'expert\',\'t\',NULL FROM roundparticipation WHERE tournament=? AND round=? AND parallel=?', undef, + $s + $num_random, $tournament, $round, $gg); } }