feat: added catch, inspect, and pokedex commands
This commit is contained in:
+115
-9
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
@@ -11,11 +12,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type context struct {
|
type context struct {
|
||||||
commands map[string]cliCommand
|
commands map[string]cliCommand
|
||||||
client *pokeapi.Client
|
client *pokeapi.Client
|
||||||
prevOffset int
|
prevOffset int
|
||||||
nextOffset int
|
nextOffset int
|
||||||
args []string
|
args []string
|
||||||
|
caughtPokemon map[string]pokeapi.Pokemon
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *context) register(c cliCommand) {
|
func (r *context) register(c cliCommand) {
|
||||||
@@ -55,11 +57,31 @@ func NewContext() *context {
|
|||||||
callback: commandExplore,
|
callback: commandExplore,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catchCommand := cliCommand{
|
||||||
|
name: "catch",
|
||||||
|
description: "Attempt to catch pokemon with given name",
|
||||||
|
callback: commandCatch,
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectCommand := cliCommand{
|
||||||
|
name: "inspect",
|
||||||
|
description: "Inspect information about pokemon with given name if caught",
|
||||||
|
callback: commandInspect,
|
||||||
|
}
|
||||||
|
|
||||||
|
pokedexCommand := cliCommand{
|
||||||
|
name: "pokedex",
|
||||||
|
description: "Display the names of all pokemon you've caught",
|
||||||
|
callback: commandPokedex,
|
||||||
|
}
|
||||||
|
|
||||||
c := &context{
|
c := &context{
|
||||||
commands: map[string]cliCommand{},
|
commands: map[string]cliCommand{},
|
||||||
client: pokeapi.NewClient(pokecache.NewCache(5 * time.Second)),
|
client: pokeapi.NewClient(pokecache.NewCache(5 * time.Second)),
|
||||||
prevOffset: 0,
|
prevOffset: 0,
|
||||||
nextOffset: 0,
|
nextOffset: 0,
|
||||||
|
args: []string{},
|
||||||
|
caughtPokemon: map[string]pokeapi.Pokemon{},
|
||||||
}
|
}
|
||||||
|
|
||||||
c.register(exitCommand)
|
c.register(exitCommand)
|
||||||
@@ -67,6 +89,9 @@ func NewContext() *context {
|
|||||||
c.register(mapCommand)
|
c.register(mapCommand)
|
||||||
c.register(mapBackCommand)
|
c.register(mapBackCommand)
|
||||||
c.register(exploreCommand)
|
c.register(exploreCommand)
|
||||||
|
c.register(catchCommand)
|
||||||
|
c.register(inspectCommand)
|
||||||
|
c.register(pokedexCommand)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@@ -165,3 +190,84 @@ func commandExplore(c *context) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func commandCatch(c *context) error {
|
||||||
|
// TODO: Probably want to allow user to decide
|
||||||
|
// if they want to catch a pokemon they've
|
||||||
|
// already caught. Maybe present xp of current
|
||||||
|
// vs encountered then let them choose.
|
||||||
|
|
||||||
|
if len(c.args) < 1 {
|
||||||
|
fmt.Println("Please provide pokemon name. i.e. catch <pokemon_name>")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon, err := c.client.Pokemon.Get(c.args[0])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Throwing a Pokeball at %s...\n", pokemon.Name)
|
||||||
|
|
||||||
|
roll := rand.Intn(100)
|
||||||
|
baseChance := 75.0
|
||||||
|
pokemonXpMinValue := 0
|
||||||
|
pokemonXpMaxValue := 1000
|
||||||
|
pokemonXp := min(max(pokemon.BaseExperience, pokemonXpMinValue), pokemonXpMaxValue)
|
||||||
|
|
||||||
|
modifier := int(float64(pokemonXp) / float64(pokemonXpMaxValue) * float64(baseChance))
|
||||||
|
chance := int(baseChance) - modifier
|
||||||
|
|
||||||
|
if roll > chance {
|
||||||
|
c.caughtPokemon[pokemon.Name] = pokemon
|
||||||
|
fmt.Printf("You caught %s!\n", pokemon.Name)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s was able to break free!\n", pokemon.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func commandInspect(c *context) error {
|
||||||
|
if len(c.args) < 1 {
|
||||||
|
fmt.Println("Please provide pokemon name. i.e. inspect <pokemon_name>")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemonToInspect := c.args[0]
|
||||||
|
|
||||||
|
pokemon, caught := c.caughtPokemon[pokemonToInspect]
|
||||||
|
|
||||||
|
if !caught {
|
||||||
|
fmt.Printf("You have not previously caught a %s", pokemonToInspect)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Name: %s\n", pokemon.Name)
|
||||||
|
fmt.Printf("Height: %d\n", pokemon.Height)
|
||||||
|
fmt.Printf("Weight: %d\n", pokemon.Weight)
|
||||||
|
fmt.Println("Stats:")
|
||||||
|
|
||||||
|
for _, stat := range pokemon.Stats {
|
||||||
|
fmt.Printf(" - %s: %d\n", stat.Stat.Name, stat.BaseStat)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Types:")
|
||||||
|
|
||||||
|
for _, t := range pokemon.Types {
|
||||||
|
fmt.Printf(" - %s\n", t.Type.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func commandPokedex(c *context) error {
|
||||||
|
fmt.Println("Your Pokedex:")
|
||||||
|
|
||||||
|
for _, pokemon := range c.caughtPokemon {
|
||||||
|
fmt.Printf(" - %s\n", pokemon.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type Client struct {
|
|||||||
cache *pokecache.Cache
|
cache *pokecache.Cache
|
||||||
|
|
||||||
Locations *locationsEndpoint
|
Locations *locationsEndpoint
|
||||||
|
Pokemon *pokemonEndpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(cache *pokecache.Cache) *Client {
|
func NewClient(cache *pokecache.Cache) *Client {
|
||||||
@@ -29,6 +30,7 @@ func NewClient(cache *pokecache.Cache) *Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.Locations = &locationsEndpoint{client: c, path: "/location-area"}
|
c.Locations = &locationsEndpoint{client: c, path: "/location-area"}
|
||||||
|
c.Pokemon = &pokemonEndpoint{client: c, path: "/pokemon"}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@@ -160,12 +162,12 @@ type Location struct {
|
|||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pokemon struct {
|
type EncounteredPokemon struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PokemonEncounter struct {
|
type PokemonEncounter struct {
|
||||||
Pokemon Pokemon `json:"pokemon"`
|
Pokemon EncounteredPokemon `json:"pokemon"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocationArea struct {
|
type LocationArea struct {
|
||||||
@@ -220,3 +222,55 @@ func (le *locationsEndpoint) List(offset int) (Page[Location], error) {
|
|||||||
|
|
||||||
return page, nil
|
return page, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Stat struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PokemonStat struct {
|
||||||
|
BaseStat int `json:"base_stat"`
|
||||||
|
Effort int `json:"effort"`
|
||||||
|
Stat Stat `json:"stat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Type struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PokemonType struct {
|
||||||
|
Type Type `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pokemon struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Height int `json:"height"`
|
||||||
|
Weight int `json:"weight"`
|
||||||
|
Stats []PokemonStat `json:"stats"`
|
||||||
|
Types []PokemonType `json:"types"`
|
||||||
|
BaseExperience int `json:"base_experience"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type pokemonEndpoint struct {
|
||||||
|
path string
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pe *pokemonEndpoint) Get(name string) (Pokemon, error) {
|
||||||
|
var pokemon Pokemon
|
||||||
|
|
||||||
|
requestUrl := fmt.Sprintf("%s/%s", pe.path, name)
|
||||||
|
req, err := pe.client.NewRequest(http.MethodGet, requestUrl, map[string]string{}, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return pokemon, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pe.client.doWithJsonResponse(req, &pokemon)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return pokemon, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pokemon, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user