From 0fde1543a88aeaac4d83b745f3c6112d8dd06fd9 Mon Sep 17 00:00:00 2001 From: "marcins78@gmail.com" Date: Wed, 4 Jul 2012 22:39:49 +0000 Subject: [PATCH] Adding statistics methods and also, fixing watchable/cancellable games. --- .../com/gempukku/lotro/db/GameHistoryDAO.java | 59 ++++++++- .../lotro/game/GameHistoryService.java | 10 ++ .../lotro/game/GameHistoryStatistics.java | 115 ++++++++++++++++++ .../gempukku/lotro/game/GetStatsConsole.java | 52 ++++++++ .../com/gempukku/lotro/game/LotroServer.java | 8 +- .../com/gempukku/lotro/hall/HallServer.java | 8 +- 6 files changed, 241 insertions(+), 11 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryStatistics.java create mode 100644 gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GetStatsConsole.java diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java index 9283fe8b3..baa96943c 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java @@ -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 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 result = new HashMap(); + 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 diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java index c5223c456..b63513566 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java @@ -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; + } } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryStatistics.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryStatistics.java new file mode 100644 index 000000000..b99b2a2ee --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryStatistics.java @@ -0,0 +1,115 @@ +package com.gempukku.lotro.game; + +import com.gempukku.lotro.db.GameHistoryDAO; + +import java.util.*; + +public class GameHistoryStatistics { + private List _formatStats; + private long _start; + private long _duration; + + public GameHistoryStatistics(long start, long duration) { + _start = start; + _duration = duration; + } + + public void init(GameHistoryDAO gameHistoryDao) { + Map countsPerFormat = gameHistoryDao.getCasualGamesPlayedPerFormat(_start, _duration); + Map result = new HashMap(); + for (Map.Entry 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 stats = new ArrayList(); + for (Map.Entry formatCount : result.entrySet()) + stats.add(new FormatStat(formatCount.getKey(), formatCount.getValue(), 1f * formatCount.getValue() / sum)); + + Collections.sort(stats, new Comparator() { + @Override + public int compare(FormatStat o1, FormatStat o2) { + return o2.getCount() - o1.getCount(); + } + }); + + _formatStats = stats; + } + + private void incrementResult(Map 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 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; + } + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GetStatsConsole.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GetStatsConsole.java new file mode 100644 index 000000000..e69158886 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GetStatsConsole.java @@ -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 stats = historyStatistics.getFormatStats(); + for (GameHistoryStatistics.FormatStat stat : stats) { + System.out.println(stat.getFormat() + ": " + stat.getCount() + " (" + percFormat.format(stat.getPercentage()) + ")"); + } + System.out.println(); + + periodStart = periodEnd; + } + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java index 9b0f534ee..e51a0d136 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java @@ -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 allowedUsers = new HashSet(); @@ -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 diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java index 2c08726ea..a232a6da6 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java @@ -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(); }