Adding statistics methods and also, fixing watchable/cancellable games.
This commit is contained in:
@@ -7,9 +7,7 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class GameHistoryDAO {
|
||||
private DbAccess _dbAccess;
|
||||
@@ -181,6 +179,61 @@ public class GameHistoryDAO {
|
||||
}
|
||||
}
|
||||
|
||||
public long getOldestGameHistoryEntry() {
|
||||
try {
|
||||
Connection connection = _dbAccess.getDataSource().getConnection();
|
||||
try {
|
||||
PreparedStatement statement = connection.prepareStatement("select min(end_date) from game_history where (tournament is null or tournament = 'Casual')");
|
||||
try {
|
||||
ResultSet rs = statement.executeQuery();
|
||||
try {
|
||||
if (rs.next())
|
||||
return rs.getLong(1);
|
||||
else
|
||||
return -1;
|
||||
} finally {
|
||||
rs.close();
|
||||
}
|
||||
} finally {
|
||||
statement.close();
|
||||
}
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
} catch (SQLException exp) {
|
||||
throw new RuntimeException("Unable to get count of games played", exp);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Integer> getCasualGamesPlayedPerFormat(long from, long duration) {
|
||||
try {
|
||||
Connection connection = _dbAccess.getDataSource().getConnection();
|
||||
try {
|
||||
PreparedStatement statement = connection.prepareStatement("select count(*), format_name from game_history where (tournament is null or tournament = 'Casual') and end_date>=? and end_date<? group by format_name");
|
||||
try {
|
||||
statement.setLong(1, from);
|
||||
statement.setLong(2, from + duration);
|
||||
ResultSet rs = statement.executeQuery();
|
||||
Map<String, Integer> result = new HashMap<String, Integer>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
result.put(rs.getString(2), rs.getInt(1));
|
||||
}
|
||||
} finally {
|
||||
rs.close();
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
statement.close();
|
||||
}
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
} catch (SQLException exp) {
|
||||
throw new RuntimeException("Unable to get count of games played", exp);
|
||||
}
|
||||
}
|
||||
|
||||
// Statistics
|
||||
// select deck_name, format_name, sum(win), sum(lose) from
|
||||
// (select winner_deck_name as deck_name, format_name, 1 as win, 0 as lose from game_history where winner='hsiale' union all select loser_deck_name as deck_name, format_name, 0 as win, 1 as lose from game_history where loser='hsiale') as u
|
||||
|
||||
@@ -69,4 +69,14 @@ public class GameHistoryService {
|
||||
_gamesPlayedCountCachedTimes.put(ms, minute);
|
||||
return result;
|
||||
}
|
||||
|
||||
public long getOldestGameHistoryEntry() {
|
||||
return _gameHistoryDAO.getOldestGameHistoryEntry();
|
||||
}
|
||||
|
||||
public GameHistoryStatistics getGameHistoryStatistics(long from, long duration) {
|
||||
GameHistoryStatistics stats = new GameHistoryStatistics(from, duration);
|
||||
stats.init(_gameHistoryDAO);
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.gempukku.lotro.game;
|
||||
|
||||
import com.gempukku.lotro.db.GameHistoryDAO;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GameHistoryStatistics {
|
||||
private List<FormatStat> _formatStats;
|
||||
private long _start;
|
||||
private long _duration;
|
||||
|
||||
public GameHistoryStatistics(long start, long duration) {
|
||||
_start = start;
|
||||
_duration = duration;
|
||||
}
|
||||
|
||||
public void init(GameHistoryDAO gameHistoryDao) {
|
||||
Map<String, Integer> countsPerFormat = gameHistoryDao.getCasualGamesPlayedPerFormat(_start, _duration);
|
||||
Map<String, Integer> result = new HashMap<String, Integer>();
|
||||
for (Map.Entry<String, Integer> formatCount : countsPerFormat.entrySet()) {
|
||||
String format = formatCount.getKey();
|
||||
if (!isIgnorable(format)) {
|
||||
incrementResult(result, getMainFormat(format), formatCount.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
int sum = 0;
|
||||
for (Integer integer : result.values())
|
||||
sum += integer;
|
||||
|
||||
List<FormatStat> stats = new ArrayList<FormatStat>();
|
||||
for (Map.Entry<String, Integer> formatCount : result.entrySet())
|
||||
stats.add(new FormatStat(formatCount.getKey(), formatCount.getValue(), 1f * formatCount.getValue() / sum));
|
||||
|
||||
Collections.sort(stats, new Comparator<FormatStat>() {
|
||||
@Override
|
||||
public int compare(FormatStat o1, FormatStat o2) {
|
||||
return o2.getCount() - o1.getCount();
|
||||
}
|
||||
});
|
||||
|
||||
_formatStats = stats;
|
||||
}
|
||||
|
||||
private void incrementResult(Map<String, Integer> result, String format, int value) {
|
||||
Integer previous = result.get(format);
|
||||
if (previous == null)
|
||||
previous = 0;
|
||||
result.put(format, previous + value);
|
||||
}
|
||||
|
||||
private String getMainFormat(String format) {
|
||||
if (format.equals("Community Fellowship block"))
|
||||
return "Fellowship block";
|
||||
if (format.equals("Community Two Towers block"))
|
||||
return "Towers block";
|
||||
if (format.equals("Community War of the Ring block"))
|
||||
return "War of the Ring block";
|
||||
if (format.equals("Two Towers block"))
|
||||
return "Towers block";
|
||||
if (format.equals("Towers Standard"))
|
||||
return "Towers standard";
|
||||
return format;
|
||||
}
|
||||
|
||||
private boolean isIgnorable(String format) {
|
||||
if (format.startsWith("Fellowship block - "))
|
||||
return true;
|
||||
if (format.equals("Format for testing"))
|
||||
return true;
|
||||
if (format.equals("Sealed FotR League (Dec 2011)"))
|
||||
return true;
|
||||
if (format.startsWith("Test league"))
|
||||
return true;
|
||||
if (format.startsWith("Towers block - "))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<FormatStat> getFormatStats() {
|
||||
return Collections.unmodifiableList(_formatStats);
|
||||
}
|
||||
|
||||
public long getStart() {
|
||||
return _start;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return _duration;
|
||||
}
|
||||
|
||||
public static class FormatStat {
|
||||
private String _format;
|
||||
private int _count;
|
||||
private float _percentage;
|
||||
|
||||
public FormatStat(String format, int count, float percentage) {
|
||||
_format = format;
|
||||
_count = count;
|
||||
_percentage = percentage;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return _format;
|
||||
}
|
||||
|
||||
public float getPercentage() {
|
||||
return _percentage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.gempukku.lotro.game;
|
||||
|
||||
import com.gempukku.lotro.db.DbAccess;
|
||||
import com.gempukku.lotro.db.GameHistoryDAO;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class GetStatsConsole {
|
||||
private static final SimpleDateFormat monthFormat = new SimpleDateFormat("MMM yyyy");
|
||||
private static final DecimalFormat percFormat = new DecimalFormat("#0.0%");
|
||||
|
||||
public static void main(String[] args) {
|
||||
DbAccess dbAccess = new DbAccess();
|
||||
GameHistoryDAO gameHistoryDAO = new GameHistoryDAO(dbAccess);
|
||||
GameHistoryService gameHistoryService = new GameHistoryService(gameHistoryDAO);
|
||||
long startTime = gameHistoryService.getOldestGameHistoryEntry();
|
||||
|
||||
createMonthlyStats(startTime, gameHistoryService);
|
||||
// createWeeklyStats(startTime, gameHistoryService);
|
||||
}
|
||||
|
||||
private static void createMonthlyStats(long startTime, GameHistoryService gameHistoryService) {
|
||||
Date startOfMonth = new Date(startTime);
|
||||
startOfMonth.setDate(1);
|
||||
startOfMonth.setHours(0);
|
||||
startOfMonth.setMinutes(0);
|
||||
startOfMonth.setSeconds(0);
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
System.out.println("Monthly statistics:");
|
||||
startOfMonth.setTime(startOfMonth.getTime() / 1000L * 1000L);
|
||||
long periodStart = startOfMonth.getTime();
|
||||
while (periodStart < currentTime) {
|
||||
startOfMonth.setMonth(startOfMonth.getMonth() + 1);
|
||||
long periodEnd = startOfMonth.getTime();
|
||||
|
||||
System.out.println(monthFormat.format(new Date(periodStart)) + ":");
|
||||
GameHistoryStatistics historyStatistics = gameHistoryService.getGameHistoryStatistics(periodStart, periodEnd - periodStart);
|
||||
List<GameHistoryStatistics.FormatStat> stats = historyStatistics.getFormatStats();
|
||||
for (GameHistoryStatistics.FormatStat stat : stats) {
|
||||
System.out.println(stat.getFormat() + ": " + stat.getCount() + " (" + percFormat.format(stat.getPercentage()) + ")");
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
periodStart = periodEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,13 +122,13 @@ public class LotroServer extends AbstractServer {
|
||||
return "Game" + gameId;
|
||||
}
|
||||
|
||||
public synchronized String createNewGame(LotroFormat lotroFormat, String tournament, final LotroGameParticipant[] participants, boolean competetive) {
|
||||
public synchronized String createNewGame(LotroFormat lotroFormat, String tournamentName, final LotroGameParticipant[] participants, boolean competetive, boolean tournament) {
|
||||
if (participants.length < 2)
|
||||
throw new IllegalArgumentException("There has to be at least two players");
|
||||
final String gameId = String.valueOf(_nextGameId);
|
||||
|
||||
boolean noSpectators = competetive;
|
||||
boolean cancellable = !competetive;
|
||||
boolean noSpectators = tournament;
|
||||
boolean cancellable = !tournament;
|
||||
|
||||
if (noSpectators) {
|
||||
Set<String> allowedUsers = new HashSet<String>();
|
||||
@@ -169,7 +169,7 @@ public class LotroServer extends AbstractServer {
|
||||
|
||||
lotroGameMediator.sendMessageToPlayers("Players in the game are: " + players.toString());
|
||||
|
||||
final GameRecorder.GameRecordingInProgress gameRecordingInProgress = _gameRecorder.recordGame(lotroGameMediator, lotroFormat.getName(), tournament, deckNames);
|
||||
final GameRecorder.GameRecordingInProgress gameRecordingInProgress = _gameRecorder.recordGame(lotroGameMediator, lotroFormat.getName(), tournamentName, deckNames);
|
||||
lotroGameMediator.addGameResultListener(
|
||||
new GameResultListener() {
|
||||
@Override
|
||||
|
||||
@@ -390,12 +390,12 @@ public class HallServer extends AbstractServer {
|
||||
};
|
||||
}
|
||||
|
||||
createGame(tableId, participants, listener, awaitingTable.getLotroFormat(), getTournamentName(awaitingTable), league != null);
|
||||
createGame(tableId, participants, listener, awaitingTable.getLotroFormat(), getTournamentName(awaitingTable), league != null, false);
|
||||
_awaitingTables.remove(tableId);
|
||||
}
|
||||
|
||||
private void createGame(String tableId, LotroGameParticipant[] participants, GameResultListener listener, LotroFormat lotroFormat, String tournamentName, boolean competetive) {
|
||||
String gameId = _lotroServer.createNewGame(lotroFormat, tournamentName, participants, competetive);
|
||||
private void createGame(String tableId, LotroGameParticipant[] participants, GameResultListener listener, LotroFormat lotroFormat, String tournamentName, boolean competetive, boolean tournament) {
|
||||
String gameId = _lotroServer.createNewGame(lotroFormat, tournamentName, participants, competetive, tournament);
|
||||
LotroGameMediator lotroGameMediator = _lotroServer.getGameById(gameId);
|
||||
if (listener != null)
|
||||
lotroGameMediator.addGameResultListener(listener);
|
||||
@@ -533,7 +533,7 @@ public class HallServer extends AbstractServer {
|
||||
public void gameCancelled() {
|
||||
createGameInternal(participants);
|
||||
}
|
||||
}, _formatLibrary.getFormat(_tournament.getFormat()), _tournament.getTournamentName(), true);
|
||||
}, _formatLibrary.getFormat(_tournament.getFormat()), _tournament.getTournamentName(), true, true);
|
||||
} finally {
|
||||
_hallDataAccessLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user