Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Character Gathering Decisions #13

Merged
merged 2 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions cmd/engine/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,29 @@ func init() {
}
}

const (
configFlag = "config"
tokenFlag = "token"
characterFlag = "character"
)

func main() {
slog.Info("starting artifacts-mmo game engine")
var config = flag.String("config", "", "path to config file")
config := flag.String(configFlag, "", "path to config file")
_ = flag.String(tokenFlag, "", "API token")
_ = flag.String(characterFlag, "", "character name")
flag.Parse()

err := initViper(*config)
if err != nil {
log.Fatal(err)
}

err = bindFlags([]string{configFlag, tokenFlag, characterFlag})
if err != nil {
log.Fatal(err)
}

v := viper.GetViper()

r, err := actions.NewDefaultRunner(v.GetString("token"))
Expand All @@ -41,20 +54,30 @@ func main() {
}

ctx := context.Background()
character := v.GetString("character")
c := v.GetString(characterFlag)

err = blockInitialAction(ctx, r, character)
err = blockInitialAction(ctx, r, c)
if err != nil {
log.Fatal(err)
}

slog.Info("starting BuildInventory engine")
err = engine.BuildInventory(ctx, r, character)
err = engine.BuildInventory(ctx, r, c)
if err != nil {
log.Fatal(err)
}
}

func bindFlags(flags []string) error {
for _, f := range flags {
err := viper.BindPFlag(f, flag.Lookup(f))
if err != nil {
return fmt.Errorf("failed to bind flag: %w", err)
}
}
return nil
}

func blockInitialAction(ctx context.Context, r *actions.Runner, character string) error {
c, err := r.GetMyCharacterInfo(ctx, character)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
)

