/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Pavel Savara * - Initial implementation * Pavel Savara * - Xml Serialization, refactoring *******************************************************************************/ package net.sf.robocode.battle.snapshot; import net.sf.robocode.battle.peer.RobotStatistics; import net.sf.robocode.serialization.IXmlSerializable; import net.sf.robocode.serialization.XmlReader; import net.sf.robocode.serialization.SerializableOptions; import net.sf.robocode.serialization.XmlWriter; import robocode.control.snapshot.IScoreSnapshot; import java.io.IOException; import java.io.Serializable; /** * A snapshot of a score at a specific time instant in a battle. * The snapshot contains a snapshot of the score data at that specific time. * * @author Pavel Savara (original) * @author Flemming N. Larsen (contributor) * @since 1.6.1 */ public final class ScoreSnapshot implements Comparable<IScoreSnapshot>, Serializable, IXmlSerializable, IScoreSnapshot { private static final long serialVersionUID = 1L; /** The name of the contestant, i.e. a robot or team */ private String name; /** The total score */ private double totalScore; /** The total survival score */ private double totalSurvivalScore; /** The total last survivor score */ private double totalLastSurvivorBonus; /** The total bullet damage score */ private double totalBulletDamageScore; /** The total bullet kill bonus */ private double totalBulletKillBonus; /** The total ramming damage score */ private double totalRammingDamageScore; /** The total ramming kill bonus */ private double totalRammingKillBonus; /** The total number of first places */ private int totalFirsts; /** The total number of second places */ private int totalSeconds; /** The total number of third places */ private int totalThirds; /** The current score */ private double currentScore; /** The current survival score */ private double currentSurvivalScore; /** The current survival bonus */ private double currentSurvivalBonus; /** The current bullet damage score */ private double currentBulletDamageScore; /** The current bullet kill bonus */ private double currentBulletKillBonus; /** The current ramming damage score */ private double currentRammingDamageScore; /** The current ramming kill bonus */ private double currentRammingKillBonus; /** * Creates a snapshot of a score that must be filled out with data later. */ public ScoreSnapshot() {} /** * Creates a snapshot of a score. * * @param score the contestant's score to take a snapshot of. * @param contestantName the name of the contestant. */ public ScoreSnapshot(String contestantName, RobotStatistics score) { this.name = contestantName; totalScore = score.getTotalScore(); totalSurvivalScore = score.getTotalSurvivalScore(); totalLastSurvivorBonus = score.getTotalLastSurvivorBonus(); totalBulletDamageScore = score.getTotalBulletDamageScore(); totalBulletKillBonus = score.getTotalBulletKillBonus(); totalRammingDamageScore = score.getTotalRammingDamageScore(); totalRammingKillBonus = score.getTotalRammingKillBonus(); totalFirsts = score.getTotalFirsts(); totalSeconds = score.getTotalSeconds(); totalThirds = score.getTotalThirds(); currentScore = score.getCurrentScore(); currentBulletDamageScore = score.getCurrentBulletDamageScore(); currentSurvivalScore = score.getCurrentSurvivalScore(); currentSurvivalBonus = score.getCurrentSurvivalBonus(); currentBulletKillBonus = score.getCurrentBulletKillBonus(); currentRammingDamageScore = score.getCurrentRammingDamageScore(); currentRammingKillBonus = score.getCurrentRammingKillBonus(); } /** * Creates a snapshot of a score based on two sets of scores that are added together. * * @param contestantName the name of the contestant. * @param score1 the contestant's first set of scores to base this snapshot on. * @param score2 the contestant's second set of scores that must be added to the first set of scores. */ public ScoreSnapshot(String contestantName, IScoreSnapshot score1, IScoreSnapshot score2) { this.name = contestantName; totalScore = score1.getTotalScore() + score2.getTotalScore(); totalSurvivalScore = score1.getTotalSurvivalScore() + score2.getTotalSurvivalScore(); totalLastSurvivorBonus = score1.getTotalLastSurvivorBonus() + score2.getTotalLastSurvivorBonus(); totalBulletDamageScore = score1.getTotalBulletDamageScore() + score2.getTotalBulletDamageScore(); totalBulletKillBonus = score1.getTotalBulletKillBonus() + score2.getTotalBulletKillBonus(); totalRammingDamageScore = score1.getTotalRammingDamageScore() + score2.getTotalRammingDamageScore(); totalRammingKillBonus = score1.getTotalRammingKillBonus() + score2.getTotalRammingKillBonus(); totalFirsts = score1.getTotalFirsts() + score2.getTotalFirsts(); totalSeconds = score1.getTotalSeconds() + score2.getTotalSeconds(); totalThirds = score1.getTotalThirds() + score2.getTotalThirds(); currentScore = score1.getCurrentScore() + score2.getCurrentScore(); currentSurvivalScore = score1.getCurrentSurvivalScore() + score2.getCurrentSurvivalScore(); currentBulletDamageScore = score1.getCurrentBulletDamageScore() + score2.getCurrentBulletDamageScore(); currentBulletKillBonus = score1.getCurrentBulletKillBonus() + score2.getCurrentBulletKillBonus(); currentRammingDamageScore = score1.getCurrentRammingDamageScore() + score2.getCurrentRammingDamageScore(); currentRammingKillBonus = score1.getCurrentBulletKillBonus() + score2.getCurrentBulletKillBonus(); } /** * {@inheritDoc} */ public String getName() { return name; } /** * {@inheritDoc} */ public double getTotalScore() { return totalScore; } /** * {@inheritDoc} */ public double getTotalSurvivalScore() { return totalSurvivalScore; } /** * {@inheritDoc} */ public double getTotalLastSurvivorBonus() { return totalLastSurvivorBonus; } /** * {@inheritDoc} */ public double getTotalBulletDamageScore() { return totalBulletDamageScore; } /** * {@inheritDoc} */ public double getTotalBulletKillBonus() { return totalBulletKillBonus; } /** * {@inheritDoc} */ public double getTotalRammingDamageScore() { return totalRammingDamageScore; } /** * {@inheritDoc} */ public double getTotalRammingKillBonus() { return totalRammingKillBonus; } /** * {@inheritDoc} */ public int getTotalFirsts() { return totalFirsts; } /** * {@inheritDoc} */ public int getTotalSeconds() { return totalSeconds; } /** * {@inheritDoc} */ public int getTotalThirds() { return totalThirds; } /** * {@inheritDoc} */ public double getCurrentScore() { return currentScore; } /** * {@inheritDoc} */ public double getCurrentSurvivalScore() { return currentSurvivalScore; } /** * {@inheritDoc} */ public double getCurrentSurvivalBonus() { return currentSurvivalBonus; } /** * {@inheritDoc} */ public double getCurrentBulletDamageScore() { return currentBulletDamageScore; } /** * {@inheritDoc} */ public double getCurrentBulletKillBonus() { return currentBulletKillBonus; } /** * {@inheritDoc} */ public double getCurrentRammingDamageScore() { return currentRammingDamageScore; } /** * {@inheritDoc} */ public double getCurrentRammingKillBonus() { return currentRammingKillBonus; } /** * {@inheritDoc} */ public int compareTo(IScoreSnapshot o) { double myScore = getTotalScore(); double hisScore = o.getTotalScore(); myScore += getCurrentScore(); hisScore += o.getCurrentScore(); if (myScore < hisScore) { return -1; } if (myScore > hisScore) { return 1; } return 0; } /** * {@inheritDoc} */ public void writeXml(XmlWriter writer, SerializableOptions options) throws IOException { writer.startElement(options.shortAttributes ? "sc" : "score"); { if (!options.skipNames) { writer.writeAttribute("name", name); } if (!options.skipTotal) { writer.writeAttribute(options.shortAttributes ? "t" : "totalScore", totalScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "tss" : "totalSurvivalScore", totalSurvivalScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "tls" : "totalLastSurvivorBonus", totalLastSurvivorBonus, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "tbd" : "totalBulletDamageScore", totalBulletDamageScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "tbk" : "totalBulletKillBonus", totalBulletKillBonus, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "trd" : "totalRammingDamageScore", totalRammingDamageScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "trk" : "totalRammingKillBonus", totalRammingKillBonus, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "t1" : "totalFirsts", totalFirsts); writer.writeAttribute(options.shortAttributes ? "t2" : "totalSeconds", totalSeconds); writer.writeAttribute(options.shortAttributes ? "t3" : "totalThirds", totalThirds); } writer.writeAttribute(options.shortAttributes ? "c" : "currentScore", currentScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "ss" : "currentSurvivalScore", currentSurvivalScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "bd" : "currentBulletDamageScore", currentBulletDamageScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "bk" : "currentBulletKillBonus", currentBulletKillBonus, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "rd" : "currentRammingDamageScore", currentRammingDamageScore, options.trimPrecision); writer.writeAttribute(options.shortAttributes ? "rk" : "currentRammingKillBonus", currentRammingKillBonus, options.trimPrecision); if (!options.skipVersion) { writer.writeAttribute("ver", serialVersionUID); } } writer.endElement(); } /** * {@inheritDoc} */ public XmlReader.Element readXml(XmlReader reader) { return reader.expect("score", new XmlReader.Element() { public IXmlSerializable read(XmlReader reader) { final ScoreSnapshot snapshot = new ScoreSnapshot(); reader.expect("name", new XmlReader.Attribute() { public void read(String value) { snapshot.name = value; } }); reader.expect("totalScore", new XmlReader.Attribute() { public void read(String value) { snapshot.totalScore = Double.parseDouble(value); } }); reader.expect("totalSurvivalScore", new XmlReader.Attribute() { public void read(String value) { snapshot.totalSurvivalScore = Double.parseDouble(value); } }); reader.expect("totalLastSurvivorBonus", new XmlReader.Attribute() { public void read(String value) { snapshot.totalLastSurvivorBonus = Double.parseDouble(value); } }); reader.expect("totalBulletDamageScore", new XmlReader.Attribute() { public void read(String value) { snapshot.totalBulletDamageScore = Double.parseDouble(value); } }); reader.expect("totalBulletKillBonus", new XmlReader.Attribute() { public void read(String value) { snapshot.totalBulletKillBonus = Double.parseDouble(value); } }); reader.expect("totalRammingDamageScore", new XmlReader.Attribute() { public void read(String value) { snapshot.totalRammingDamageScore = Double.parseDouble(value); } }); reader.expect("totalRammingKillBonus", new XmlReader.Attribute() { public void read(String value) { snapshot.totalRammingKillBonus = Double.parseDouble(value); } }); reader.expect("totalFirsts", new XmlReader.Attribute() { public void read(String value) { snapshot.totalFirsts = Integer.parseInt(value); } }); reader.expect("totalSeconds", new XmlReader.Attribute() { public void read(String value) { snapshot.totalSeconds = Integer.parseInt(value); } }); reader.expect("totalThirds", new XmlReader.Attribute() { public void read(String value) { snapshot.totalThirds = Integer.parseInt(value); } }); reader.expect("currentScore", new XmlReader.Attribute() { public void read(String value) { snapshot.currentScore = Double.parseDouble(value); } }); reader.expect("currentSurvivalScore", new XmlReader.Attribute() { public void read(String value) { snapshot.currentSurvivalScore = Double.parseDouble(value); } }); reader.expect("currentBulletDamageScore", new XmlReader.Attribute() { public void read(String value) { snapshot.currentBulletDamageScore = Double.parseDouble(value); } }); reader.expect("currentBulletKillBonus", new XmlReader.Attribute() { public void read(String value) { snapshot.currentBulletKillBonus = Double.parseDouble(value); } }); reader.expect("currentRammingDamageScore", new XmlReader.Attribute() { public void read(String value) { snapshot.currentRammingDamageScore = Double.parseDouble(value); } }); reader.expect("currentRammingKillBonus", new XmlReader.Attribute() { public void read(String value) { snapshot.currentRammingKillBonus = Double.parseDouble(value); } }); return snapshot; } }); } @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(currentBulletDamageScore); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(currentBulletKillBonus); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(currentRammingDamageScore); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(currentRammingKillBonus); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(currentScore); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(currentSurvivalBonus); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(currentSurvivalScore); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((name == null) ? 0 : name.hashCode()); temp = Double.doubleToLongBits(totalBulletDamageScore); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(totalBulletKillBonus); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + totalFirsts; temp = Double.doubleToLongBits(totalLastSurvivorBonus); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(totalRammingDamageScore); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(totalRammingKillBonus); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(totalScore); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + totalSeconds; temp = Double.doubleToLongBits(totalSurvivalScore); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + totalThirds; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ScoreSnapshot other = (ScoreSnapshot) obj; if (Double.doubleToLongBits(currentBulletDamageScore) != Double.doubleToLongBits(other.currentBulletDamageScore)) { return false; } if (Double.doubleToLongBits(currentBulletKillBonus) != Double.doubleToLongBits(other.currentBulletKillBonus)) { return false; } if (Double.doubleToLongBits(currentRammingDamageScore) != Double.doubleToLongBits(other.currentRammingDamageScore)) { return false; } if (Double.doubleToLongBits(currentRammingKillBonus) != Double.doubleToLongBits(other.currentRammingKillBonus)) { return false; } if (Double.doubleToLongBits(currentScore) != Double.doubleToLongBits(other.currentScore)) { return false; } if (Double.doubleToLongBits(currentSurvivalBonus) != Double.doubleToLongBits(other.currentSurvivalBonus)) { return false; } if (Double.doubleToLongBits(currentSurvivalScore) != Double.doubleToLongBits(other.currentSurvivalScore)) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } if (Double.doubleToLongBits(totalBulletDamageScore) != Double.doubleToLongBits(other.totalBulletDamageScore)) { return false; } if (Double.doubleToLongBits(totalBulletKillBonus) != Double.doubleToLongBits(other.totalBulletKillBonus)) { return false; } if (totalFirsts != other.totalFirsts) { return false; } if (Double.doubleToLongBits(totalLastSurvivorBonus) != Double.doubleToLongBits(other.totalLastSurvivorBonus)) { return false; } if (Double.doubleToLongBits(totalRammingDamageScore) != Double.doubleToLongBits(other.totalRammingDamageScore)) { return false; } if (Double.doubleToLongBits(totalRammingKillBonus) != Double.doubleToLongBits(other.totalRammingKillBonus)) { return false; } if (Double.doubleToLongBits(totalScore) != Double.doubleToLongBits(other.totalScore)) { return false; } if (totalSeconds != other.totalSeconds) { return false; } if (Double.doubleToLongBits(totalSurvivalScore) != Double.doubleToLongBits(other.totalSurvivalScore)) { return false; } if (totalThirds != other.totalThirds) { return false; } return true; } }