Skip to content

Commit

Permalink
Update future match predictions; change rocket RP chance model
Browse files Browse the repository at this point in the history
  • Loading branch information
spencerng committed Mar 5, 2019
1 parent 1a03d7c commit 77bfe05
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,11 @@ private void processData() {
}

if (generatePredictions.isSelected()) {
eventReport.generateMatchPredictions(currentDataDirectory);
status += "\nFuture match predictions generated";
if (eventReport.generateMatchPredictions(currentDataDirectory)) {
status += "\nFuture match predictions generated";
} else {
status += "\nMatch prediction generation failed";
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.usfirst.frc.team25.scouting.data;

import org.apache.commons.math3.exception.NotStrictlyPositiveException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

/**
Expand All @@ -24,7 +23,7 @@ public class AllianceReport {
* The number of Monte Carlo simulation iterations to run to compute standard deviations of functions.
* A larger number of iterations generally provides greater accuracy.
*/
private final int MONTE_CARLO_ITERATIONS = 5000;
private final int MONTE_CARLO_ITERATIONS = 1000;
private final String[] numStrNames = new String[]{"One", "Two", "Three", "total"};
/**
* Denotes the best HAB levels to start from at the beginning of the match in order to maximize points earned.
Expand Down Expand Up @@ -432,7 +431,6 @@ private double calculateStdDevTeleOpPoints(ArrayList<ArrayList<HashMap<String, D
}



//Restores values using the original alliance report
calculateExpectedValues();
calculatePredictedTeleOpPoints();
Expand Down Expand Up @@ -480,13 +478,33 @@ private ArrayList<ArrayList<HashMap<String, Double>>> generateMonteCarloSet() {
}

public double calculateClimbRpChance() {
double climbRpChance;
try {
climbRpChance = Stats.rightTailNormalProbability(15, predictedValues.get("endgamePoints"),
standardDeviations.get("endgamePoints"));
} catch (NotStrictlyPositiveException e) {
climbRpChance = predictedValues.get("endgamePoints") >= 15 ? 1.0 : 0.0;
double climbRpChance = 0.0;

final int[] climbPointValues = new int[]{3, 6, 12};

for (int teamOneClimb = 0; teamOneClimb < 2; teamOneClimb++) {
for (int teamTwoClimb = 0; teamTwoClimb < 2; teamTwoClimb++) {
for (int teamThreeClimb = 0; teamThreeClimb < 2; teamThreeClimb++) {
int points = 0;
int[] climbStatus = new int[]{teamOneClimb, teamTwoClimb, teamThreeClimb};
for (int i = 0; i < 3; i++) {
points += climbStatus[i] * climbPointValues[bestClimbLevels[i] - 1];
}
if (points >= 15) {
double probabilityIteration = 1.0;
for (int i = 0; i < 3; i++) {
if (climbStatus[i] == 1) {
probabilityIteration *= teamReports[i].getAttemptSuccessRate("level" + numStrNames[bestClimbLevels[i] - 1] + "Climb");
} else {
probabilityIteration *= 1 - teamReports[i].getAttemptSuccessRate("level" + numStrNames[bestClimbLevels[i] - 1] + "Climb");
}
}
climbRpChance += probabilityIteration;
}
}
}
}

predictedValues.put("climbRp", climbRpChance);

return climbRpChance;
Expand All @@ -499,6 +517,9 @@ public double calculateClimbRpChance() {
*/
public String getQuickAllianceReport() {

Object[] keys = predictedValues.keySet().toArray();
Arrays.sort(keys);

String quickReport = "";
for (TeamReport report : teamReports) {
quickReport += "Team " + report.getTeamNum();
Expand All @@ -509,7 +530,7 @@ public String getQuickAllianceReport() {
quickReport += "\n";
}

for (String key : predictedValues.keySet()) {
for (Object key : keys) {
quickReport += key + ": " + Stats.round(predictedValues.get(key), 2) + "\n";
}

Expand Down
77 changes: 32 additions & 45 deletions src/main/java/org/usfirst/frc/team25/scouting/data/EventReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

/**
Expand Down Expand Up @@ -523,65 +522,53 @@ public void generatePicklists(File outputDirectory) {
pg.generatePickPointList();
}

public void generateMatchPredictions(File outputDirectory) {
public boolean generateMatchPredictions(File outputDirectory) {

int greatestMatchNum = 0;
for (ScoutEntry entry : scoutEntries) {
if (entry.getPreMatch().getMatchNum() > greatestMatchNum) {
greatestMatchNum = entry.getPreMatch().getMatchNum();
}
}
File matchList = FileManager.getMatchList(outputDirectory);
String[] blocksOfStringMatchesArray;
List<String> futureMatchesBlockList = new ArrayList<>();

try {
String matchesString = FileManager.getFileString(matchList);
blocksOfStringMatchesArray = matchesString.split("\n");
for (String element : blocksOfStringMatchesArray) {
String[] tempArray = element.split(",");
for (String tempElement : tempArray) {
if (tempElement.equals("25") && Integer.parseInt(tempArray[0]) > greatestMatchNum) {
futureMatchesBlockList.add(element);
String predictions = "";

File matchList = FileManager.getMatchList(directory);

String[] matches = FileManager.getFileString(matchList).split("\n");

for (int i = greatestMatchNum + 1; i < matches.length - 1; i++) {
AllianceReport[] allianceReports = getAlliancesInMatch(i);
predictions += "Match " + i + ": ";
for (int j = 0; j < allianceReports.length; j++) {
predictions += allianceReports[j].getTeamReports()[0].getTeamNum() + "-";
predictions += allianceReports[j].getTeamReports()[1].getTeamNum() + "-";
predictions += allianceReports[j].getTeamReports()[2].getTeamNum() + " (";
predictions += Stats.round(allianceReports[j].calculatePredictedRp(allianceReports[Math.abs(j - 1)]), 1) + " RP, ";
predictions += Stats.round(allianceReports[j].getPredictedValue("totalPoints"), 1) + " pts)";
if (j == 0) {
predictions += " vs. ";
}
}
}
for (String element : futureMatchesBlockList) {
String[] tempSplitElement = element.split(",");
for (int i = 1; i < 4; i++) {
if (tempSplitElement[i].equals("25")) {
AllianceReport futureMatchPredictions1 =
new AllianceReport(new TeamReport[]{
teamReports.get(Integer.parseInt(tempSplitElement[1])),
teamReports.get(Integer.parseInt(tempSplitElement[2])),
teamReports.get(Integer.parseInt(tempSplitElement[3]))});
futureMatchPredictions1.getQuickAllianceReport();

AllianceReport futureMatchPredictions2 =
new AllianceReport(new TeamReport[]{
teamReports.get(Integer.parseInt(tempSplitElement[4])),
teamReports.get(Integer.parseInt(tempSplitElement[5])),
teamReports.get(Integer.parseInt(tempSplitElement[6]))});
futureMatchPredictions2.getQuickAllianceReport();
} else {
AllianceReport futureMatchPredictions1 =
new AllianceReport(new TeamReport[]{
teamReports.get(Integer.parseInt(tempSplitElement[4])),
teamReports.get(Integer.parseInt(tempSplitElement[5])),
teamReports.get(Integer.parseInt(tempSplitElement[6]))});
futureMatchPredictions1.getQuickAllianceReport();

AllianceReport futureMatchPrediction2 =
new AllianceReport(new TeamReport[]{
teamReports.get(Integer.parseInt(tempSplitElement[1])),
teamReports.get(Integer.parseInt(tempSplitElement[2])),
teamReports.get(Integer.parseInt(tempSplitElement[3]))});
futureMatchPrediction2.getQuickAllianceReport();
}
double redWinChance = allianceReports[0].calculateWinChance(allianceReports[1]);
if (redWinChance > 0.5) {
predictions += " - Red win, " + Stats.round(redWinChance * 100, 2) + "%\n";
} else {
predictions += " - Blue win, " + Stats.round((1 - redWinChance) * 100, 2) + "%\n";
}

}

if (!predictions.isEmpty()) {
FileManager.outputFile(outputDirectory.getAbsolutePath() + "/MatchPredictions", "txt", predictions);
return true;
}
} catch (Exception e) {

}

return false;
}

public AllianceReport[] getAlliancesInMatch(int matchNum) throws FileNotFoundException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,13 @@ public void calculateDerivedStats() {


//Tele-Op
teleOpHatches = teleOpRocketHatches + teleOp.getCargoShipHatches();

teleOpRocketHatches = teleOp.getRocketLevelOneHatches() + teleOp.getRocketLevelTwoHatches()
+ teleOp.getRocketLevelThreeHatches();

teleOpRocketCargo = teleOp.getRocketLevelOneCargo() + teleOp.getRocketLevelTwoCargo()
+ teleOp.getRocketLevelThreeCargo();

teleOpHatches = teleOpRocketHatches + teleOp.getCargoShipHatches();
teleOpCargo = teleOpRocketCargo + teleOp.getCargoShipCargo();


Expand All @@ -69,16 +68,15 @@ public void calculateDerivedStats() {
calculatedSandstormPoints += preMatch.getStartingLevel() * 3;
}

calculatedTeleOpPoints = teleOpHatches * 2
+ teleOpCargo * 3;
calculatedTeleOpPoints = teleOpHatches * 2 + teleOpCargo * 3;

calculatedClimbPoints = 0;

if ((teleOp.isSuccessHabClimb()) || teleOp.getNumPartnerClimbAssists() > 0) {
calculatedClimbPoints += Math.pow(2, (teleOp.getSuccessHabClimbLevel() - 1)) * 3;
calculatedClimbPoints += 3 * teleOp.getNumPartnerClimbAssists()
* (Math.pow(2, teleOp.getPartnerClimbAssistEndLevel() - 1)
- Math.pow(2, teleOp.getPartnerClimbAssistStartLevel() - 1));
calculatedClimbPoints += 3 * teleOp.getNumPartnerClimbAssists() * (Math.pow(2,
teleOp.getPartnerClimbAssistEndLevel() - 1) - Math.pow(2,
teleOp.getPartnerClimbAssistStartLevel() - 1));
}

calculatedPointContribution = calculatedSandstormPoints + calculatedClimbPoints + calculatedTeleOpPoints;
Expand Down

0 comments on commit 77bfe05

Please sign in to comment.