Compare commits

..

2 commits

2 changed files with 99 additions and 42 deletions

View file

@ -0,0 +1,71 @@
package trainer
import (
"fmt"
"maps"
"codeflow.dananglin.me.uk/apollo/pokedex/internal/api/pokeapi"
)
type Trainer struct {
previousLocationArea *string
nextLocationArea *string
currentLocationAreaID int
pokedex map[string]pokeapi.Pokemon
}
func NewTrainer() *Trainer {
trainer := Trainer{
previousLocationArea: nil,
nextLocationArea: nil,
currentLocationAreaID: 0,
pokedex: make(map[string]pokeapi.Pokemon),
}
return &trainer
}
func (t *Trainer) UpdateLocationAreas(previous, next *string) {
t.previousLocationArea = previous
t.nextLocationArea = next
}
func (t *Trainer) PreviousLocationArea() *string {
return t.previousLocationArea
}
func (t *Trainer) NextLocationArea() *string {
return t.nextLocationArea
}
func (t *Trainer) AddPokemonToPokedex(name string, details pokeapi.Pokemon) {
t.pokedex[name] = details
}
func (t *Trainer) GetPokemonFromPokedex(name string) (pokeapi.Pokemon, bool) {
details, ok := t.pokedex[name]
return details, ok
}
func (t *Trainer) ListAllPokemonFromPokedex() {
if len(t.pokedex) == 0 {
fmt.Println("You have no Pokemon in your Pokedex.")
return
}
fmt.Println("Your Pokedex:")
for name := range maps.All(t.pokedex) {
fmt.Println(" -", name)
}
}
func (t *Trainer) CurrentLocationAreaID() int {
return t.currentLocationAreaID
}
func (t *Trainer) UpdateCurrentLocationAreaID(locationAreaID int) {
t.currentLocationAreaID = locationAreaID
}

70
main.go
View file

