// Text Adventure -- main loop (finished). // // Run from this folder: // cd projects/04-text-adventure/finished // go run . package main import ( "bufio" "fmt" "os" "slices" "strings" "textadventure/world" ) var reader = bufio.NewReader(os.Stdin) var currentRoom = world.StartID var inventory = []string{} func describe(room int) { fmt.Printf("-- %s --\n", world.Names[room]) fmt.Println(world.Descriptions[room]) if len(world.Items[room]) > 0 { fmt.Println("Items here: " + strings.Join(world.Items[room], ", ")) } exitNames := []string{} for direction := range world.Exits[room] { exitNames = append(exitNames, direction) } slices.Sort(exitNames) fmt.Println("Exits: " + strings.Join(exitNames, ", ")) } func goTo(direction string) { nextRoom, ok := world.Exits[currentRoom][direction] if !ok { fmt.Println("You cannot go that way.") return } currentRoom = nextRoom describe(currentRoom) } func take(itemName string) bool { items := world.Items[currentRoom] i := slices.Index(items, itemName) if i == -1 { fmt.Printf("There is no %s here.\n", itemName) return false } world.Items[currentRoom] = append(items[:i], items[i+1:]...) inventory = append(inventory, itemName) fmt.Printf("You pick up the %s.\n", itemName) if itemName == "gold coin" { fmt.Println("You found the treasure! You win!") return true } return false } func showInventory() { if len(inventory) == 0 { fmt.Println("You are carrying nothing.") return } fmt.Println("You are carrying: " + strings.Join(inventory, ", ")) } // readLine prints the prompt and gives back one trimmed line. The error is // not nil when there is no more input. func readLine(prompt string) (string, error) { fmt.Print(prompt) text, err := reader.ReadString('\n') line := strings.TrimSpace(text) if err != nil && line == "" { return "", err } return line, nil } // parse splits a typed line into a verb and an argument. Items like // "gold coin" are two words, so everything after the verb is the argument. func parse(line string) (string, string) { words := strings.Fields(line) if len(words) == 0 { return "", "" } return words[0], strings.Join(words[1:], " ") } func main() { describe(currentRoom) for { line, err := readLine("> ") if err != nil { fmt.Println() fmt.Println("Goodbye.") break } verb, arg := parse(line) if verb == "" { continue // an empty line: ask again } if verb == "look" { describe(currentRoom) } else if verb == "go" { if arg == "" { fmt.Println("Go where?") } else { goTo(arg) } } else if verb == "take" { if arg == "" { fmt.Println("Take what?") } else if take(arg) { break } } else if verb == "inv" || verb == "inventory" { showInventory() } else if verb == "quit" { fmt.Println("Goodbye.") break } else { fmt.Printf("I do not understand '%s'.\n", verb) } } }