+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")
+ }
+ return dims
+}
+
+func StateTableSize(dims []int) int {
+ sum := 0
+ for _, size := range dims {
+ sum += size
+ }
+ return sum
+}
+
+type State struct {
+ funds, from int
+}
+
+func NewStateTable(dims []int) []State {
+ return make([]State, StateTableSize(dims))
+}
+
+func EncodeIndex(dims, addr []int) int {
+ index := addr[0]
+ for i := 1; i < len(dims); i++ {
+ index = index*dims[i] + addr[i]
+ }
+ return index
+}
+
+func DecodeIndex(dims []int, index int) []int {
+ addr := make([]int, len(dims))
+ for i := len(dims) - 1; i > 0; i-- {
+ addr[i] = index % dims[i]
+ index /= dims[i]
+ }
+ addr[0] = index
+ return addr
+}
+
+/* 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 {
+ if !data.Commodities[commodity].CanSell {
+ return 0
+ }
+ from_relative_price, from_available := from.RelativePrices[commodity]