@ -11,15 +11,10 @@ import (
"strings" "strings"
"time" "time"
"codeflow.dananglin.me.uk/apollo/pokedex/internal/api/pokeapi"
"codeflow.dananglin.me.uk/apollo/pokedex/internal/pokeclient" "codeflow.dananglin.me.uk/apollo/pokedex/internal/pokeclient"
"codeflow.dananglin.me.uk/apollo/pokedex/internal/trainer"
) )
type State struct {
Previous *string
Next *string
}
type command struct { type command struct {
name string name string
description string description string
@ -28,10 +23,6 @@ type command struct {
type callbackFunc func(args []string) error type callbackFunc func(args []string) error
type pokedex map[string]pokeapi.Pokemon
var dexter = make(pokedex)
func main() { func main() {
run() run()
} }
@ -42,7 +33,7 @@ func run() {
10*time.Second, 10*time.Second,
) )
var state State trainer := trainer.NewTrainer()
commandMap := map[string]command{ commandMap := map[string]command{
"exit": { "exit": {
@ -58,12 +49,12 @@ func run() {
"map": { "map": {
name: "map", name: "map",
description: "Displays the next 20 locations in the Pokemon world", description: "Displays the next 20 locations in the Pokemon world",
callback: mapFunc(client, &state), callback: mapFunc(client, trainer),
}, },
"mapb": { "mapb": {
name: "map back", name: "map back",
description: "Displays the previous 20 locations in the Pokemon world", description: "Displays the previous 20 locations in the Pokemon world",
callback: mapBFunc(client, &state), callback: mapBFunc(client, trainer),
}, },
"explore": { "explore": {
name: "explore", name: "explore",
@ -73,17 +64,17 @@ func run() {
"catch": { "catch": {
name: "catch", name: "catch",
description: "Catches a Pokemon and adds them to your Pokedex", description: "Catches a Pokemon and adds them to your Pokedex",
callback: catchFunc(client), callback: catchFunc(client, trainer),
}, },
"inspect": { "inspect": {
name: "inspect", name: "inspect",
description: "Inspects a Pokemon from your Pokedex", description: "Inspects a Pokemon from your Pokedex",
callback: inspectFunc(), callback: inspectFunc(trainer),
}, },
"pokedex": { "pokedex": {
name: "pokedex", name: "pokedex",
description: "Lists the names of all the Pokemon in your Pokedex", description: "Lists the names of all the Pokemon in your Pokedex",
callback: pokedexFunc(), callback: pokedexFunc(trainer),
}, },
} }
@ -158,26 +149,26 @@ func exitFunc(_ []string) error {
return nil return nil
} }
func mapFunc(client *pokeclient.Client, state *State) callbackFunc { func mapFunc(client *pokeclient.Client, trainer *trainer.Trainer) callbackFunc {
return func(_ []string) error { return func(_ []string) error {
url := state.Next url := trainer.NextLocationArea()
if url == nil { if url == nil {
url = new(string) url = new(string)
*url = pokeclient.LocationAreaPath *url = pokeclient.LocationAreaPath
} }
return printResourceList(client, *url, state) return printResourceList(client, *url, trainer.UpdateLocationAreas)
} }
} }
func mapBFunc(client *pokeclient.Client, state *State) callbackFunc { func mapBFunc(client *pokeclient.Client, trainer *trainer.Trainer) callbackFunc {
return func(_ []string) error { return func(_ []string) error {
url := state.Previous url := trainer.PreviousLocationArea()
if url == nil { if url == nil {
return fmt.Errorf("no previous locations available") return fmt.Errorf("no previous locations available")
} }
return printResourceList(client, *url, state) return printResourceList(client, *url, trainer.UpdateLocationAreas)
} }
} }
@ -216,7 +207,7 @@ func exploreFunc(client *pokeclient.Client) callbackFunc {
} }
} }
func catchFunc(client *pokeclient.Client) callbackFunc { func catchFunc(client *pokeclient.Client, trainer *trainer.Trainer) callbackFunc {
return func(args []string) error { return func(args []string) error {
if args == nil { if args == nil {
return errors.New("the name of the Pokemon has not been specified") return errors.New("the name of the Pokemon has not been specified")
@ -233,7 +224,7 @@ func catchFunc(client *pokeclient.Client) callbackFunc {
fmt.Printf("Throwing a Pokeball at %s...\n", pokemonName) fmt.Printf("Throwing a Pokeball at %s...\n", pokemonName)
pokemon, err := client.GetPokemon(pokemonName) pokemonDetails, err := client.GetPokemon(pokemonName)
if err != nil { if err != nil {
return fmt.Errorf( return fmt.Errorf(
"unable to get the information on %s: %w", "unable to get the information on %s: %w",
@ -245,7 +236,7 @@ func catchFunc(client *pokeclient.Client) callbackFunc {
chance := 50 chance := 50
if caught := catchPokemon(chance); caught { if caught := catchPokemon(chance); caught {
dexter[pokemonName] = pokemon trainer.AddPokemonToPokedex(pokemonName, pokemonDetails)
fmt.Printf("%s was caught!\nYou may now inspect it with the inspect command.\n", pokemonName) fmt.Printf("%s was caught!\nYou may now inspect it with the inspect command.\n", pokemonName)
} else { } else {
fmt.Printf("%s escaped!\n", pokemonName) fmt.Printf("%s escaped!\n", pokemonName)
@ -255,7 +246,7 @@ func catchFunc(client *pokeclient.Client) callbackFunc {
} }
} }
func inspectFunc() callbackFunc { func inspectFunc(trainer *trainer.Trainer) callbackFunc {
return func(args []string) error { return func(args []string) error {
if args == nil { if args == nil {
return errors.New("the name of the Pokemon has not been specified") return errors.New("the name of the Pokemon has not been specified")
@ -270,7 +261,7 @@ func inspectFunc() callbackFunc {
pokemonName := args[0] pokemonName := args[0]
pokemon, ok := dexter[pokemonName] pokemon, ok := trainer.GetPokemonFromPokedex(pokemonName)
if !ok { if !ok {
return fmt.Errorf("you have not caught %s", pokemonName) return fmt.Errorf("you have not caught %s", pokemonName)
} }
@ -302,32 +293,27 @@ func inspectFunc() callbackFunc {
} }
} }
func pokedexFunc() callbackFunc { func pokedexFunc(trainer *trainer.Trainer) callbackFunc {
return func(_ []string) error { return func(_ []string) error {
if len(dexter) == 0 { trainer.ListAllPokemonFromPokedex()
fmt.Println("You have no Pokemon in your Pokedex")
return nil
}
fmt.Println("Your Pokedex:")
for name := range maps.All(dexter) {
fmt.Println(" -", name)
}
return nil return nil
} }
} }
func printResourceList(client *pokeclient.Client, url string, state *State) error { func printResourceList(
client *pokeclient.Client,
url string,
updateStateFunc func(previous *string, next *string),
) error {
list, err := client.GetNamedAPIResourceList(url) list, err := client.GetNamedAPIResourceList(url)
if err != nil { if err != nil {
return fmt.Errorf("unable to get the list of resources: %w", err) return fmt.Errorf("unable to get the list of resources: %w", err)
} }
state.Next = list.Next if updateStateFunc != nil {
state.Previous = list.Previous updateStateFunc(list.Previous, list.Next)
}
for _, location := range slices.All(list.Results) { for _, location := range slices.All(list.Results) {
fmt.Println(location.Name) fmt.Println(location.Name)