Skip to content

Commit

Permalink
Improve /advent leaderboard
Browse files Browse the repository at this point in the history
  • Loading branch information
mangstadt committed Dec 15, 2018
1 parent 45476e6 commit c225812
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 26 deletions.
94 changes: 85 additions & 9 deletions src/main/java/oakbot/command/AdventOfCodeCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import static oakbot.command.Command.reply;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -97,14 +99,39 @@ public ChatResponse onMessage(ChatCommand chatCommand, BotContext context) {
return b.getStars() - a.getStars();
});

//build names
List<String> names = new ArrayList<>(players.size());
int lengthOfLongestName = 0;
for (Player player : players) {
String name = (player.getName() == null) ? "(user #" + player.getId() + ")" : player.getName();
if (name.length() > lengthOfLongestName) {
lengthOfLongestName = name.length();
}
names.add(name);
}

//find number of digits in highest score
int digitsInHighestScore = 0;
{
int highestScore = -1;
for (Player player : players) {
if (player.getScore() > highestScore) {
highestScore = player.getScore();
}
}
digitsInHighestScore = numberOfDigits(highestScore);
}

//output leaderboard
ChatBuilder cb = new ChatBuilder();
String htmlUrl = api.getLeaderboardWebsite(leaderboardId);
cb.append("Leaderboard owned by ").append(owner.getName()).append(" (").append(htmlUrl).append(")").nl();
cb.fixed().append("Leaderboard owned by ").append(owner.getName()).append(" (").append(htmlUrl).append(")").nl();

int rank = 0;
int prevScore = -1, prevStars = -1;
for (Player player : players) {
for (int i = 0; i < players.size(); i++) {
Player player = players.get(i);

/*
* Do not increase the rank number if two players have the same
* score & stars.
Expand All @@ -113,13 +140,49 @@ public ChatResponse onMessage(ChatCommand chatCommand, BotContext context) {
rank++;
}

//@formatter:off
cb.append(rank).append(". ")
.append((player.getName() == null) ? "anonymous user #" + player.getId() : player.getName())
.append(" - ").append(player.getScore())
.append(" (").append(player.getStars()).append(" stars)")
.nl();
//@formatter:on
cb.fixed();

//output rank
cb.append(rank).append(". ");
if (rank < 10) {
cb.append(' ');
}

//output name
String playerName = names.get(i);
cb.append(playerName).append(' ', lengthOfLongestName - playerName.length());

//output score
cb.append(" (score: ");
cb.append(' ', digitsInHighestScore - numberOfDigits(player.getScore()));
cb.append(player.getScore()).append(") ");

//output stars
Map<Integer, Instant[]> days = player.getCompletionTimes();
for (int day = 1; day <= 25; day++) {
Instant[] parts = days.get(day);
if (parts == null) {
//did not finish anything
cb.append('.');
} else if (parts[1] == null) {
//only finished part 1
cb.append('^');
} else {
//finished part 1 and 2
cb.append('*');
}

if (day != 25 && day % 5 == 0) {
cb.append('|');
}
}

//output star count
cb.append(' ');
if (player.getStars() < 10) {
cb.append(' ');
}
cb.append(player.getStars()).append(" stars").nl();

prevScore = player.getScore();
prevStars = player.getStars();
Expand All @@ -135,6 +198,19 @@ public ChatResponse onMessage(ChatCommand chatCommand, BotContext context) {
return new ChatResponse(cb, SplitStrategy.NONE, true, condensed);
}

private static int numberOfDigits(int number) {
if (number == 0) {
return 1;
}

int digits = 0;
while (number > 0) {
number = number / 10;
digits++;
}
return digits;
}

/**
* Determines whether this command is currently active. This method is
* package private so this class can be unit tested.
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/oakbot/util/ChatBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ public ChatBuilder append(char c) {
return this;
}

/**
* Appends a raw character multiple times.
* @param c the character to append
* @param repeat the number of times to repeat the character
* @return this
*/
public ChatBuilder append(char c, int repeat) {
for (int i = 0; i < repeat; i++) {
append(c);
}
return this;
}

/**
* Appends a number.
* @param i the number to append
Expand Down
34 changes: 17 additions & 17 deletions src/test/java/oakbot/command/AdventOfCodeCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,23 +124,23 @@ private static void assertLeaderboardResponse(String expectedId, ChatResponse ac

//@formatter:off
String expected =
"Leaderboard owned by Unihedron (http://adventofcode.com/" + year + "/leaderboard/private/view/" + expectedId + ")\n" +
"1. gzgreg - 312 (20 stars)\n" +
"2. Unihedron - 306 (20 stars)\n" +
"3. geisterfurz007 - 230 (20 stars)\n" +
"3. Lazy Zefiris - 230 (20 stars)\n" +
"4. Rishav - 227 (18 stars)\n" +
"5. asterisk man - 205 (20 stars)\n" +
"6. ByteCommander - 201 (18 stars)\n" +
"7. Mike Angstadt - 124 (20 stars)\n" +
"8. ProgramFOX - 104 (13 stars)\n" +
"9. ArcticEcho - 102 (12 stars)\n" +
"10. dSolver - 90 (12 stars)\n" +
"11. Shady_maniac - 90 (8 stars)\n" +
"12. anonymous user #238463 - 38 (6 stars)\n" +
"13. Michael Prieto - 31 (5 stars)\n" +
"14. Simon - 26 (5 stars)\n" +
"15. Jacob Gray - 0 (0 stars)\n";
" Leaderboard owned by Unihedron (http://adventofcode.com/" + year + "/leaderboard/private/view/" + expectedId + ")\n" +
" 1. gzgreg (score: 312) *****|*****|.....|.....|..... 20 stars\n" +
" 2. Unihedron (score: 306) *****|*****|.....|.....|..... 20 stars\n" +
" 3. geisterfurz007 (score: 230) *****|*****|.....|.....|..... 20 stars\n" +
" 3. Lazy Zefiris (score: 230) *****|*****|.....|.....|..... 20 stars\n" +
" 4. Rishav (score: 227) *****|****.|.....|.....|..... 18 stars\n" +
" 5. asterisk man (score: 205) *****|*****|.....|.....|..... 20 stars\n" +
" 6. ByteCommander (score: 201) *****|****.|.....|.....|..... 18 stars\n" +
" 7. Mike Angstadt (score: 124) *****|*****|.....|.....|..... 20 stars\n" +
" 8. ProgramFOX (score: 104) *****|*^...|.....|.....|..... 13 stars\n" +
" 9. ArcticEcho (score: 102) *****|*....|.....|.....|..... 12 stars\n" +
" 10. dSolver (score: 90) *****|*....|.....|.....|..... 12 stars\n" +
" 11. Shady_maniac (score: 90) **.**|.....|.....|.....|..... 8 stars\n" +
" 12. (user #238463) (score: 38) ***..|.....|.....|.....|..... 6 stars\n" +
" 13. Michael Prieto (score: 31) **^..|.....|.....|.....|..... 5 stars\n" +
" 14. Simon (score: 26) **.^.|.....|.....|.....|..... 5 stars\n" +
" 15. Jacob Gray (score: 0) .....|.....|.....|.....|..... 0 stars\n";
//@formatter:on

assertEquals(expected, actual.getMessage());
Expand Down

0 comments on commit c225812

Please sign in to comment.