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 ", 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 ", description: "Attempt to catch a pokemon", callback: commandCatch, }, } 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 }