panic(0)
}
for i := 1; i < NumDimensions; i++ {
- if addr[i] > dims[i] {
+ if addr[i] < 0 || addr[i] > dims[i] {
panic(i)
}
index = index*dims[i] + addr[i]
}
/* Travel here via Eden Warp Unit */
- if addr[Edens]+1 < dims[Edens] {
+ if addr[Edens]+1 < dims[Edens] && addr[UnusedCargo] > 1 {
_, available := data.Planets[data.i2p[addr[Location]]].RelativePrices["Eden Warp Units"]
if !available {
other[Edens] = addr[Edens] + 1
+ other[UnusedCargo] = addr[UnusedCargo] - 1
for other[Location] = 0; other[Location] < dims[Location]; other[Location]++ {
UpdateCell(table, my_index, EncodeIndex(dims, other), 0)
}
other[Location] = addr[Location]
+ other[UnusedCargo] = addr[UnusedCargo]
other[Edens] = addr[Edens]
}
}
my_index := EncodeIndex(dims, addr)
other := make([]int, NumDimensions)
copy(other, addr)
- /* Buy Eden warp units */
+
/* Buy a Device of Cloaking */
if addr[Cloaks] == 1 && addr[UnusedCargo] < dims[UnusedCargo]-1 {
relative_price, available := data.Planets[data.i2p[addr[Location]]].RelativePrices["Device Of Cloakings"]
/* Visit this planet */
}
+func FillCellByBuyingEdens(data planet_data, dims []int, table []State, addr []int) {
+ my_index := EncodeIndex(dims, addr)
+ other := make([]int, NumDimensions)
+ copy(other, addr)
+
+ /* Buy Eden warp units */
+ eden_limit := data.Commodities["Eden Warp Units"].Limit
+ if addr[Edens] > 0 && addr[Edens] <= eden_limit {
+ relative_price, available := data.Planets[data.i2p[addr[Location]]].RelativePrices["Eden Warp Units"]
+ if available {
+ absolute_price := int(float64(data.Commodities["Eden Warp Units"].BasePrice) * float64(relative_price) / 100.0)
+ for quantity := addr[Edens]; quantity > 0; quantity-- {
+ other[Edens] = addr[Edens] - quantity
+ if addr[Hold] != 0 {
+ other[UnusedCargo] = addr[UnusedCargo] + quantity
+ }
+ if other[UnusedCargo] < dims[UnusedCargo] {
+ UpdateCell(table, my_index, EncodeIndex(dims, other), -absolute_price * quantity)
+ }
+ }
+ other[Edens] = addr[Edens]
+ other[UnusedCargo] = addr[UnusedCargo]
+ }
+ }
+}
+
func FillStateTable2Iteration(data planet_data, dims []int, table []State,
addr []int, f func(planet_data, []int, []State, []int)) {
/* TODO: Justify the safety of the combination of this dimension
}
func FillStateTable2(data planet_data, dims []int, table []State,
-fuel_remaining, edens_remaining int, planet string, barrier chan<- bool) {
- addr := make([]int, len(dims))
- addr[Edens] = edens_remaining
- addr[Fuel] = fuel_remaining
- addr[Location] = data.p2i[planet]
+addr []int, barrier chan<- bool) {
FillStateTable2Iteration(data, dims, table, addr, FillCellByArriving)
FillStateTable2Iteration(data, dims, table, addr, FillCellBySelling)
FillStateTable2Iteration(data, dims, table, addr, FillCellByBuying)
work_done := 0.0
for fuel_remaining := *fuel; fuel_remaining >= 0; fuel_remaining-- {
for edens_remaining := eden_capacity; edens_remaining >= 0; edens_remaining-- {
+ /* Do the brunt of the work */
for planet := range data.Planets {
- go FillStateTable2(data, dims, table, fuel_remaining,
- edens_remaining, planet, barrier)
+ addr := make([]int, len(dims))
+ addr[Edens] = edens_remaining
+ addr[Fuel] = fuel_remaining
+ addr[Location] = data.p2i[planet]
+ go FillStateTable2(data, dims, table, addr, barrier)
}
for _ = range data.Planets {
<-barrier
work_done++
print(fmt.Sprintf("\r%3.0f%%", 100*work_done/work_units))
}
+ /* Make an Eden-buying pass (uphill) */
+ addr := make([]int, len(dims))
+ addr[Fuel] = fuel_remaining
+ for addr[Edens] = 0; addr[Edens] <= eden_capacity; addr[Edens]++ {
+ for planet := range data.Planets {
+ addr[Location] = data.p2i[planet]
+ FillStateTable2Iteration(data, dims, table, addr, FillCellByBuyingEdens)
+ }
+ }
}
print("\n")
}
func DescribePath(data planet_data, dims []int, table []State, start int) (description []string) {
for index := start; index > 0 && table[index].from > 0; index = table[index].from {
- line := fmt.Sprintf("%13v", Commas(table[index].value))
+ var line string
addr := DecodeIndex(dims, index)
prev := DecodeIndex(dims, table[index].from)
- if addr[Location] != prev[Location] {
+ if addr[Fuel] != prev[Fuel] {
from := data.i2p[prev[Location]]
to := data.i2p[addr[Location]]
- if addr[Fuel] != prev[Fuel] {
- line += fmt.Sprintf(" Jump from %v to %v (%v reactor units)", from, to, prev[Fuel]-addr[Fuel])
- } else if addr[Edens] != prev[Edens] {
- line += fmt.Sprintf(" Eden warp from %v to %v", from, to)
- } else {
- panic("Traveling without fuel?")
- }
+ line += fmt.Sprintf("Jump from %v to %v (%v reactor units)", from, to, prev[Fuel]-addr[Fuel])
+ }
+ if addr[Edens] == prev[Edens] - 1 {
+ from := data.i2p[prev[Location]]
+ to := data.i2p[addr[Location]]
+ line += fmt.Sprintf("Eden warp from %v to %v", from, to)
}
if addr[Hold] != prev[Hold] {
if addr[Hold] == 0 {
quantity := *hold - (prev[UnusedCargo] + prev[Edens] + prev[Cloaks])
- line += fmt.Sprintf(" Sell %v %v", quantity, data.i2c[prev[Hold]])
+ line += fmt.Sprintf("Sell %v %v", quantity, data.i2c[prev[Hold]])
} else if prev[Hold] == 0 {
quantity := *hold - (addr[UnusedCargo] + addr[Edens] + addr[Cloaks])
- line += fmt.Sprintf(" Buy %v %v", quantity, data.i2c[addr[Hold]])
+ line += fmt.Sprintf("Buy %v %v", quantity, data.i2c[addr[Hold]])
} else {
panic("Switched cargo?")
}
}
if addr[Cloaks] == 1 && prev[Cloaks] == 0 {
// TODO: Dump cloaks, convert from cargo?
- line += " Buy a Cloak"
+ line += "Buy a Cloak"
+ }
+ if addr[Edens] > prev[Edens] {
+ line += fmt.Sprint("Buy ", addr[Edens] - prev[Edens], " Eden Warp Units")
+ }
+ if line == "" {
+ line = fmt.Sprint(prev, " -> ", addr)
}
- description = append(description, line)
+ description = append(description, fmt.Sprintf("%13v ", Commas(table[index].value)) + line)
}
return
}