]> git.scottworley.com Git - planeteer/blobdiff - planeteer.go
Implement Eden buying
[planeteer] / planeteer.go
index 9ff2de79976d0f4ef565ff3009c3d59ac50450f1..40d19dd700c6b9dc4187ed32869c35555f220216 100644 (file)
@@ -77,7 +77,7 @@ func end() map[string]bool {
                return nil
        }
        m := make(map[string]bool)
-       for _, p := range strings.Split(*flight_plan_string, ",") {
+       for _, p := range strings.Split(*end_string, ",") {
                m[p] = true
        }
        return m
@@ -300,13 +300,17 @@ func FillCellByArriving(data planet_data, dims []int, table []State, addr []int)
        }
 
        /* Travel here via Eden Warp Unit */
-       for other[Edens] = addr[Edens] + 1; other[Edens] < dims[Edens]; other[Edens]++ {
-               for other[Location] = 0; other[Location] < dims[Location]; other[Location]++ {
-                       UpdateCell(table, my_index, EncodeIndex(dims, other), 0)
+       if addr[Edens]+1 < dims[Edens] {
+               _, available := data.Planets[data.i2p[addr[Location]]].RelativePrices["Eden Warp Units"]
+               if !available {
+                       other[Edens] = addr[Edens] + 1
+                       for other[Location] = 0; other[Location] < dims[Location]; other[Location]++ {
+                               UpdateCell(table, my_index, EncodeIndex(dims, other), 0)
+                       }
+                       other[Location] = addr[Location]
+                       other[Edens] = addr[Edens]
                }
        }
-       other[Location] = addr[Location]
-       other[Edens] = addr[Edens]
 }
 
 func FillCellBySelling(data planet_data, dims []int, table []State, addr []int) {
@@ -378,7 +382,7 @@ func FillCellByMisc(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 */
+
        /* 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"]
@@ -399,6 +403,32 @@ func FillCellByMisc(data planet_data, dims []int, table []State, addr []int) {
        /* 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
@@ -419,11 +449,7 @@ addr []int, f func(planet_data, []int, []State, []int)) {
 }
 
 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)
@@ -455,9 +481,13 @@ func FillStateTable1(data planet_data, dims []int, table []State) {
        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
@@ -465,6 +495,15 @@ func FillStateTable1(data planet_data, dims []int, table []State) {
                        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")
 }
@@ -480,10 +519,12 @@ func FindBestState(data planet_data, dims []int, table []State) int {
        max_index := -1
        max_value := 0
        for addr[Location] = 0; addr[Location] < dims[Location]; addr[Location]++ {
-               index := EncodeIndex(dims, addr)
-               if table[index].value > max_value {
-                       max_value = table[index].value
-                       max_index = index
+               if len(end()) == 0 || end()[data.i2p[addr[Location]]] {
+                       index := EncodeIndex(dims, addr)
+                       if table[index].value > max_value {
+                               max_value = table[index].value
+                               max_index = index
+                       }
                }
        }
        return max_index
@@ -503,27 +544,26 @@ func Commas(n int) (s string) {
 
 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?")
                        }
@@ -531,9 +571,15 @@ func DescribePath(data planet_data, dims []int, table []State, start int) (descr
                }
                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
 }