From 416d3d469d9ce4c15a860f61e24aee79da12402d Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 23 Apr 2005 00:48:17 +0000 Subject: [PATCH] Pull in changes from --baby. Patches applied: * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-2 UTF-8 fix. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-3 Change the final ranking list generation to the new rules. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-4 Seed people from round N to round N+1 based on the new system. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-5 Divide by the max possible songrating for single mode, not the max possible songrating for whatever the player chose to play. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-6 Don't pick challenge-only songs. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-7 Make sure the best players get last in their groups. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-8 Remove some debugging statements. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-9 Add TODO. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-10 Reduce resolution for laptop (local commit). * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-11 Add support for sub-pixel rendering for LCD screens. * sgunderson@bigfoot.com--2005-baby/ccbs--baby--0.1--patch-12 Update TODO --- TODO | 12 +++++ bigscreen/fonts.cpp | 35 ++++++++++++--- bigscreen/resolution.h | 5 ++- html/do-finish-tournament.pl | 86 +++++------------------------------- html/do-start-round.pl | 40 ++++++++++++----- sql/ccbs.sql | 2 + 6 files changed, 85 insertions(+), 95 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..1c799a6 --- /dev/null +++ b/TODO @@ -0,0 +1,12 @@ +- 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. diff --git a/bigscreen/fonts.cpp b/bigscreen/fonts.cpp index 8ceb871..cedd03a 100644 --- a/bigscreen/fonts.cpp +++ b/bigscreen/fonts.cpp @@ -61,7 +61,11 @@ unsigned my_draw_text(const widestring &str, unsigned char *buf, double size, in 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; @@ -80,19 +84,38 @@ unsigned my_draw_text(const widestring &str, unsigned char *buf, double size, in 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 } } diff --git a/bigscreen/resolution.h b/bigscreen/resolution.h index a8be1d4..a27b336 100644 --- a/bigscreen/resolution.h +++ b/bigscreen/resolution.h @@ -1,8 +1,9 @@ #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 diff --git a/html/do-finish-tournament.pl b/html/do-finish-tournament.pl index 012ccb9..bea25b4 100755 --- a/html/do-finish-tournament.pl +++ b/html/do-finish-tournament.pl @@ -16,82 +16,18 @@ my %already_ordered = (); 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; diff --git a/html/do-start-round.pl b/html/do-start-round.pl index d843be2..3684423 100755 --- a/html/do-start-round.pl +++ b/html/do-start-round.pl @@ -52,7 +52,7 @@ if ($round == 1) { # 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); @@ -70,36 +70,52 @@ if ($round == 1) { 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!'); diff --git a/sql/ccbs.sql b/sql/ccbs.sql index 22c99bc..756f54c 100644 --- a/sql/ccbs.sql +++ b/sql/ccbs.sql @@ -68,6 +68,8 @@ CREATE TABLE songratings ( ); 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, -- 2.39.2