Skip to content

Commit

Permalink
Fix #139 : Use "auctions" (turn 1) for Mercatos proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
axel3rd committed Jan 9, 2022
1 parent e2a7eb7 commit 9d035be
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Automate and optimize your [MPG](http://mpg.football/) weekly league actions, us
* Displaying your teams, line by line, ordered by players efficiency (with injured players)
* Updating your team
* Proposing some players to buy, better than the one you have (if option `transactions.proposal` is enabled and *MPG* expert mode is bought)
* When league not started (aka: *mercato*), the best players to buy for your incoming team
* When league not started (aka: *mercato*), the best players to buy with good turn 1 auction (since v1.9) for your incoming team

**NB:** Your tactical organization and selected bonus are not updated and let as configured (but selected if some will be lost or no captain).

Expand Down
18 changes: 10 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.blondin</groupId>
<artifactId>mpg-coach-bot</artifactId>
<packaging>jar</packaging>
<version>1.8.4-SNAPSHOT</version>
<version>1.9-SNAPSHOT</version>
<name>MPG Coach Bot</name>
<properties>
<goals>package</goals>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<main.class>org.blondin.mpg.Main</main.class>
<jdk.version>1.8</jdk.version>
<jersey.version>2.34</jersey.version>
<jackson.version>2.12.4</jackson.version>
<jersey.version>2.35</jersey.version>
<jackson.version>2.13.1</jackson.version>
<slf4j.version>1.7.32</slf4j.version>
<log4j.version>2.17.1</log4j.version>
</properties>
Expand All @@ -32,7 +34,7 @@
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<version>3.2.1</version>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
Expand All @@ -48,7 +50,7 @@
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.0-M4</version>
<version>3.0.0-M5</version>
</plugin>
</plugins>
</pluginManagement>
Expand Down Expand Up @@ -171,7 +173,7 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.2</version>
<version>1.14.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down Expand Up @@ -202,7 +204,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.11.2</version>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
67 changes: 41 additions & 26 deletions src/main/java/org/blondin/mpg/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,17 @@ static void processMercatoLeague(League league, ApiClients apiClients, Config co
LOG.info("\nProposal for your mercato:\n");
List<Player> players = apiClients.getMpg().getAvailablePlayers(league.getDivisionId()).getList();
completePlayersClub(players, apiClients.getMpg().getClubs());
calculateEfficiency(players, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config, false, true);
completeAuctionAndcalculateEfficiency(players, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config,
false, true);
processMercato(players, apiClients.getOutPlayers(), ChampionshipTypeWrapper.toOut(league.getChampionship()));
}

static void processMercatoChampionship(League league, ApiClients apiClients, Config config) {
LOG.info("\nProposal for your coming soon mercato:\n");
List<Player> players = apiClients.getMpg().getPoolPlayers(league.getChampionship()).getPlayers();
completePlayersClub(players, apiClients.getMpg().getClubs());
calculateEfficiency(players, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config, false, true);
completeAuctionAndcalculateEfficiency(players, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config,
false, true);
processMercato(players, apiClients.getOutPlayers(), ChampionshipTypeWrapper.toOut(league.getChampionship()));
}

Expand All @@ -144,7 +146,7 @@ static void processMercato(List<Player> players, InjuredSuspendedWrapperClient o
List<Player> midfielders = players.stream().filter(p -> p.getPosition().equals(Position.M)).collect(Collectors.toList()).subList(0, 10);
List<Player> attackers = players.stream().filter(p -> p.getPosition().equals(Position.A)).collect(Collectors.toList()).subList(0, 10);

AsciiTable at = getTable(TABLE_POSITION, TABLE_PLAYER_NAME, TABLE_EFFICIENCY, TABLE_QUOTE, "Out info");
AsciiTable at = getTable(TABLE_POSITION, TABLE_PLAYER_NAME, TABLE_EFFICIENCY, TABLE_QUOTE, "Auct.", "Out info");
for (List<Player> line : Arrays.asList(goals, defenders, midfielders, attackers)) {
for (Player player : line) {
org.blondin.mpg.out.model.Player outPlayer = outPlayersClient.getPlayer(championship, player.getName(),
Expand All @@ -154,10 +156,11 @@ static void processMercato(List<Player> players, InjuredSuspendedWrapperClient o
outInfos = String.format("%s - %s - %s", outPlayer.getOutType(), outPlayer.getDescription(), outPlayer.getLength());
}
AT_Row row = at.addRow(player.getPosition(), player.getName(), FORMAT_DECIMAL_DOUBLE.format(player.getEfficiency()),
player.getQuotation(), outInfos);
player.getQuotation(), player.getAuction(), outInfos);
setTableFormatRowPaddingSpace(row);
row.getCells().get(2).getContext().setTextAlignment(TextAlignment.RIGHT);
row.getCells().get(3).getContext().setTextAlignment(TextAlignment.RIGHT);
row.getCells().get(4).getContext().setTextAlignment(TextAlignment.RIGHT);
}
at.addRule();
}
Expand All @@ -179,8 +182,9 @@ static void processGames(League league, ApiClients apiClients, Config config) {
completePlayersTeam(team.getSquad(), pool);
List<Player> players = team.getSquad().values().stream().collect(Collectors.toList());

// Calculate efficiency (notes should be in injured players display), and save for transactions proposal
calculateEfficiency(players, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config, false, true);
// Complete auction and calculate efficiency (notes should be in injured players display), and save for transactions proposal
completeAuctionAndcalculateEfficiency(players, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config,
false, true);
List<Player> playersTeam = players.stream().collect(Collectors.toList());

// Remove out players (and write them)
Expand Down Expand Up @@ -212,8 +216,8 @@ static void processGames(League league, ApiClients apiClients, Config config) {
List<Player> playersAvailable = apiClients.getMpg().getAvailablePlayers(league.getDivisionId()).getList();
completePlayersClub(playersAvailable, apiClients.getMpg().getClubs());
removeOutPlayers(playersAvailable, apiClients.getOutPlayers(), ChampionshipTypeWrapper.toOut(league.getChampionship()), false);
calculateEfficiency(playersAvailable, apiClients.getStats(), ChampionshipTypeWrapper.toStats(league.getChampionship()), config,
false, false);
completeAuctionAndcalculateEfficiency(playersAvailable, apiClients.getStats(),
ChampionshipTypeWrapper.toStats(league.getChampionship()), config, false, false);

Integer currentPlayersBuy = team.getBids().stream().map(Player::getPricePaid).collect(Collectors.summingInt(Integer::intValue));
writeTransactionsProposal(playersTeam, playersAvailable, team.getBudget() - currentPlayersBuy, apiClients.getOutPlayers(),
Expand Down Expand Up @@ -424,8 +428,35 @@ private static void writeTeamOptimized(List<Player> players, boolean isDebug) {
LOG.info(render);
}

private static List<Player> calculateEfficiency(List<Player> players, MpgStatsClient stats, ChampionshipStatsType championship, Config config,
boolean failIfPlayerNotFound, boolean logWarnIfPlayerNotFound) {
private static List<Player> completeAuctionAndcalculateEfficiency(List<Player> players, MpgStatsClient stats, ChampionshipStatsType championship,
Config config, boolean failIfPlayerNotFound, boolean logWarnIfPlayerNotFound) {

// Pre-process efficiencies
calculateEfficiencies(stats, championship, config);

// Fill MPG model
for (Player player : players) {
try {
org.blondin.mpg.stats.model.Player p = stats.getStats(championship).getPlayer(player.getName());
if (p.getAuction() != null) {
// Feature in API only since 2021-11
player.setAuction(p.getAuction().getAverage());
}
player.setEfficiency(p.getEfficiency());
} catch (PlayerNotFoundException e) {
if (failIfPlayerNotFound) {
throw e;
}
if (logWarnIfPlayerNotFound) {
LOG.warn("WARN: Player can't be found in statistics: {}", player.getName());
}
player.setEfficiency(0);
}
}
return players;
}

private static void calculateEfficiencies(MpgStatsClient stats, ChampionshipStatsType championship, Config config) {
int daysPeriod = getCurrentDay(stats, championship);
int days4efficiency = 0;
if (config.isEfficiencyRecentFocus() && stats.getStats(championship).getInfos().getAnnualStats().getCurrentDay().getDayReached() > 0) {
Expand All @@ -443,22 +474,6 @@ private static List<Player> calculateEfficiency(List<Player> players, MpgStatsCl
// round efficiency to 2 decimals
p.setEfficiency(efficiency);
}

// Fill MPG model
for (Player player : players) {
try {
player.setEfficiency(stats.getStats(championship).getPlayer(player.getName()).getEfficiency());
} catch (PlayerNotFoundException e) {
if (failIfPlayerNotFound) {
throw e;
}
if (logWarnIfPlayerNotFound) {
LOG.warn("WARN: Player can't be found in statistics: {}", player.getName());
}
player.setEfficiency(0);
}
}
return players;
}

private static int getCurrentDay(MpgStatsClient stats, ChampionshipStatsType championship) {
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/blondin/mpg/root/model/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class Player {
private String clubId;
private String clubName;
private double efficiency;
private int auction;

public String getId() {
return id;
Expand Down Expand Up @@ -47,6 +48,14 @@ public int getPricePaid() {
return pricePaid;
}

public int getAuction() {
return auction;
}

public void setAuction(int auction) {
this.auction = auction;
}

public void setPricePaid(int pricePaid) {
this.pricePaid = pricePaid;
}
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/org/blondin/mpg/stats/model/Auction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.blondin.mpg.stats.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Auction {

@JsonProperty("m")
private int min;
@JsonProperty("a")
private int average;
@JsonProperty("M")
private int max;
@JsonProperty("n")
private int number;

public int getMin() {
return min;
}

public int getAverage() {
return average;
}

public int getMax() {
return max;
}

public int getNumber() {
return number;
}

}
6 changes: 6 additions & 0 deletions src/main/java/org/blondin/mpg/stats/model/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class Player {
private Stats stats;
@JsonProperty("r")
private int price;
@JsonProperty("a")
private Auction auction;

private double efficiency;

Expand All @@ -50,6 +52,10 @@ public int getPrice() {
return price;
}

public Auction getAuction() {
return auction;
}

public Stats getStats() {
if (stats == null) {
stats = new Stats();
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/blondin/mpg/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,10 @@ public void testPrepareMercatoTurn0Day0Ligue1() throws Exception {
Assert.assertTrue(getLogOut(), getLogOut().contains("Proposal for your coming soon mercato"));

// When championship not started (incoming day 1 in statistics), the previous year should be taken
Assert.assertTrue(getLogOut(), getLogOut().contains("| A | Mbappé Kylian | 166.21 | 40 | |"));
Assert.assertTrue(getLogOut(), getLogOut().contains("| A | Mbappé Kylian | 166.21 | 40 | 0 | |"));

// Test some injuries
Assert.assertTrue(getLogOut(), getLogOut().contains("| D | Maripán Guillermo | 24.19 | 18 | INJURY_RED - Leg injury - Mid July |"));
Assert.assertTrue(getLogOut(), getLogOut().contains("| D | Maripán Guillermo | 24.19 | 18 | 0 | INJURY_RED - Leg injury - Mid July |"));
}

@Test
Expand Down
15 changes: 15 additions & 0 deletions src/test/java/org/blondin/mpg/stats/MpgStatsClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@

public class MpgStatsClientTest extends AbstractMockTestClient {

//

@Test
public void testAuction() {
stubFor(get("/builds").willReturn(aResponse().withHeader("Content-Type", "application/json").withBodyFile("mlnstats.builds.20211122.json")));
stubFor(get("/leagues/Ligue-1")
.willReturn(aResponse().withHeader("Content-Type", "application/json").withBodyFile("mlnstats.ligue-1.20211122.json")));
MpgStatsClient mpgStatsClient = MpgStatsClient.build(getConfig(), "http://localhost:" + getServer().port());
Player p = mpgStatsClient.getStats(ChampionshipStatsType.LIGUE_1).getPlayer("Mbappé");
Assert.assertEquals(43, p.getAuction().getMin());
Assert.assertEquals(103, p.getAuction().getAverage());
Assert.assertEquals(199, p.getAuction().getMax());
Assert.assertEquals(106, p.getAuction().getNumber());
}

@Test
public void testPlayersWithSameName() {
stubFor(get("/builds").willReturn(aResponse().withHeader("Content-Type", "application/json").withBodyFile("mlnstats.builds.20210804.json")));
Expand Down
17 changes: 17 additions & 0 deletions src/test/resources/__files/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ The `XXX` should be replaced by a use case scenario (like date, some league, dat
| `equipeactu.serie-a.XXX.html` | <https://www.equipeactu.fr/blessures-et-suspensions/fodbold/italie/serie-a> | **Deprecated since October 20, 2020** ([#169](https://github.com/axel3rd/mpg-coach-bot/issues/169)). Injury / Suspended players for **Seria A (Italia)** |
| `equipeactu.ligue-2.XXX.html` | | **Not used**, see below and [#99](https://github.com/axel3rd/mpg-coach-bot/issues/99), EquipeActu Website doesn't contain Ligue 2 (France) |

### Mpg Mobile App (complement, if needed)

Mercato history:

* GET <https://api.mpg.football/division/mpg_division_MLEXXXXX_4_1/history>
* GET <https://api.mpg.football/division/mpg_division_MLEXXXXX_2_1/history>

User leagues:

* GET <https://api.mpg.football/user> ; use info, see `hiddenLeaguesIds` field in addition
* GET <https://api.mpg.football/user/leagues> ; Leagues details

Enable/disable one league:

* PATCH <https://api.mpg.football/league/mpg_league_MLEXXXXX/un-hide>
* PATCH <https://api.mpg.football/league/mpg_league_MLEXXXXX/hide>

### Mpg WebSite (deprecated since 19 July 2021)

| **File** | **URL** | **Description** |
Expand Down

0 comments on commit 9d035be

Please sign in to comment.