Project:

Choose Your Own Adventure


Choose Your Own Adventure

Your Goal:

Build a text based game that allows users to experience different scenarios based on their actions:

  • A user will enter text-based commands into the console and your program should be able to handle each request

  • Each project will be built around a "map" of rooms, areas, locations that can only be reached from an adjacent location, just like in real life

  • Rooms or scenes will have items you can gather, look at, use, etc

  • There is a goal or way of winning your game

  • A user should be able to type "help" and understand what they can and cannot do

  • A user can enter other commands, such as GO, TAKE, TALK, etc. and your program should be able to identify these and do stuff with them

  • A user will be given feedback based on their choices

  • Use arrays to store game items, dialog, scenes, player inventory or other needs



The Project Broken Down:

Part 1: Brainstorm

  • Map out your adventure

    • What rooms will your story consist of?

    • How are each of the rooms linked?

    • What items can be found in each room?

  • What is the storyline that the player is going through?

  • What actions will be available to the player?

Part 2: Game Loop

  • Use readline_sync to prompt users in the terminal

  • Use variables to store the user’s reply in a string and keep track of the game's status

  • Use a while loop to continuously check for answers while the game is in play

  • Write the following functions:

    • startGame() should print the welcome message, instructions, and start the game loop

    • promptUser() to ask the question and return the reply

    • checkAnswer() to process the reply and use the .includes string method to see what command was entered

    • checkAnswer() should use conditionals and the .includes() method to see if a command was entered

  • Use conditionals to check for at least two replies: 'help' and 'end'

    • If a user enters 'help', the options they can type should be printed

    • If a user enters 'end', the game should end

Part 3: Classes

  • Define classes with the necessary properties and methods

  • Instantiate objects from the defined classes

  • Handle player input messages and check if they are valid

  • Add more elements to the game (rooms, characters, items, etc)

  • Add a property to the class that can keep track of where the player is

Part 4: Player Commands

  • Declare an inputMsg variable to store the incoming message from readline-sync

  • handle player input messages and check if valid by splitting strings into arrays

  • handle a command that lets a player 'look' or check their status, inventory, etc.

  • handle a command to make player move throughout the map

  • handle a command to interact in some way with the environment

  • Give an initial welcome message with instructions

  • add more scenes , items, NPC to the game as needed



Reference

A Current Room

An easy first step, once you create your classes (Room, Player, etc.) is to create a currentRoom variable which will change as the player moves through the map.

You will probably need to store all the rooms you create in a rooms array:

//create a rooms or scenes array and push instantiated room objects to it

let rooms = []

rooms.push(bathroom)

rooms.push(kitchen)

rooms.push(livingRoom)


let currentRoom = kitchen //current room will be updated each move


Checking commands

Your checkAnswer() function should already handle a "help" and and "end" command. Today you will add more checks to see if a user inputs the commands to interact with your game.

If a user enters: go living room, or go west , your program should be able to check if the action can be taken. Previously, you used the .includes() method to see if help, or end were entered. Now you will be able to handle a second input. How can we do this?

This code shows you how to convert a string input into an array and grab the second element, where to go.

let commandArray = inputMessage.split(" ") // "go bathroom" becomes ["go", "bathroom"]

let whereToGo = commandArray[1] //take the second element, "bathroom"


//now check if you can get there from your current location, if not warn the user.


What if there are two words, like living room? How can we grab both? Use splice() to take out the first element of the array, which is your command, and keep the rest of the array which includes the rest of the input:

["go" , "living", "room"] -> splice(0,1) -> ["living", "room"] -> join(" ") --> "living room"


Using the splice method

function checkAnswer(input){



input = input.split(" ")

let command = input.splice(0,1) //separate the command from the rest of the message

inputMsg = input.join(" ") //join it back again


if(command.includes("use")){


console.log(" ---> USING: " + inputMsg)

}

else {

console.log("Sorry, I don't know what that means.")

}

}


Can I go there?

If you have added an array for your available routes for each scene, you can check if it is possible to go there by checking if the currentRoom paths array has the room you want to go to as one of its members. It makes more sense by just reading the JavaScript!

Some helpful array methods:

  • for-of loops to search through arrays quickly.

  • indexOf(element) - returns the "address" of the element, if it exists (only the first occurrence)

Inside of your checkInput

if(currentRoom.paths.includes(newRoom)){


for (room of rooms){ //for-of loops! we can look through all the array elements one-by-one.


if(room.name.toLowerCase() == newRoom.toLocaleLowerCase()){


//set the current room by grabbing its index with the indexOf() method

let index = rooms.indexOf(room)

currentRoom = rooms[index]

console.log("You are now at the : " + currentRoom.name);

}

}

}

Make sure to assign your current room as above , otherwise your player will never actually "move there"

Adding to your inventory

In some cases, you may wish to "take" objects or items found in areas. How can you do this? Remember we have a currentRoom variable we can use to see if there are items to pick up . Again, we use the indexOf() to search for its location, then we use splice to remove 1 item, starting from the indexToRemove.

if(currentRoom.objects.includes(itemToTake)){

player.items.push(itemToTake) //add to the players items array


//remove from room using the index

let indexToRemove = currentRoom.objects.indexOf(itemToTake)

currentRoom.objects.splice(indexToRemove, 1)

console.log("player has : " + player.items)

}