+var cell_filled_count int
+
+func CellValue(data planet_data, dims []int, table []State, addr []int) int32 {
+ my_index := EncodeIndex(dims, addr)
+ if table[my_index].value == VALUE_BEING_EVALUATED {
+ panic("Circular dependency")
+ }
+ if table[my_index].value != VALUE_UNINITIALIZED {
+ return table[my_index].value
+ }
+ table[my_index].value = VALUE_BEING_EVALUATED
+
+ best_value := int32(VALUE_RUBISH)
+ best_source := make([]int, NumDimensions)
+ other := make([]int, NumDimensions)
+ copy(other, addr)
+ planet := data.i2p[addr[Location]]
+
+ /* Travel here */
+ if addr[Traded] == 0 { /* Can't have traded immediately after traveling. */
+ other[Traded] = 1 /* Travel from states that have done trading. */
+
+ /* Travel here via a 2-fuel unit jump */
+ if addr[Fuel]+2 < dims[Fuel] {
+ other[Fuel] = addr[Fuel] + 2
+ hole_index := (dims[Fuel] - 1) - (addr[Fuel] + 2)
+ if hole_index >= len(flight_plan()) || addr[Location] != data.p2i[flight_plan()[hole_index]] {
+ for other[Location] = 0; other[Location] < dims[Location]; other[Location]++ {
+ if data.Planets[data.i2p[addr[Location]]].BeaconOn {
+ Consider(data, dims, table, other, 0, &best_value, best_source)
+ }
+ }
+ }
+ other[Location] = addr[Location]
+ other[Fuel] = addr[Fuel]
+ }
+
+ /* Travel here via a 1-fuel unit jump (a hyper hole) */
+ if addr[Fuel]+1 < dims[Fuel] {
+ hole_index := (dims[Fuel] - 1) - (addr[Fuel] + 1)
+ if hole_index < len(flight_plan()) && addr[Location] == data.p2i[flight_plan()[hole_index]] {
+ other[Fuel] = addr[Fuel] + 1
+ for other[Location] = 0; other[Location] < dims[Location]; other[Location]++ {
+ Consider(data, dims, table, other, 0, &best_value, best_source)
+ }
+ other[Location] = addr[Location]
+ other[Fuel] = addr[Fuel]
+ }
+ }
+
+ /* Travel here via Eden Warp Unit */
+ if addr[Edens]+1 < dims[Edens] && addr[UnusedCargo] > 0 {
+ _, available := data.Planets[data.i2p[addr[Location]]].RelativePrices["Eden Warp Units"]
+ if !available {
+ other[Edens] = addr[Edens] + 1
+ if other[Hold] != 0 {
+ other[UnusedCargo] = addr[UnusedCargo] - 1
+ }
+ for other[Location] = 0; other[Location] < dims[Location]; other[Location]++ {
+ Consider(data, dims, table, other, 0, &best_value, best_source)
+ }
+ other[Location] = addr[Location]
+ other[UnusedCargo] = addr[UnusedCargo]
+ other[Edens] = addr[Edens]
+ }
+ }
+ other[Traded] = addr[Traded]
+ }
+
+ /* Trade */
+ if addr[Traded] == 1 {
+ other[Traded] = 0
+
+ /* Consider not trading */
+ Consider(data, dims, table, other, 0, &best_value, best_source)
+
+ if !data.Planets[data.i2p[addr[Location]]].Private {
+
+ /* Sell */
+ if addr[Hold] == 0 && addr[UnusedCargo] == 0 {
+ for other[Hold] = 0; other[Hold] < dims[Hold]; other[Hold]++ {
+ commodity := data.i2c[other[Hold]]
+ if !data.Commodities[commodity].CanSell {
+ continue
+ }
+ relative_price, available := data.Planets[planet].RelativePrices[commodity]
+ if !available {
+ // TODO: Dump cargo
+ continue
+ }
+ base_price := data.Commodities[commodity].BasePrice
+ absolute_price := float64(base_price) * float64(relative_price) / 100.0
+ sell_price := int(absolute_price * 0.9)
+
+ for other[UnusedCargo] = 0; other[UnusedCargo] < dims[UnusedCargo]; other[UnusedCargo]++ {
+ quantity := *hold - (other[UnusedCargo] + other[Cloaks] + other[Edens])
+ sale_value := quantity * sell_price
+ Consider(data, dims, table, other, sale_value, &best_value, best_source)
+ }
+ }
+ other[UnusedCargo] = addr[UnusedCargo]
+ other[Hold] = addr[Hold]
+ }
+
+ /* Buy */
+ other[Traded] = addr[Traded] /* Buy after selling */
+ if addr[Hold] != 0 {
+ commodity := data.i2c[addr[Hold]]
+ if data.Commodities[commodity].CanSell {
+ relative_price, available := data.Planets[planet].RelativePrices[commodity]
+ if available {
+ base_price := data.Commodities[commodity].BasePrice
+ absolute_price := int(float64(base_price) * float64(relative_price) / 100.0)
+ quantity := *hold - (addr[UnusedCargo] + addr[Cloaks] + addr[Edens])
+ total_price := quantity * absolute_price
+ other[Hold] = 0
+ other[UnusedCargo] = 0
+ Consider(data, dims, table, other, -total_price, &best_value, best_source)
+ other[UnusedCargo] = addr[UnusedCargo]
+ other[Hold] = addr[Hold]
+ }
+ }
+ }
+ }
+ other[Traded] = addr[Traded]
+ }
+
+ /* 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"]
+ if available {
+ absolute_price := int(float64(data.Commodities["Device Of Cloakings"].BasePrice) * float64(relative_price) / 100.0)
+ other[Cloaks] = 0
+ if other[Hold] != 0 {
+ other[UnusedCargo] = addr[UnusedCargo] + 1