235 lines
5.0 KiB
Go
235 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/rdarius/boot-dev-pokedex/pokeapi"
|
|
"math/rand"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type config struct {
|
|
pokeapiClient pokeapi.Client
|
|
nextLocationsURL *string
|
|
prevLocationsURL *string
|
|
caughtPokemon map[string]pokeapi.Pokemon
|
|
}
|
|
|
|
type cliCommand struct {
|
|
name string
|
|
description string
|
|
callback func(*config, ...string) error
|
|
}
|
|
|
|
var commands map[string]cliCommand
|
|
|
|
func main() {
|
|
|
|
pokeClient := pokeapi.NewClient(5*time.Second, time.Minute*5)
|
|
cfg := &config{
|
|
caughtPokemon: map[string]pokeapi.Pokemon{},
|
|
pokeapiClient: pokeClient,
|
|
}
|
|
|
|
commands = map[string]cliCommand{
|
|
"exit": {
|
|
name: "exit",
|
|
description: "Exit the Pokedex",
|
|
callback: commandExit,
|
|
},
|
|
"explore": {
|
|
name: "explore <location_name>",
|
|
description: "Explore a location",
|
|
callback: commandExplore,
|
|
},
|
|
"help": {
|
|
name: "help",
|
|
description: "Display a help message",
|
|
callback: printHelpMessage,
|
|
},
|
|
"map": {
|
|
name: "map",
|
|
description: "Get the next page of locations",
|
|
callback: commandMapf,
|
|
},
|
|
"mapb": {
|
|
name: "mapb",
|
|
description: "Get the previous page of locations",
|
|
callback: commandMapb,
|
|
},
|
|
"catch": {
|
|
name: "catch <pokemon_name>",
|
|
description: "Attempt to catch a pokemon",
|
|
callback: commandCatch,
|
|
},
|
|
"inspect": {
|
|
name: "inspect <pokemon_name>",
|
|
description: "View details about a caught Pokemon",
|
|
callback: commandInspect,
|
|
},
|
|
"pokedex": {
|
|
name: "pokedex",
|
|
description: "View list of pokemons caught",
|
|
callback: commandPokedex,
|
|
},
|
|
}
|
|
for {
|
|
// read user input
|
|
input := bufio.NewScanner(os.Stdin)
|
|
fmt.Print("Pokedex > ")
|
|
for input.Scan() {
|
|
word := input.Text()
|
|
cleanedWord := cleanInput(word)
|
|
command := cleanedWord[0]
|
|
var args []string
|
|
if len(cleanedWord) > 1 {
|
|
args = cleanedWord[1:]
|
|
}
|
|
cmd, ok := commands[command]
|
|
if ok {
|
|
err := cmd.callback(cfg, args...)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
} else {
|
|
fmt.Println("Unknown command")
|
|
}
|
|
fmt.Print("Pokedex > ")
|
|
}
|
|
}
|
|
}
|
|
|
|
func commandExit(*config, ...string) error {
|
|
fmt.Println("Closing the Pokedex... Goodbye!")
|
|
os.Exit(0)
|
|
return nil
|
|
}
|
|
|
|
func cleanInput(text string) []string {
|
|
output := strings.ToLower(text)
|
|
words := strings.Fields(output)
|
|
return words
|
|
}
|
|
|
|
func printHelpMessage(*config, ...string) error {
|
|
fmt.Print("Welcome to the Pokedex!\nUsage:\n\n")
|
|
for _, v := range commands {
|
|
fmt.Printf("%s: %s\n", v.name, v.description)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func commandMapf(cfg *config, _ ...string) error {
|
|
locationsResp, err := cfg.pokeapiClient.ListLocations(cfg.nextLocationsURL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cfg.nextLocationsURL = locationsResp.Next
|
|
cfg.prevLocationsURL = locationsResp.Previous
|
|
|
|
for _, loc := range locationsResp.Results {
|
|
fmt.Println(loc.Name)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func commandMapb(cfg *config, _ ...string) error {
|
|
if cfg.prevLocationsURL == nil {
|
|
return errors.New("you're on the first page")
|
|
}
|
|
|
|
locationResp, err := cfg.pokeapiClient.ListLocations(cfg.prevLocationsURL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cfg.nextLocationsURL = locationResp.Next
|
|
cfg.prevLocationsURL = locationResp.Previous
|
|
|
|
for _, loc := range locationResp.Results {
|
|
fmt.Println(loc.Name)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func commandExplore(cfg *config, args ...string) error {
|
|
if len(args) != 1 {
|
|
return errors.New("you must provide a location name")
|
|
}
|
|
|
|
name := args[0]
|
|
location, err := cfg.pokeapiClient.GetLocation(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Printf("Exploring %s...\n", location.Name)
|
|
fmt.Println("Found Pokemon: ")
|
|
for _, enc := range location.PokemonEncounters {
|
|
fmt.Printf(" - %s\n", enc.Pokemon.Name)
|
|
}
|
|
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
|
|
}
|
|
|
|
func commandInspect(cfg *config, args ...string) error {
|
|
if len(args) != 1 {
|
|
return errors.New("you must provide a pokemon name")
|
|
}
|
|
|
|
name := args[0]
|
|
pokemon, ok := cfg.caughtPokemon[name]
|
|
if !ok {
|
|
return errors.New("you have not caught that pokemon")
|
|
}
|
|
|
|
fmt.Println("Name:", pokemon.Name)
|
|
fmt.Println("Height:", pokemon.Height)
|
|
fmt.Println("Weight:", pokemon.Weight)
|
|
fmt.Println("Stats:")
|
|
for _, stat := range pokemon.Stats {
|
|
fmt.Printf(" -%s: %v\n", stat.Stat.Name, stat.BaseStat)
|
|
}
|
|
fmt.Println("Types:")
|
|
for _, typeInfo := range pokemon.Types {
|
|
fmt.Println(" -", typeInfo.Type.Name)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func commandPokedex(cfg *config, _ ...string) error {
|
|
|
|
for name := range cfg.caughtPokemon {
|
|
fmt.Println(cfg.caughtPokemon[name].Name)
|
|
}
|
|
|
|
return nil
|
|
}
|