--- /dev/null
+- Proper functionality for editing groups (adding/deleting players and songs)
+- Ability to edit players (in particular, fix country/group)
+- Multiple variations on short titles
+- Add DP/pass in addition to score
+- Auto-reset of the song selector on first elimination round?
+- Fix the "highest average" screen and pull it in from ccbs--tg
+- Link to songratings.pl from somewhere public
+- Warning when an entered score is too high for a given song
+- A flag for determining playmode in a tournament (single, double, both),
+ and make the bigscreen understand it.
+- Make the bigscreen understand the special order of chosen songs in the
+ first round.
if (glyph_index == 0)
continue;
+#if SCREEN_LCD
+ if (FT_Load_Glyph(*j, glyph_index, FT_LOAD_RENDER | FT_LOAD_TARGET_LCD))
+#else
if (FT_Load_Glyph(*j, glyph_index, FT_LOAD_RENDER))
+#endif
throw std::runtime_error("Couldn't load glyph");
slot = (*j)->glyph;
break;
if (dsty < 0 || dsty > signed(screen_height-1)) continue;
unsigned char *dst = buf + dsty * screen_width*4 + (x + xpos + slot->bitmap_left)*4;
- unsigned char *src = bm->buffer + y * bm->width;
-
+#if SCREEN_LCD
+ unsigned char *src = bm->buffer + y * bm->pitch;
+ int width = (x + xpos + slot->bitmap_left + bm->width/3 >= signed(screen_width)) ? ((screen_width-1) - x - xpos - slot->bitmap_left) : bm->width/3;
+#else
+ unsigned char *src = bm->buffer + y * bm->pitch;
int width = (x + xpos + slot->bitmap_left + bm->width >= signed(screen_width)) ? ((screen_width-1) - x - xpos - slot->bitmap_left) : bm->width;
+#endif
+
+#if SCREEN_LCD
+ for (xx = 0; xx < width; xx++) {
+ *dst = (*dst * (256-src[2]) + b * src[2]) >> 8;
+ ++dst;
+ *dst = (*dst * (256-src[1]) + g * src[1]) >> 8;
+ ++dst;
+ *dst = (*dst * (256-src[0]) + r * src[0]) >> 8;
+ ++dst;
+ *dst++ = 0;
+
+ src += 3;
+ }
+#else
for (xx = 0; xx < width; xx++) {
*dst = (*dst * (256-*src) + b * *src) >> 8;
- *dst++;
+ ++dst;
*dst = (*dst * (256-*src) + g * *src) >> 8;
- *dst++;
+ ++dst;
*dst = (*dst * (256-*src) + r * *src) >> 8;
- *dst++;
+ ++dst;
*dst++ = 0;
- src++;
+ ++src;
}
+#endif
}
}
#ifndef _RESOLUTION_H
#define _RESOLUTION_H 1
-#define SCREEN_WIDTH 1024
-#define SCREEN_HEIGHT 768
+#define SCREEN_WIDTH 800
+#define SCREEN_HEIGHT 600
+#define SCREEN_LCD 1
/*
* This is used in the screens, mostly for historical reasons (they were
my $ranking = 1;
my $points = 100;
-# Find all last rounds with only one group per round
-my $srounds = ccbs::db_fetch_all($dbh, 'SELECT round FROM groups WHERE tournament=? GROUP BY round HAVING COUNT(*) = 1 ORDER BY round DESC', $tournament);
-
-my $last_sround;
-for my $sr (@$srounds) {
- # only accept strict ordering
- last if (defined($last_sround) && $sr->{'round'} != $last_sround - 1);
- $last_sround = $sr->{'round'};
-
- # Grab the highscore list from this round
- my $scores = ccbs::db_fetch_all($dbh, 'SELECT player,SUM(score) AS score FROM scores WHERE tournament=? AND round=? GROUP BY parallel,player ORDER BY SUM(score) DESC',
- $tournament, $sr->{'round'});
- 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;
- }
-}
-
-# This should never happen
-if (!defined($last_sround)) {
- ccbs::user_error("Forsøk på å avslutte en turnering med flere grupper aktive.");
-}
-
-# Grab all the remaining groups; we order by the simple criteria:
+# Grab all the 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 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++;
- }
+# 2. If player A has a higher (max sum of songs)/(max feet of songs) (where
+# any chosen song counts for 10) than B, player A is higher.
+my $scores = ccbs::db_fetch_all($dbh, 'SELECT player FROM scores NATURAL JOIN tournaments NATURAL JOIN max_single_feetrating WHERE tournament=? GROUP BY round,player ORDER BY round DESC,SUM(score)/SUM(CASE WHEN chosen THEN 10 ELSE feetrating END) DESC',
+ $tournament);
+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;
}
$dbh->commit;
# 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) AS score FROM scores WHERE tournament=? AND round=? GROUP BY parallel,player ORDER BY parallel, SUM(score) DESC');
+ 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);
if ($num_groups == 1) {
# Everybody's in the same group
+ my @speople = sort { $a->{'score'} <=> $b->{'score'} } @$people;
+
my $position = 1;
- for my $p (@$people) {
+ for my $p (@speople) {
$dbh->do('INSERT INTO roundparticipation (tournament, round, parallel, player, position) VALUES (?, ?, ?, ?, ?)', undef,
$tournament, $round, 0, $p->{'player'}, $position);
$position++;
}
} else {
# 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);
+ my @speople = sort { $b->{'score'} <=> $a->{'score'} } @$people;
- if ($group + $direction < 1 || $group + $direction > $num_groups) {
+ 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;
- $position++;
} 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!');
);
CREATE INDEX songratings_feetrating ON songratings ( feetrating );
+CREATE VIEW max_single_feetrating AS SELECT machine,song,MAX(feetrating) AS feetrating FROM songratings WHERE playmode='single' GROUP BY machine,song;
+
CREATE TABLE players (
player SERIAL PRIMARY KEY,
nick VARCHAR NOT NULL,