/**
* PaternMatchingGunStatistic.java
*/
package rampancy_old.statistics;
import rampancy_old.RampantRobot;
import rampancy_old.statistics.pattern.*;
import rampancy_old.util.*;
import rampancy_old.weapons.FiringSolution;
import rampancy_old.weapons.PatternMatchingGun;
import java.awt.geom.Point2D;
import java.util.*;
/**
* @author Matthew Chun-Lum
*
*/
public class PatternMatchingGunStatistic {
public static final int MAX_HISTORY_LENGTH = 1000;
public static final int SEARCH_DEPTH = 60;
public static final int LOG_DEPTH = 20;
private ArrayList<PMState> movementHistory;
private int shotsFired;
private int shotsHit;
private double hitPercentage;
private double closestDistance;
public PatternMatchingGunStatistic() {
movementHistory = new ArrayList<PMState>();
}
/**
* Logs the current state of the enemy robot in the movementHistory
* @param enemy
*/
public void logState(EnemyRobot enemy) {
PMState state = new PMState(enemy);
movementHistory.add(state);
// keep the size within reasonable limits
if(movementHistory.size() > MAX_HISTORY_LENGTH)
movementHistory.remove(0);
}
/**
* @param enemy
* @return a firing solution based on the enemy's current state
*/
public FiringSolution getFiringSolution(RampantRobot reference, EnemyRobot enemy) {
EnemyState enemyState = new EnemyState(enemy);
int[] profile = enemy.getVariationProfile().getProfile();
PMMatch match = getMatchForPattern(enemy.getMovementLog());
PMFiringSolution fs = PatternMatchingGun.computOffsetAngle(reference.getMovementManager().getBattlefield(), match, enemy, reference.getLocation());
if(fs == null) {
fs = new PMFiringSolution(0.1, 0, null);
}
return new FiringSolution(enemyState, fs.offset, fs.power, null, PatternMatchingGun.DEFAULT_COLOR, fs.anticipated, (match == null ? 100 : match.distance));
}
public PMMatch getMatchForPattern(ArrayList<PMState> pattern) {
int index = getIndexOfClosestMatch(pattern);
return new PMMatch(getProjectedState(index + pattern.size()), closestDistance);
}
public ArrayList<PMState> getProjectedState(int index) {
if(index >= movementHistory.size() - 1 || index == -1)
return null;
return new ArrayList<PMState>(movementHistory.subList(index, Math.min(movementHistory.size(), index + SEARCH_DEPTH)));
}
public int getIndexOfClosestMatch(ArrayList<PMState> pattern) {
int closest = -1;
closestDistance = 100000;
for(int i = 0; i < movementHistory.size() - LOG_DEPTH; i++) {
double distance = computeDistance(pattern, i);
if(distance < closestDistance) {
closest = i;
closestDistance = distance;
}
}
return closest;
}
private double computeDistance(ArrayList<PMState> pattern, int startingIndex) {
double distance = 0;
int i, j;
for(i = startingIndex, j = 0; i < movementHistory.size() && j < pattern.size(); i++, j++) {
distance += movementHistory.get(i).distance(pattern.get(j));
}
if(movementHistory.size() - startingIndex < pattern.size())
distance *= 4;
return distance;
}
}