Adding statistics methods and also, fixing watchable/cancellable games.

This commit is contained in:
marcins78@gmail.com
2012-07-04 22:39:49 +00:00
parent c8202dfd13
commit 0fde1543a8
6 changed files with 241 additions and 11 deletions

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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();
}