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)
}