Archived
0

implement compute min and max fuel for jump to distance

This commit is contained in:
iMoHax
2015-07-13 15:19:00 +03:00
parent 70d140c7de
commit 6e0fe05576
2 changed files with 150 additions and 16 deletions

View File

@@ -31,6 +31,7 @@ public class Ship {
public void setCargo(int cargo) { public void setCargo(int cargo) {
this.cargo = cargo; this.cargo = cargo;
fuelTable = null;
} }
public Engine getEngine() { public Engine getEngine() {
@@ -38,11 +39,12 @@ public class Ship {
} }
public void setEngine(int clazz, char rating) { public void setEngine(int clazz, char rating) {
this.engine = new Engine(clazz, rating); setEngine(new Engine(clazz, rating));
} }
public void setEngine(Engine engine) { public void setEngine(Engine engine) {
this.engine = engine; this.engine = engine;
fuelTable = null;
} }
public double getTank() { public double getTank() {
@@ -59,6 +61,7 @@ public class Ship {
public void setMass(double mass) { public void setMass(double mass) {
this.mass = mass; this.mass = mass;
fuelTable = null;
} }
public double getLadenMass(){ public double getLadenMass(){
@@ -69,41 +72,49 @@ public class Ship {
return mass+fuel+cargo; return mass+fuel+cargo;
} }
//Laden fuel cost
public double getFuelCost(double distance){
return engine.getFuelCost(distance, getLadenMass(getRoundMaxFuel(distance)));
}
public double getFuelCost(double fuel, double distance){ public double getFuelCost(double fuel, double distance){
return engine.getFuelCost(distance, getLadenMass(fuel)); return engine.getFuelCost(distance, getLadenMass(fuel));
} }
public double getMaxFuelCost(double distance){
return engine.getMaxFuel(distance, getLadenMass(engine.getMaxFuel()));
}
public double getRoundMaxFuel(double distance){ public double getRoundMaxFuel(double distance){
return getRoundMaxFuel(distance, REFILL_FUEL_STEP); return getRoundMaxFuel(distance, REFILL_FUEL_STEP);
} }
public double getRoundFuel(double fuel){
return getRoundFuel(fuel, REFILL_FUEL_STEP);
}
public double getRoundFuel(double fuel, int step){
fuel = Math.floor(fuel*step/tank) * tank / step;
return fuel < 0 ? 0 : fuel;
}
private double getRoundMaxFuel(double distance, int step){ private double getRoundMaxFuel(double distance, int step){
double fuel = getMaxFuel(distance); double fuel = getMaxFuel(distance);
if (fuel == 0 || fuel == tank) return fuel; if (fuel == 0 || fuel == tank) return fuel;
double minFuel = engine.getFuelCost(distance, getLadenMass(0)); double minFuel = getMinFuel(distance);
fuel = Math.floor(fuel*step/tank) * tank / step; fuel = Math.floor(fuel*step/tank) * tank / step;
return fuel < minFuel ? 0 : fuel; return fuel < minFuel ? 0 : fuel;
} }
public double getMaxFuel(double distance){
double fuel = engine.getMaxFuel(distance, getLadenMass(0));
if (fuel >= tank) return tank;
return fuel;
}
public double getMaxJumpRange(){ public double getMaxJumpRange(){
return getJumpRange(Math.min(engine.getMaxFuel(), tank)); if (Double.isNaN(maxJumpRange)){
maxJumpRange = getJumpRange(Math.min(engine.getMaxFuel(), tank));
}
return maxJumpRange;
} }
//Jump range with full fuel tank //Jump range with full fuel tank
public double getJumpRange(){ public double getJumpRange(){
return getJumpRange(tank); if (Double.isNaN(ladenJumpRange)){
ladenJumpRange = getJumpRange(tank);
}
return ladenJumpRange;
} }
//Laden jump range //Laden jump range
@@ -208,6 +219,7 @@ public class Ship {
return getMultiplier() * Math.pow(distance * (mass / getOptMass()), getPowMultiplier()); return getMultiplier() * Math.pow(distance * (mass / getOptMass()), getPowMultiplier());
} }
//return max fuel for jump to distance
public double getMaxFuel(double distance, double emptyTankMass){ public double getMaxFuel(double distance, double emptyTankMass){
double f = Math.pow(getMaxFuel()/getMultiplier(), 1/getPowMultiplier())*getOptMass()/distance - emptyTankMass; double f = Math.pow(getMaxFuel()/getMultiplier(), 1/getPowMultiplier())*getOptMass()/distance - emptyTankMass;
return f < getMaxFuel() ? 0 : f; return f < getMaxFuel() ? 0 : f;
@@ -224,4 +236,49 @@ public class Ship {
", fuelPJ="+getMaxFuel()+"}"; ", fuelPJ="+getMaxFuel()+"}";
} }
} }
private final static float FUEL_TABLE_STEP = 0.01f;
private FuelHelper[] fuelTable;
private double maxJumpRange = Double.NaN;
private double ladenJumpRange = Double.NaN;
private void fillFuelTable(){
double fuel = getEngine().getMaxFuel();
fuelTable = new FuelHelper[(int) (fuel/FUEL_TABLE_STEP)];
maxJumpRange = Double.NaN; ladenJumpRange = Double.NaN;
for (int i = fuelTable.length - 1; i >= 0; i--) {
double distance = getJumpRange(fuel);
fuelTable[i] = new FuelHelper(distance, fuel);
fuel = fuel - FUEL_TABLE_STEP;
}
}
public double getMaxFuel(double distance){
if (distance > getMaxJumpRange()) return 0;
if (distance <= getJumpRange()) return tank;
return engine.getMaxFuel(distance, getLadenMass(0));
}
public double getMinFuel(double distance){
if (fuelTable == null) fillFuelTable();
if (distance > getMaxJumpRange()) return 0;
for (int i = 0; i < fuelTable.length; i++) {
FuelHelper h = fuelTable[i];
if (distance <= h.distance) {
return i == 0 ? 0 : h.fuel <= tank ? h.fuel : 0;
}
}
return 0;
}
private class FuelHelper {
private final double distance;
private final double fuel;
private FuelHelper(double distance, double fuel) {
this.distance = distance;
this.fuel = fuel;
}
}
} }

View File

@@ -0,0 +1,77 @@
package ru.trader.core;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ShipTest extends Assert {
private final static Logger LOG = LoggerFactory.getLogger(ShipTest.class);
@Test
public void testShip() throws Exception {
Ship ship = new Ship();
ship.setCargo(440); ship.setTank(15);
ship.setEngine(5, 'A'); ship.setMass(466);
assertEquals(906, ship.getLadenMass(0), 0.0000001);
assertEquals(913, ship.getLadenMass(7), 0.0000001);
assertEquals(921, ship.getLadenMass(15), 0.0000001);
assertEquals(921, ship.getLadenMass(), 0.0000001);
assertEquals(13.373, ship.getJumpRange(), 0.001);
assertEquals(13.373, ship.getJumpRange(15), 0.001);
assertEquals(13.446, ship.getJumpRange(10), 0.001);
assertEquals(13.519, ship.getJumpRange(5), 0.001);
assertEquals(9.332, ship.getJumpRange(2), 0.001);
assertEquals(0, ship.getJumpRange(0), 0.001);
assertEquals(13.519, ship.getMaxJumpRange(), 0.001);
assertEquals(40.339, ship.getFullTankJumpRange(), 0.001);
assertEquals(0, ship.getMinFuel(0), 0.01);
assertEquals(0.44, ship.getMinFuel(5), 0.01);
assertEquals(2.38, ship.getMinFuel(10), 0.01);
assertEquals(4.54, ship.getMinFuel(13), 0.01);
assertEquals(4.94, ship.getMinFuel(13.45), 0.01);
assertEquals(5, ship.getMinFuel(13.519), 0.01);
assertEquals(0, ship.getMinFuel(14), 0.01);
assertEquals(0, ship.getMinFuel(20), 0.01);
assertEquals(15, ship.getMaxFuel(0), 0.01);
assertEquals(15, ship.getMaxFuel(5), 0.01);
assertEquals(15, ship.getMaxFuel(10), 0.01);
assertEquals(15, ship.getMaxFuel(13), 0.01);
assertEquals(9.73, ship.getMaxFuel(13.45), 0.01);
assertEquals(5.05, ship.getMaxFuel(13.519), 0.01);
assertEquals(0, ship.getMaxFuel(14), 0.01);
assertEquals(0, ship.getMaxFuel(20), 0.01);
assertEquals(15, ship.getRoundMaxFuel(0), 0.01);
assertEquals(15, ship.getRoundMaxFuel(5), 0.01);
assertEquals(15, ship.getRoundMaxFuel(10), 0.01);
assertEquals(15, ship.getRoundMaxFuel(13), 0.01);
assertEquals(9, ship.getRoundMaxFuel(13.45), 0.01);
assertEquals(0, ship.getRoundMaxFuel(13.519), 0.01);
assertEquals(0, ship.getRoundMaxFuel(14), 0.01);
assertEquals(0, ship.getRoundMaxFuel(20), 0.01);
assertEquals(0, ship.getFuelCost(15, 0), 0.001);
assertEquals(0.448, ship.getFuelCost(15, 5), 0.001);
assertEquals(2.453, ship.getFuelCost(15, 10), 0.001);
assertEquals(4.665, ship.getFuelCost(15, 13), 0.001);
assertEquals(5.070, ship.getFuelCost(15, 13.45), 0.001);
assertEquals(5.134, ship.getFuelCost(15, 13.519), 0.001);
assertEquals(5.593, ship.getFuelCost(15, 14), 0.001);
assertEquals(13.403, ship.getFuelCost(15, 20), 0.001);
assertEquals(0, ship.getFuelCost(5, 0), 0.001);
assertEquals(0.437, ship.getFuelCost(5, 5), 0.001);
assertEquals(2.388, ship.getFuelCost(5, 10), 0.001);
assertEquals(4.542, ship.getFuelCost(5, 13), 0.001);
assertEquals(4.936, ship.getFuelCost(5, 13.45), 0.001);
assertEquals(4.999, ship.getFuelCost(5, 13.519), 0.001);
assertEquals(5.446, ship.getFuelCost(5, 14), 0.001);
assertEquals(13.050, ship.getFuelCost(5, 20), 0.001);
}
}