diff --git a/main.go b/main.go index 8966c06..4ddb92e 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "github.com/rdarius/boot-dev-pokedex/pokeapi" + "math/rand" "os" "strings" "time" @@ -14,6 +15,7 @@ type config struct { pokeapiClient pokeapi.Client nextLocationsURL *string prevLocationsURL *string + caughtPokemon map[string]pokeapi.Pokemon } type cliCommand struct { @@ -28,6 +30,7 @@ func main() { pokeClient := pokeapi.NewClient(5*time.Second, time.Minute*5) cfg := &config{ + caughtPokemon: map[string]pokeapi.Pokemon{}, pokeapiClient: pokeClient, } @@ -57,6 +60,11 @@ func main() { description: "Get the previous page of locations", callback: commandMapb, }, + "catch": { + name: "catch ", + description: "Attempt to catch a pokemon", + callback: commandCatch, + }, } for { // read user input @@ -70,7 +78,6 @@ func main() { if len(cleanedWord) > 1 { args = cleanedWord[1:] } - //check if command is in commands map cmd, ok := commands[command] if ok { err := cmd.callback(cfg, args...) @@ -156,3 +163,28 @@ func commandExplore(cfg *config, args ...string) error { } return nil } + +func commandCatch(cfg *config, args ...string) error { + if len(args) != 1 { + return errors.New("you must provide a pokemon name") + } + + name := args[0] + pokemon, err := cfg.pokeapiClient.GetPokemon(name) + if err != nil { + return err + } + + res := rand.Intn(pokemon.BaseExperience) + + fmt.Printf("Throwing a Pokeball at %s...\n", pokemon.Name) + if res > 40 { + fmt.Printf("%s escaped!\n", pokemon.Name) + return nil + } + + fmt.Printf("%s was caught!\n", pokemon.Name) + + cfg.caughtPokemon[pokemon.Name] = pokemon + return nil +} diff --git a/pokeapi/pokemon_get.go b/pokeapi/pokemon_get.go new file mode 100644 index 0000000..9a3ce26 --- /dev/null +++ b/pokeapi/pokemon_get.go @@ -0,0 +1,49 @@ +package pokeapi + +import ( + "encoding/json" + "io" + "net/http" +) + +// GetPokemon - +func (c *Client) GetPokemon(pokemonName string) (Pokemon, error) { + url := baseURL + "/pokemon/" + pokemonName + + if val, ok := c.cache.Get(url); ok { + pokemonResp := Pokemon{} + err := json.Unmarshal(val, &pokemonResp) + if err != nil { + return Pokemon{}, err + } + return pokemonResp, nil + } + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return Pokemon{}, err + } + + resp, err := c.httpClient.Do(req) + if err != nil { + return Pokemon{}, err + } + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + + dat, err := io.ReadAll(resp.Body) + if err != nil { + return Pokemon{}, err + } + + pokemonResp := Pokemon{} + err = json.Unmarshal(dat, &pokemonResp) + if err != nil { + return Pokemon{}, err + } + + c.cache.Add(url, dat) + + return pokemonResp, nil +} diff --git a/pokeapi/types_pokemon.go b/pokeapi/types_pokemon.go new file mode 100644 index 0000000..da1128c --- /dev/null +++ b/pokeapi/types_pokemon.go @@ -0,0 +1,246 @@ +package pokeapi + +// Pokemon - +type Pokemon struct { + Abilities []struct { + Ability struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"ability"` + IsHidden bool `json:"is_hidden"` + Slot int `json:"slot"` + } `json:"abilities"` + BaseExperience int `json:"base_experience"` + Forms []struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"forms"` + GameIndices []struct { + GameIndex int `json:"game_index"` + Version struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"version"` + } `json:"game_indices"` + Height int `json:"height"` + HeldItems []interface{} `json:"held_items"` + ID int `json:"id"` + IsDefault bool `json:"is_default"` + LocationAreaEncounters string `json:"location_area_encounters"` + Moves []struct { + Move struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"move"` + VersionGroupDetails []struct { + LevelLearnedAt int `json:"level_learned_at"` + MoveLearnMethod struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"move_learn_method"` + VersionGroup struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"version_group"` + } `json:"version_group_details"` + } `json:"moves"` + Name string `json:"name"` + Order int `json:"order"` + PastTypes []interface{} `json:"past_types"` + Species struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"species"` + Sprites struct { + BackDefault string `json:"back_default"` + BackFemale interface{} `json:"back_female"` + BackShiny string `json:"back_shiny"` + BackShinyFemale interface{} `json:"back_shiny_female"` + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + Other struct { + DreamWorld struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + } `json:"dream_world"` + Home struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"home"` + OfficialArtwork struct { + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + } `json:"official-artwork"` + } `json:"other"` + Versions struct { + GenerationI struct { + RedBlue struct { + BackDefault string `json:"back_default"` + BackGray string `json:"back_gray"` + BackTransparent string `json:"back_transparent"` + FrontDefault string `json:"front_default"` + FrontGray string `json:"front_gray"` + FrontTransparent string `json:"front_transparent"` + } `json:"red-blue"` + Yellow struct { + BackDefault string `json:"back_default"` + BackGray string `json:"back_gray"` + BackTransparent string `json:"back_transparent"` + FrontDefault string `json:"front_default"` + FrontGray string `json:"front_gray"` + FrontTransparent string `json:"front_transparent"` + } `json:"yellow"` + } `json:"generation-i"` + GenerationIi struct { + Crystal struct { + BackDefault string `json:"back_default"` + BackShiny string `json:"back_shiny"` + BackShinyTransparent string `json:"back_shiny_transparent"` + BackTransparent string `json:"back_transparent"` + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + FrontShinyTransparent string `json:"front_shiny_transparent"` + FrontTransparent string `json:"front_transparent"` + } `json:"crystal"` + Gold struct { + BackDefault string `json:"back_default"` + BackShiny string `json:"back_shiny"` + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + FrontTransparent string `json:"front_transparent"` + } `json:"gold"` + Silver struct { + BackDefault string `json:"back_default"` + BackShiny string `json:"back_shiny"` + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + FrontTransparent string `json:"front_transparent"` + } `json:"silver"` + } `json:"generation-ii"` + GenerationIii struct { + Emerald struct { + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + } `json:"emerald"` + FireredLeafgreen struct { + BackDefault string `json:"back_default"` + BackShiny string `json:"back_shiny"` + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + } `json:"firered-leafgreen"` + RubySapphire struct { + BackDefault string `json:"back_default"` + BackShiny string `json:"back_shiny"` + FrontDefault string `json:"front_default"` + FrontShiny string `json:"front_shiny"` + } `json:"ruby-sapphire"` + } `json:"generation-iii"` + GenerationIv struct { + DiamondPearl struct { + BackDefault string `json:"back_default"` + BackFemale interface{} `json:"back_female"` + BackShiny string `json:"back_shiny"` + BackShinyFemale interface{} `json:"back_shiny_female"` + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"diamond-pearl"` + HeartgoldSoulsilver struct { + BackDefault string `json:"back_default"` + BackFemale interface{} `json:"back_female"` + BackShiny string `json:"back_shiny"` + BackShinyFemale interface{} `json:"back_shiny_female"` + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"heartgold-soulsilver"` + Platinum struct { + BackDefault string `json:"back_default"` + BackFemale interface{} `json:"back_female"` + BackShiny string `json:"back_shiny"` + BackShinyFemale interface{} `json:"back_shiny_female"` + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"platinum"` + } `json:"generation-iv"` + GenerationV struct { + BlackWhite struct { + Animated struct { + BackDefault string `json:"back_default"` + BackFemale interface{} `json:"back_female"` + BackShiny string `json:"back_shiny"` + BackShinyFemale interface{} `json:"back_shiny_female"` + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"animated"` + BackDefault string `json:"back_default"` + BackFemale interface{} `json:"back_female"` + BackShiny string `json:"back_shiny"` + BackShinyFemale interface{} `json:"back_shiny_female"` + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"black-white"` + } `json:"generation-v"` + GenerationVi struct { + OmegarubyAlphasapphire struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"omegaruby-alphasapphire"` + XY struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"x-y"` + } `json:"generation-vi"` + GenerationVii struct { + Icons struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + } `json:"icons"` + UltraSunUltraMoon struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + FrontShiny string `json:"front_shiny"` + FrontShinyFemale interface{} `json:"front_shiny_female"` + } `json:"ultra-sun-ultra-moon"` + } `json:"generation-vii"` + GenerationViii struct { + Icons struct { + FrontDefault string `json:"front_default"` + FrontFemale interface{} `json:"front_female"` + } `json:"icons"` + } `json:"generation-viii"` + } `json:"versions"` + } `json:"sprites"` + Stats []struct { + BaseStat int `json:"base_stat"` + Effort int `json:"effort"` + Stat struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"stat"` + } `json:"stats"` + Types []struct { + Slot int `json:"slot"` + Type struct { + Name string `json:"name"` + URL string `json:"url"` + } `json:"type"` + } `json:"types"` + Weight int `json:"weight"` +}