"The planet to start at")
var end = flag.String("end", "",
- "A comma-separated list of planets to end at")
+ "A comma-separated list of acceptable ending planets.")
var planet_data_file = flag.String("planet_data_file", "planet-data",
"The file to read planet data from")
-var fuel = flag.Int("fuel", 16,
- "Reactor units; How many non-Eden jumps we can make " +
- "(but remember that deviating from the flight plan " +
- "costs two units of fuel per jump)")
+var fuel = flag.Int("fuel", 16, "Reactor units")
+
+var hold = flag.Int("hold", 300, "Size of your cargo hold")
var start_edens = flag.Int("start_edens", 0,
"How many Eden Warp Units are you starting with?")
var cloak = flag.Bool("cloak", false,
"Make sure to end with a Device of Cloaking")
-var drones = flag.Int("drones", 0,
- "Buy this many Fighter Drones")
+var drones = flag.Int("drones", 0, "Buy this many Fighter Drones")
-var batteries = flag.Int("batteries", 0,
- "Buy this many Shield Batterys")
+var batteries = flag.Int("batteries", 0, "Buy this many Shield Batterys")
var visit_string = flag.String("visit", "",
"A comma-separated list of planets to make sure to visit")
BeaconOn bool
/* Use relative prices rather than absolute prices because you
can get relative prices without traveling to each planet. */
- RelativePrices map [string] int
+ RelativePrices map[string]int
}
type planet_data struct {
- Commodities map [string] Commodity
- Planets map [string] Planet
- pi, ci map [string] int // Generated; not read from file
+ Commodities map[string]Commodity
+ Planets map[string]Planet
+ pi, ci map[string]int // Generated; not read from file
}
func ReadData() (data planet_data) {
// The official list of dimensions:
const (
- // Name Num Size Description
- Edens = iota // 1 3 # of Eden warp units (0 - 2 typically)
- Cloaks // 2 2 # of Devices of Cloaking (0 or 1)
- UnusedCargo // 3 4 # of unused cargo spaces (0 - 3 typically)
- Fuel // 4 17 Reactor power left (0 - 16)
- Location // 5 26 Location (which planet)
- Hold // 6 15 Cargo bay contents (a *Commodity or nil)
- NeedFighters // 7 2 Errand: Buy fighter drones (needed or not)
- NeedShields // 8 2 Errand: Buy shield batteries (needed or not)
- Visit // 9 2**N Visit: Stop by these N planets in the route
+ // Name Num Size Description
+ Edens = iota // 1 3 # of Eden warp units (0 - 2 typically)
+ Cloaks // 2 2 # of Devices of Cloaking (0 or 1)
+ UnusedCargo // 3 4 # of unused cargo spaces (0 - 3 typically)
+ Fuel // 4 17 Reactor power left (0 - 16)
+ Location // 5 26 Location (which planet)
+ Hold // 6 15 Cargo bay contents (a *Commodity or nil)
+ NeedFighters // 7 2 Errand: Buy fighter drones (needed or not)
+ NeedShields // 8 2 Errand: Buy shield batteries (needed or not)
+ Visit // 9 2**N Visit: Stop by these N planets in the route
NumDimensions
)
func bint(b bool) int {
- if b { return 1 }
+ if b {
+ return 1
+ }
return 0
}
func DimensionSizes(data planet_data) []int {
eden_capacity := data.Commodities["Eden Warp Units"].Limit
cloak_capacity := bint(*cloak)
- dims := []int{
- eden_capacity + 1,
- cloak_capacity + 1,
- eden_capacity + cloak_capacity + 1,
- *fuel + 1,
- len(data.Planets),
- len(data.Commodities),
- bint(*drones > 0) + 1,
- bint(*batteries > 0) + 1,
- 1 << uint(len(visit())),
- }
- if len(dims) != NumDimensions {
- panic("Dimensionality mismatch")
+ dims := make([]int, NumDimensions)
+ dims[Edens] = eden_capacity + 1
+ dims[Cloaks] = cloak_capacity + 1
+ dims[UnusedCargo] = eden_capacity + cloak_capacity + 1
+ dims[Fuel] = *fuel + 1
+ dims[Location] = len(data.Planets)
+ dims[Hold] = len(data.Commodities)
+ dims[NeedFighters] = bint(*drones > 0) + 1
+ dims[NeedShields] = bint(*batteries > 0) + 1
+ dims[Visit] = 1 << uint(len(visit()))
+
+ // Remind myself to add a line above when adding new dimensions
+ for i, dim := range dims {
+ if dim < 1 {
+ panic(i)
+ }
}
return dims
}
func EncodeIndex(dims, addr []int) int {
index := addr[0]
for i := 1; i < len(dims); i++ {
- index = index * dims[i] + addr[i]
+ index = index*dims[i] + addr[i]
}
return index
}
/* What is the value of hauling 'commodity' from 'from' to 'to'?
* Take into account the available funds and the available cargo space. */
func TradeValue(data planet_data,
- from, to Planet,
- commodity string,
- initial_funds, max_quantity int) int {
+from, to Planet,
+commodity string,
+initial_funds, max_quantity int) int {
if !data.Commodities[commodity].CanSell {
return 0
}
}
for commodity := range price_list {
gain := TradeValue(data,
- data.Planets[from],
- data.Planets[to],
- commodity,
- 10000000,
- 1)
+ data.Planets[from],
+ data.Planets[to],
+ commodity,
+ 10000000,
+ 1)
if gain > best_gain {
best[data.pi[from]][data.pi[to]] = commodity
gain = best_gain
}
// (Example of a use case for generics in Go)
-func IndexPlanets(m *map [string] Planet) map [string] int {
- index := make(map [string] int, len(*m))
+func IndexPlanets(m *map[string]Planet) map[string]int {
+ index := make(map[string]int, len(*m))
i := 0
for e := range *m {
index[e] = i
}
return index
}
-func IndexCommodities(m *map [string] Commodity) map [string] int {
- index := make(map [string] int, len(*m))
+func IndexCommodities(m *map[string]Commodity) map[string]int {
+ index := make(map[string]int, len(*m))
i := 0
for e := range *m {
index[e] = i
data.ci = IndexCommodities(&data.Commodities)
dims := DimensionSizes(data)
table := NewStateTable(dims)
- table[0] = State{ 1, 1 }
+ table[0] = State{1, 1}
best_trades := FindBestTrades(data)
for from := range data.Planets {