require (
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.5.0 // indirect
Expand All @@ -20,6 +22,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oapi-codegen/runtime v1.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
Expand Down
10 changes: 9 additions & 1 deletion internal/actions/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,15 @@ func (r *Runner) GetMonsters(ctx context.Context, min, max int) (models.Monsters
return monsters, nil
}

func (r *Runner) GetResources(ctx context.Context, skill string, min, max int) (models.Resources, error) {
func (r *Runner) GetResources(ctx context.Context, skill client.ResourceSchemaSkill, min, max int) (models.Resources, error) {
if min < 0 {
min = 0
}

if max < 0 {
max = 0
}

s := client.GetAllResourcesResourcesGetParamsSkill(skill)

resp, err := r.Client.GetAllResourcesResourcesGetWithResponse(ctx, &client.GetAllResourcesResourcesGetParams{
Expand Down
2 changes: 1 addition & 1 deletion internal/engine/decision.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func BuildInventory(ctx context.Context, r *actions.Runner, character string) er
return fmt.Errorf("get character info: %w", err)
}

ctx, cancel := context.WithCancel(context.Background())
ctx, cancel := context.WithCancel(ctx)
defer cancel()

currentIndex := 1
Expand Down
6 changes: 3 additions & 3 deletions internal/engine/gather.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ func Gather(ctx context.Context, r *actions.Runner, character string) error {
return err
}

// it's in 10s, so we don't want to go lower than the band
minLevel := c.WoodcuttingLevel - 10
resourceInfo, err := r.GetResources(ctx, string(client.Woodcutting), minLevel, c.WoodcuttingLevel)
skill := c.ChooseWeakestSkill()
resourceInfo, err := r.GetResources(ctx, skill.Code, skill.MinLevel, skill.CurrentLevel)
if err != nil {
slog.Error("failed to get resources", "error", err)
return err
Expand All @@ -39,6 +38,7 @@ func Gather(ctx context.Context, r *actions.Runner, character string) error {
loc := models.LocationsToMap(resourceLoations)
res := models.ResourcesToMap(resourceInfo)
// TODO there are more than one resource available, we should move to the one closet to the bank
// implement with manhattan distance
res.FindResources(loc)

resources := res.ToSlice()
Expand Down
8 changes: 8 additions & 0 deletions internal/math/simple.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package math

func Max(x, y int) int {
if x < y {
return y
}
return x
}
27 changes: 27 additions & 0 deletions internal/math/simple_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package math

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
)

func TestMax(t *testing.T) {
tests := []struct {
a int
b int
expected int
}{
{0, 1, 1},
{0, -1, 0},
{0, 10, 10},
}

for _, tt := range tests {
t.Run(fmt.Sprintf("%d,%d", tt.a, tt.b), func(t *testing.T) {
res := Max(tt.a, tt.b)
assert.Equal(t, tt.expected, res)
})
}
}
38 changes: 37 additions & 1 deletion internal/models/character.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package models

import (
"cmp"
"fmt"
"log/slog"
"slices"
"time"

"github.com/promiseofcake/artifactsmmo-go-client/client"

"github.com/promiseofcake/artifactsmmo-engine/internal/math"
)

// Character is our representation of the Player's character
Expand All @@ -24,6 +28,38 @@ func (c Character) CountInventory() int {
return count
}

type CharacterSkill struct {
Code client.ResourceSchemaSkill
CurrentLevel int
MinLevel int
}

func (c Character) ChooseWeakestSkill() CharacterSkill {
skills := []CharacterSkill{
{
Code: client.ResourceSchemaSkillWoodcutting,
CurrentLevel: c.WoodcuttingLevel,
MinLevel: math.Max(0, c.WoodcuttingLevel-10),
},
{
Code: client.ResourceSchemaSkillMining,
CurrentLevel: c.MiningLevel,
MinLevel: math.Max(0, c.MiningLevel-10),
},
{
Code: client.ResourceSchemaSkillFishing,
CurrentLevel: c.FishingLevel,
MinLevel: math.Max(0, c.FishingLevel-10),
},
}

slices.SortFunc(skills, func(a, b CharacterSkill) int {
return cmp.Compare(a.CurrentLevel, b.CurrentLevel)
})

return skills[0]
}

// GetCooldownDuration returns the time.Duration remaining on the character for cooldown
func (c Character) GetCooldownDuration() (time.Duration, error) {
t, err := c.CooldownExpiration.AsCharacterSchemaCooldownExpiration0()
Expand All @@ -46,7 +82,7 @@ func (c Character) GetPosition() Coords {
func (c Character) ShouldBank() bool {
percentFull := float64(c.CountInventory()) / float64(c.InventoryMaxItems)
result := []any{"percent_full", percentFull}
if percentFull > 0.7 {
if percentFull > 0.9 {
slog.Debug("Character should bank", result...)
return true
} else {
Expand Down
8 changes: 8 additions & 0 deletions internal/models/map.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package models

import "math"

// Coords defines X, Y map coordinates as signed integers
type Coords struct {
X int
Y int
}

// CalculateDistance determines the number of moves (distance) to get
// from one Coords to a second Coords using the Manhattan distance forumla
func CalculateDistance(one, two Coords) int {
return int(math.Abs(float64(one.X-two.X)) + math.Abs(float64(one.Y-two.Y)))
}
27 changes: 27 additions & 0 deletions internal/models/map_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package models

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
)

func TestCalculateDistance(t *testing.T) {
tests := []struct {
one Coords
two Coords
expected int
}{
{Coords{0, 0}, Coords{0, 0}, 0},
{Coords{1, 1}, Coords{0, 0}, 2},
{Coords{-5, 1}, Coords{0, 0}, 6},
}

for n, tt := range tests {
t.Run(fmt.Sprintf("%d", n), func(t *testing.T) {
res := CalculateDistance(tt.one, tt.two)
assert.Equal(t, tt.expected, res)
})
}
}
8 changes: 4 additions & 4 deletions internal/models/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ func resourcePK(resource Resource) string {
}

func ResourcesToMap(resources Resources) ResourceMap {
monsterMap := make(ResourceMap)
for _, m := range resources {
monsterMap[resourcePK(m)] = &m
resourceMap := make(ResourceMap)
for _, r := range resources {
resourceMap[resourcePK(r)] = &r
}
return monsterMap
return resourceMap
}

func (r ResourceMap) FindResources(l LocationMap) {
Expand Down
Loading