X-Git-Url: http://git.scottworley.com/planeteer/blobdiff_plain/e7e4bc13603972237c4d2979a60739f0764391be..544108c4d2c99c98bdf7566a23e5996127c8fe8e:/planeteer.go diff --git a/planeteer.go b/planeteer.go index 456e6b3..c6a309c 100644 --- a/planeteer.go +++ b/planeteer.go @@ -26,6 +26,9 @@ import "strings" var start = flag.String("start", "", "The planet to start at") +var flight_plan = flag.String("flight_plan", "", + "Your hidey-holes for the day, comma-separated.") + var end = flag.String("end", "", "A comma-separated list of acceptable ending planets.") @@ -171,7 +174,7 @@ func StateTableSize(dims []int) int { } type State struct { - funds, from int + value, from int } func EncodeIndex(dims, addr []int) int { @@ -192,7 +195,35 @@ func DecodeIndex(dims []int, index int) []int { return addr } -func FillStateCell(data planet_data, dims []int, table []State, addr []int) { +/* Fill in the cell at address addr by looking at all the possible ways + * to reach this cell and selecting the best one. + * + * The other obvious implementation choice is to do this the other way + * around -- for each cell, conditionally overwrite all the other cells + * that are reachable *from* the considered cell. We choose gathering + * reads over scattering writes to avoid having to take a bunch of locks. + * + * The order that we check things here matters only for value ties. We + * keep the first best path. So when action order doesn't matter, the + * check that is performed first here will appear in the output first. + */ +func FillStateTableCell(data planet_data, dims []int, table []State, addr []int) { + /* Travel here via jumping */ + /* Travel here via Eden Warp Unit */ + /* Silly: Dump Eden warp units */ + /* Buy Eden warp units */ + /* Buy a Device of Cloaking */ + /* Silly: Dump a Device of Cloaking */ + /* Buy Fighter Drones */ + /* Buy Shield Batteries */ + if addr[Hold] == 0 { + /* Sell or dump things */ + for commodity := range data.Commodities { + } + } else { + /* Buy this thing */ + } + /* Visit this planet */ } func FillStateTable2(data planet_data, dims []int, table []State, @@ -216,21 +247,13 @@ fuel_remaining, edens_remaining int, planet string, barrier chan<- bool) { addr[Location] = data.p2i[planet] for addr[Hold] = 0; addr[Hold] < dims[Hold]; addr[Hold]++ { for addr[Cloaks] = 0; addr[Cloaks] < dims[Cloaks]; addr[Cloaks]++ { - for addr[UnusedCargo] = 0; - addr[UnusedCargo] < dims[UnusedCargo]; - addr[UnusedCargo]++ { - if addr[Edens] + addr[Cloaks] + addr[UnusedCargo] <= - eden_capacity + 1 { - for addr[NeedFighters] = 0; - addr[NeedFighters] < dims[NeedFighters]; - addr[NeedFighters]++ { - for addr[NeedShields] = 0; - addr[NeedShields] < dims[NeedShields]; - addr[NeedShields]++ { - for addr[Visit] = 0; - addr[Visit] < dims[Visit]; - addr[Visit]++ { - FillStateCell(data, dims, table, addr) + for addr[UnusedCargo] = 0; addr[UnusedCargo] < dims[UnusedCargo]; addr[UnusedCargo]++ { + if addr[Edens]+addr[Cloaks]+addr[UnusedCargo] <= + eden_capacity+1 { + for addr[NeedFighters] = 0; addr[NeedFighters] < dims[NeedFighters]; addr[NeedFighters]++ { + for addr[NeedShields] = 0; addr[NeedShields] < dims[NeedShields]; addr[NeedShields]++ { + for addr[Visit] = 0; addr[Visit] < dims[Visit]; addr[Visit]++ { + FillStateTableCell(data, dims, table, addr) } } } @@ -265,9 +288,7 @@ func FillStateTable1(data planet_data, dims []int) []State { work_units := (float64(*fuel) + 1) * (float64(eden_capacity) + 1) work_done := 0.0 for fuel_remaining := *fuel; fuel_remaining >= 0; fuel_remaining-- { - for edens_remaining := eden_capacity; - edens_remaining >= 0; - edens_remaining-- { + for edens_remaining := eden_capacity; edens_remaining >= 0; edens_remaining-- { for planet := range data.Planets { go FillStateTable2(data, dims, table, fuel_remaining, edens_remaining, planet, barrier) @@ -276,7 +297,7 @@ func FillStateTable1(data planet_data, dims []int) []State { <-barrier } work_done++ - fmt.Printf("\r%3.0f%%", 100 * work_done / work_units) + fmt.Printf("\r%3.0f%%", 100*work_done/work_units) } } return table @@ -343,8 +364,8 @@ func FindBestTrades(data planet_data) [][]string { // (Example of a use case for generics in Go) func IndexPlanets(m *map[string]Planet, start_at int) (map[string]int, []string) { - e2i := make(map[string]int, len(*m) + start_at) - i2e := make([]string, len(*m) + start_at) + e2i := make(map[string]int, len(*m)+start_at) + i2e := make([]string, len(*m)+start_at) i := start_at for e := range *m { e2i[e] = i @@ -354,8 +375,8 @@ func IndexPlanets(m *map[string]Planet, start_at int) (map[string]int, []string) return e2i, i2e } func IndexCommodities(m *map[string]Commodity, start_at int) (map[string]int, []string) { - e2i := make(map[string]int, len(*m) + start_at) - i2e := make([]string, len(*m) + start_at) + e2i := make(map[string]int, len(*m)+start_at) + i2e := make([]string, len(*m)+start_at) i := start_at for e := range *m { e2i[e] = i