f7a86cea23d3ff653bef652984800dcd2a444433
[ccbs] / html / do-start-round.pl
1 #! /usr/bin/perl
2
3 use ccbs;
4 use strict;
5 use warnings;
6
7 my $dbh = ccbs::db_connect();
8 my $cgi = new CGI;
9
10 my $tournament = $cgi->param('tournament');
11 my $round = $cgi->param('round');
12 my $num_random = $cgi->param('numrandom');
13 my $num_chosen = $cgi->param('numchosen');
14 my $num_groups = $cgi->param('numgroups');
15 my $num_qual = $cgi->param('numqual');
16
17 $dbh->{AutoCommit} = 0;
18
19 $dbh->do('INSERT INTO rounds (tournament, round, randomsongs, chosensongs, numqualifying) VALUES (?, ?, ?, ?, ?)',
20         undef, $tournament, $round, $num_random, $num_chosen, $num_qual);
21
22 if ($num_groups == 1) {
23         $dbh->do('INSERT INTO groups (tournament, round, parallel) VALUES (?, ?, ?)',
24                 undef, $tournament, $round, 0);
25 } else {
26         for my $i (1..$num_groups) {
27                 $dbh->do('INSERT INTO groups (tournament, round, parallel) VALUES (?, ?, ?)',
28                         undef, $tournament, $round, $i);
29         }
30 }
31
32 # Seed people into groups (quite preliminary for now)
33 my $people;
34 if ($round == 1) {
35         $people = ccbs::db_fetch_all($dbh, 'SELECT * FROM players WHERE player IN ( SELECT player FROM tournamentparticipation WHERE tournament=? ) ORDER BY lower(nick)',
36                 $tournament);
37 } else {
38         # First of all, check that there are no null values!
39         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);
40         if ($ref->{'num_incomplete'} != 0) {
41                 ccbs::user_error("Det er fortsatt $ref->{'num_incomplete'} sanger igjen i denne runden som ikke har alle data registrert.");
42         }
43
44         # Find out how many people will go on from the _current_ group (ie. the one
45         # before the one we just inserted)
46         my $ref = $dbh->selectrow_hashref('SELECT numqualifying FROM rounds WHERE tournament=? AND round=?',
47                 undef, $tournament, $round - 1);
48         my $num_qual_prev = $ref->{'numqualifying'};
49
50         # Get the total list of scores for each player in this round, and pick
51         # out the best N
52         $people = [];
53         my $q = $dbh->prepare('SELECT parallel,player,SUM(score) AS score FROM scores WHERE tournament=? AND round=? GROUP BY parallel,player ORDER BY parallel, SUM(score) DESC');
54         $q->execute($tournament, $round - 1);
55         
56         my ($parallel,$num_from_this_parallel);
57
58         while (my $ref = $q->fetchrow_hashref()) {
59                 if (!defined($parallel) || $parallel != $ref->{'parallel'}) {
60                         $parallel = $ref->{'parallel'};
61                         $num_from_this_parallel = 0;
62                 }
63                 if ($num_from_this_parallel++ < $num_qual_prev) {
64                         push @$people, {%$ref};
65                 }
66         }
67 }
68
69 if ($num_groups == 1) {
70         # Everybody's in the same group
71         my $position = 1;
72         for my $p (@$people) {
73                 $dbh->do('INSERT INTO roundparticipation (tournament, round, parallel, player, position) VALUES (?, ?, ?, ?, ?)', undef,
74                         $tournament, $round, 0, $p->{'player'}, $position);
75                 $position++;
76         }
77 } else {
78         # Zigzag people to get the most fair groups possible
79         my $group = 1;
80         my $direction = 1;
81         my $position = 1;
82         for my $p (@$people) {
83                 $dbh->do('INSERT INTO roundparticipation (tournament, round, parallel, player, position) VALUES (?, ?, ?, ?, ?)', undef,
84                                 $tournament, $round, $group, $p->{'player'}, $position);
85
86                 if ($group + $direction < 1 || $group + $direction > $num_groups) {
87                         $direction = -$direction;
88                         $position++;
89                 } else {
90                         $group += $direction;
91                 }
92         }
93 }
94
95 # Pick random songs for the groups
96 for my $g (1..$num_groups) {
97         my $gg = ($num_groups == 1) ? 0 : $g;
98
99         for my $s (1..$num_random) {
100                 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',
101                         undef, $tournament);
102                 if (!defined($ref)) {
103                         ccbs::user_error('Det er ikke flere sanger igjen i sangvelgeren!');
104                 }
105                 $dbh->do('INSERT INTO randomsongsused (song) VALUES (?)',
106                         undef, $ref->{'song'});
107                 $dbh->do('INSERT INTO roundrandomsongs (tournament, round, parallel, song) VALUES (?,?,?,?)',
108                         undef, $tournament, $round, $gg, $ref->{'song'});
109
110                 $dbh->do('INSERT INTO scores SELECT tournament,round,parallel,player,?,?,\'single\',\'expert\',\'f\',NULL FROM roundparticipation WHERE tournament=? AND round=? AND parallel=?', undef,
111                         $s, $ref->{'song'}, $tournament, $round, $gg);
112         }
113 }
114
115 # Add empty "score" records for the chosen songs.
116 for my $g (1..$num_groups) {
117         my $gg = ($num_groups == 1) ? 0 : $g;
118
119         for my $s (1..$num_chosen) {
120                 $dbh->do('INSERT INTO scores SELECT tournament,round,parallel,player,?,NULL,\'single\',\'expert\',\'t\',NULL FROM roundparticipation WHERE tournament=? AND round=? AND parallel=?', undef,
121                         $s + $num_random, $tournament, $round, $gg);
122         }
123 }
124
125 ccbs::print_see_other('show-tournament.pl?id=' . $tournament);
126
127 $dbh->commit;
128 $dbh->disconnect;