SoccerMatchAnalysis.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. package objects;
  2. import data.GuiMysql;
  3. import java.io.Serializable;
  4. import java.math.BigDecimal;
  5. import java.math.RoundingMode;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.SQLException;
  9. import java.text.DecimalFormat;
  10. import java.time.LocalDate;
  11. import java.time.format.DateTimeFormatter;
  12. import java.util.List;
  13. import java.util.Optional;
  14. public class SoccerMatchAnalysis extends SoccerMatch implements Serializable {
  15. GuiMysql database;
  16. private List<TeamStanding> leagueTable;
  17. private LocalDate leagueTableUpdated;
  18. private int scoringDiffValue;
  19. private int scoringTotal;
  20. private int winCount;
  21. private int winLossRatio;
  22. private String percentages;
  23. Percentages calculatedPercentages;
  24. private int scoringTotalValue;
  25. public SoccerMatchAnalysis(SoccerMatch match) {
  26. setMatchData(match);
  27. database = GuiMysql.getInstance();
  28. }
  29. public int getWinLossRatio() {
  30. return winLossRatio;
  31. }
  32. public String getPercentages() {
  33. return percentages;
  34. }
  35. public void setPercentages(String value) {
  36. percentages = value;
  37. }
  38. public void setWinLossRatio(int winLossRatio) {
  39. this.winLossRatio = winLossRatio;
  40. }
  41. public int getWinCount() {
  42. return winCount;
  43. }
  44. public void setWinCount(int winCount) {
  45. this.winCount = winCount;
  46. }
  47. public int getScoringTotal() {
  48. return scoringTotal;
  49. }
  50. public void setScoringTotal(int scoringTotal) {
  51. this.scoringTotal = scoringTotal;
  52. }
  53. public int getScoringDiffValue() {
  54. return scoringDiffValue;
  55. }
  56. public void setScoringDiffValue(int scoringDiffValue) {
  57. this.scoringDiffValue = scoringDiffValue;
  58. }
  59. /**
  60. * Antalet mål som hemma laget gjort de senaste "gamesLookback" matcherna -
  61. * antalet mål för bortalaget under samma period
  62. *
  63. * @param gamesLookback - hur många matcher bakåt i tiden som ska kontrolleras
  64. * @return Float med skillnaden i mål mellan lagen hemma/borta
  65. */
  66. public int getScoringDiffLastGames(int gamesLookback) {
  67. int result = 0;
  68. String sql = "SELECT * FROM " +
  69. "(SELECT * FROM SoccerResults WHERE homeTeamId = ? AND leagueId = ? AND DATE" +
  70. "(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) ht " +
  71. "UNION " +
  72. "(SELECT * FROM SoccerResults WHERE " +
  73. "awayTeamId = ? AND leagueId = ? AND DATE(gameDate) < ? " +
  74. "ORDER BY gameDate DESC " +
  75. "LIMIT ?);";
  76. int homeRes = 0;
  77. int awayRes = 0;
  78. try (PreparedStatement stat = database.getDbConnection().prepareStatement(sql)) {
  79. stat.setInt(1, getHomeTeam().getTeamId());
  80. stat.setInt(2, getHomeTeam().getTeamLeagueId());
  81. stat.setString(3, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  82. stat.setInt(4, gamesLookback);
  83. stat.setInt(5, getAwayTeam().getTeamId());
  84. stat.setInt(6, getAwayTeam().getTeamLeagueId());
  85. stat.setString(7, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  86. stat.setInt(8, gamesLookback);
  87. ResultSet rs = stat.executeQuery();
  88. while (rs.next()) {
  89. if (getHomeTeam().getTeamId() == rs.getInt("homeTeamId")) {
  90. homeRes += rs.getInt("homeScore");
  91. }
  92. if (getAwayTeam().getTeamId() == rs.getInt("awayTeamId")) {
  93. awayRes += rs.getInt("awayScore");
  94. }
  95. }
  96. } catch (SQLException e) {
  97. e.printStackTrace();
  98. }
  99. scoringDiffValue = homeRes - awayRes;
  100. return scoringDiffValue;
  101. }
  102. /**
  103. * Plocka fram antalet mål som ett specifikt lag gjort under de senaste
  104. * gamesLookback matcherna
  105. *
  106. * @param gamesLookback - hur många matcher bakåt i tiden som ska kontrolleras
  107. * @param homeTeam - är det hemma laget som ska kontrolleras i matchen
  108. * @return antalet mål som är gjorda av bestämt lag.
  109. */
  110. public int scoringTotal(int gamesLookback, boolean homeTeam) {
  111. int result = 0;
  112. /*
  113. * String sql = "SELECT * FROM " +
  114. * "(SELECT * FROM SoccerResults WHERE homeTeamId = ? AND leagueId = ? AND DATE"
  115. * +
  116. * "(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) ht " + "UNION DISTINCT " +
  117. * "(SELECT * FROM " +
  118. * "SoccerResults WHERE awayTeamId = ? AND leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC "
  119. * +
  120. * "LIMIT ?)";
  121. */
  122. String sql = "SELECT * FROM ( " +
  123. "SELECT * FROM SoccerResults " +
  124. "WHERE (homeTeamId = ? OR awayTeamId = ?) AND leagueId = ? AND gameDate < ? " +
  125. ") AS CombinedResults " +
  126. "ORDER BY gameDate DESC " +
  127. "LIMIT ?";
  128. try (PreparedStatement stat = database.getDbConnection().prepareStatement(sql)) {
  129. final Team team;
  130. if (homeTeam) {
  131. team = getHomeTeam();
  132. } else {
  133. team = getAwayTeam();
  134. }
  135. stat.setInt(1, team.getTeamId());
  136. stat.setInt(2, team.getTeamId());
  137. stat.setInt(3, team.getTeamLeagueId());
  138. stat.setString(4, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  139. stat.setInt(5, gamesLookback);
  140. /*
  141. * stat.setInt(5, team.getTeamId());
  142. * stat.setInt(6, team.getTeamLeagueId());
  143. * stat.setString(7, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  144. * stat.setInt(8, gamesLookback);
  145. */
  146. ResultSet rs = stat.executeQuery();
  147. while (rs.next()) {
  148. if (rs.getInt("homeTeamId") == team.getTeamId()) {
  149. result += rs.getInt("homeScore");
  150. } else if (rs.getInt("awayTeamId") == team.getTeamId()) {
  151. result += rs.getInt("awayScore");
  152. }
  153. }
  154. } catch (SQLException e) {
  155. e.printStackTrace();
  156. }
  157. return result;
  158. }
  159. /**
  160. * Hämta tabell positionen för hemma eller borta laget
  161. *
  162. * @param homeTeam - är det hemma laget som ska kontrolleras för matchen?
  163. * @return position för specifierat lag
  164. */
  165. public int getTablePosition(boolean homeTeam) {
  166. int result = 0;
  167. updateLeagueTable();
  168. Optional<TeamStanding> standingOptional = leagueTable.stream().filter(
  169. p -> p.getTeamName().equals(homeTeam ? getHomeTeam().getTeamName() : getAwayTeam().getTeamName()))
  170. .findFirst();
  171. if (standingOptional.isPresent()) {
  172. TeamStanding standing = standingOptional.get();
  173. result = leagueTable.indexOf(standing);
  174. }
  175. return result;
  176. }
  177. private void updateLeagueTable() {
  178. if (!leagueTableUpdated.isEqual(getGameDate().toLocalDate())) {
  179. leagueTable = database.getLeagueTable(getHomeTeam().getTeamLeagueId(), getSeason(),
  180. getHomeTeam().getCountryId(), getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  181. leagueTableUpdated = getGameDate().toLocalDate();
  182. }
  183. }
  184. /**
  185. * @return Integer - hur många platser det är mellan hemma och borta laget
  186. */
  187. public int diffInStanding() {
  188. int result = 0;
  189. updateLeagueTable();
  190. Optional<TeamStanding> homeTeamStandingOptional = leagueTable.stream()
  191. .filter(p -> p.getTeamName().equals(getHomeTeam().getTeamName())).findFirst();
  192. Optional<TeamStanding> awayTeamStandingOptional = leagueTable.stream()
  193. .filter(p -> p.getTeamName().equals(getAwayTeam().getTeamName())).findFirst();
  194. if (homeTeamStandingOptional.isPresent() && awayTeamStandingOptional.isPresent()) {
  195. TeamStanding homeStanding = homeTeamStandingOptional.get();
  196. TeamStanding awayStanding = awayTeamStandingOptional.get();
  197. result = leagueTable.indexOf(homeStanding) - leagueTable.indexOf(awayStanding);
  198. }
  199. return result;
  200. }
  201. /**
  202. * Vinst förlust ratio för om man är enbart hemma eller bortalag.
  203. *
  204. * @param gamesLookback
  205. * @param homeTeam
  206. * @return Integer där vinst ger +1 lika ger 0 och förlust get -1
  207. */
  208. public int winLossRatio(int gamesLookback, boolean homeTeam) {
  209. int result = 0;
  210. Team team = homeTeam ? getHomeTeam() : getAwayTeam();
  211. String teamSql = homeTeam ? "homeTeamId = ? " : "awayTeamId = ? ";
  212. String sql = "SELECT * FROM SoccerResults WHERE " + teamSql + "AND leagueId = ? AND DATE(gameDate) < ? ORDER " +
  213. "BY gameDate DESC LIMIT ?";
  214. try (PreparedStatement stat = database.getDbConnection().prepareStatement(sql)) {
  215. stat.setInt(1, team.getTeamId());
  216. stat.setInt(2, team.getTeamLeagueId());
  217. stat.setString(3, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  218. stat.setInt(4, gamesLookback);
  219. ResultSet rs = stat.executeQuery();
  220. while (rs.next()) {
  221. int homeScore = rs.getInt("homeScore");
  222. int awayScore = rs.getInt("awayScore");
  223. if (homeTeam) {
  224. if (homeScore > awayScore) {
  225. result++;
  226. } else if (homeScore < awayScore) {
  227. result--;
  228. }
  229. } else {
  230. if (homeScore > awayScore) {
  231. result--;
  232. } else if (homeScore < awayScore) {
  233. result++;
  234. }
  235. }
  236. }
  237. } catch (SQLException e) {
  238. e.printStackTrace();
  239. }
  240. return result;
  241. }
  242. public int winLossRatioHomeAndAway(int gamesLookback, boolean homeTeam) {
  243. int result = 0;
  244. String sql = "SELECT * FROM SoccerResults " +
  245. "WHERE (homeTeamId = ? OR awayTeamId = ?) " +
  246. "AND leagueId = ? " +
  247. "AND DATE(gameDate) < ? " +
  248. "ORDER BY gameDate DESC " +
  249. "LIMIT ?";
  250. /*
  251. * String sql = "SELECT * FROM " +
  252. * "(SELECT * FROM SoccerResults WHERE homeTeamId = ? AND leagueId = ? AND DATE"
  253. * +
  254. * "(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) a " + "UNION DISTINCT " +
  255. * "(SELECT * FROM " +
  256. * "SoccerResults WHERE awayTeamId = ? AND leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC "
  257. * +
  258. * "LIMIT ?) " + "ORDER BY gameDate DESC " + "LIMIT ?";
  259. */
  260. Team team = homeTeam ? getHomeTeam() : getAwayTeam();
  261. try (PreparedStatement stat = database.getDbConnection().prepareStatement(sql)) {
  262. stat.setInt(1, team.getTeamId());
  263. stat.setInt(2, team.getTeamId());
  264. stat.setInt(3, team.getTeamLeagueId());
  265. stat.setString(4, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  266. stat.setInt(5, gamesLookback);
  267. /*
  268. * stat.setInt(1, team.getTeamId());
  269. * stat.setInt(2, team.getTeamLeagueId());
  270. * stat.setString(3, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  271. * stat.setInt(4, gamesLookback);
  272. *
  273. * stat.setInt(5, team.getTeamId());
  274. * stat.setInt(6, team.getTeamLeagueId());
  275. * stat.setString(7, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  276. * stat.setInt(8, gamesLookback);
  277. *
  278. * stat.setInt(9, gamesLookback);
  279. */
  280. ResultSet rs = stat.executeQuery();
  281. while (rs.next()) {
  282. if (rs.getInt("homeTeamId") == team.getTeamId() && rs.getInt("homeScore") > rs.getInt("awayScore")) {
  283. result++;
  284. } else if (rs.getInt("awayTeamId") == team.getTeamId() && rs.getInt("awayScore") > rs.getInt(
  285. "homeScore")) {
  286. result++;
  287. } else {
  288. result--;
  289. }
  290. }
  291. } catch (SQLException e) {
  292. e.printStackTrace();
  293. }
  294. return result;
  295. }
  296. public float goalsScoredHomeAndAway(boolean homeTeam, int gameLookback) {
  297. int result = 0;
  298. Team team = homeTeam ? getHomeTeam() : getAwayTeam();
  299. String sql = "SELECT * FROM SoccerResults " +
  300. "WHERE (" + (homeTeam ? "home" : "away") + "TeamId = ?) " +
  301. " AND leagueId = ? " +
  302. " AND DATE(gameDate) < ? " +
  303. "ORDER BY gameDate DESC " +
  304. "LIMIT ?";
  305. /*
  306. * String sql = "SELECT * FROM " +
  307. * "(SELECT * FROM SoccerResults WHERE homeTeamId = ? AND leagueId = ? AND DATE"
  308. * +
  309. * "(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) a " + "UNION ALL " +
  310. * "(SELECT * FROM SoccerResults " +
  311. * "WHERE awayTeamId = ? AND leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) "
  312. * +
  313. * "ORDER BY gameDate DESC " + "LIMIT ?";
  314. */
  315. try (PreparedStatement stat = database.getDbConnection().prepareStatement(sql)) {
  316. stat.setInt(1, team.getTeamId());
  317. stat.setInt(2, team.getTeamLeagueId());
  318. stat.setString(3, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  319. stat.setInt(4, gameLookback);
  320. /*
  321. * stat.setInt(1, team.getTeamId());
  322. * stat.setInt(2, team.getTeamLeagueId());
  323. * stat.setString(3, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  324. * stat.setInt(4, gameLookback);
  325. * stat.setInt(5, team.getTeamId());
  326. * stat.setInt(6, team.getTeamLeagueId());
  327. * stat.setString(7, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  328. * stat.setInt(8, gameLookback);
  329. * stat.setInt(9, gameLookback);
  330. */
  331. ResultSet rs = stat.executeQuery();
  332. while (rs.next()) {
  333. if (rs.getInt("homeTeamId") == team.getTeamId()) {
  334. result += rs.getInt("homeScore");
  335. }
  336. if (rs.getInt("awayTeamId") == team.getTeamId()) {
  337. result += rs.getInt("awayScore");
  338. }
  339. }
  340. } catch (SQLException e) {
  341. e.printStackTrace();
  342. }
  343. // TODO Think Should the result be divided by lookback??
  344. // NEW TEST, devide by lookback (OR SIZE IF LESS THAN LOOKBACK?
  345. BigDecimal res = BigDecimal.valueOf((result / (float) gameLookback) * 2);
  346. res = res.setScale(1, RoundingMode.HALF_UP);
  347. DecimalFormat df = new DecimalFormat("#.00");
  348. return Float.valueOf(df.format(res.floatValue() / 2.0f).replaceAll(",", "."));
  349. }
  350. public int goalsScoredHomeOrAway(boolean homeTeam, int gameLookback) {
  351. int result = 0;
  352. Team team = homeTeam ? getHomeTeam() : getAwayTeam();
  353. String homeOrAway = homeTeam ? "home" : "away";
  354. String sql = "SELECT SUM(" + homeOrAway + "Score) FROM SoccerResults WHERE " + homeOrAway + "TeamId = ? AND " +
  355. "leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ? " + "ORDER BY gameDate DESC";
  356. try (PreparedStatement stat = database.getDbConnection().prepareStatement(sql)) {
  357. stat.setInt(1, team.getTeamId());
  358. stat.setInt(2, team.getTeamLeagueId());
  359. stat.setString(3, getGameDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
  360. stat.setInt(4, gameLookback);
  361. ResultSet rs = stat.executeQuery();
  362. while (rs.next()) {
  363. result += rs.getInt(homeOrAway + "Score");
  364. }
  365. } catch (SQLException e) {
  366. e.printStackTrace();
  367. }
  368. return result;
  369. }
  370. public int getScoringTotalValue() {
  371. return scoringTotalValue;
  372. }
  373. public void setScoringTotalValue(int value) {
  374. scoringTotalValue = value;
  375. }
  376. public Percentages calculateWinPercentages() {
  377. calculatedPercentages = new Percentages();
  378. League leagueInfo = database.getLeagueInfo(this.getHomeTeam().getTeamLeagueId());
  379. int homeScore = this.scoringTotal(leagueInfo.getScoringTotal(), true);
  380. int awayScore = this.scoringTotal(leagueInfo.getScoringTotal(), false);
  381. database.getTotalGoalStat(calculatedPercentages, leagueInfo.getLeagueId(), leagueInfo.getScoringTotal(),
  382. homeScore - awayScore);
  383. database.getScoringDiffLastGames(calculatedPercentages, leagueInfo.getLeagueId(),
  384. leagueInfo.getScoringDiffLastGame(),
  385. this.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame()));
  386. int winLossHAHome = this.winLossRatioHomeAndAway(leagueInfo.getWinLossRatioHomeAndAway(), true);
  387. int winLossHAAway = this.winLossRatioHomeAndAway(leagueInfo.getWinLossRatioHomeAndAway(), false);
  388. database.getWinLossRatioHomeAndAwayStatistics(calculatedPercentages, leagueInfo.getLeagueId(),
  389. leagueInfo.getWinLossRatioHomeAndAway(),
  390. winLossHAHome - winLossHAAway);
  391. int winLossHome = this.winLossRatio(leagueInfo.getWinLossRatio(), true);
  392. int winLossAway = this.winLossRatio(leagueInfo.getWinLossRatio(), false);
  393. this.winLossRatio(leagueInfo.getWinLossRatio(), false);
  394. database.getWinLossRatioStatisticsGames(calculatedPercentages, leagueInfo.getLeagueId(),
  395. leagueInfo.getWinLossRatio(), winLossHome - winLossAway);
  396. calculatedPercentages.calculatePercentages();
  397. return calculatedPercentages;
  398. }
  399. public Percentages getCalculatedPercentages() {
  400. if (calculatedPercentages == null) {
  401. calculatedPercentages = calculateWinPercentages();
  402. }
  403. return calculatedPercentages;
  404. }
  405. public void setCalculatedPercentages(Percentages calculatedPercentages) {
  406. this.calculatedPercentages = calculatedPercentages;
  407. }
  408. }