Problem
I’ve only been programming for about 2 weeks. I’ve been following a lot of tutorials and decided that the best way to learn would be to do it myself
Looking to properly structure my code as well as a way to split it into multiple classes (Player, Item etc.)
package kataKeptar;
import java.util.Scanner;
public class Main {
static Scanner scan = new Scanner(System.in); //scan is the Scanner variable for user input
static String[] weapons = {"Bow and Arrow","Metal Rod","Axe","Sledge Hammer"};
String[] firstAidSmall = {"Band-Aid","Ace Bandage","Small Roll of Tape","Small Bottle of Peroxide"};
String[] aiPlayers = {"You","Jordan","Isaac","Carla", "Theresa"};
int[] firstAidAmt = {1,2,3,4,5,6,7,8,9,10};
static String yourName; //stores the players name for the game
String decision1, decision2, decision3; //stores the players decision
int age; //stores the players age
int health; //stores the players health throughout the game
int stamina; //stores the players current stamina
int playerDamage; //how much damage the player deals
int bowAndArrow = 7; //weapon damage initial start
int metalRod = 5;
int axe = 3;
int sledgeHammer = 10;
int diamonds;
public static void noteToPlayers(){
System.out.println("Hello and welcome to our first Text based RPG!");
System.out.println("Please bare with us as we design this adventure!");
System.out.println("Suggestions are always welcome!");
System.out.println("nFor the time being please enter all responses as");
System.out.println("you are prompted upper or lower case does not matter.");
System.out.println("Eventually we will be adding an engine to understand ");
System.out.println("and look for key words in your responses.");
System.out.println("nPress ENTER to continue...");
String enter = scan.nextLine();
beginGame();
}
public static void beginGame(){
System.out.println("n");
System.out.println("You wake up in a strange place surrounded by trees and dirt.");
System.out.println("You have no idea how you got there and seem a bit confused at");
System.out.println("first. As you start to get up and look around you there are 4");
System.out.println("other people near you. They are all starting to stir just as ");
System.out.println("yourself. You all look around at eachother befuddled as to why");
System.out.println("you're all left alone out in this strange forest.");
System.out.println("nnWould you like to go and talk to the others?");
System.out.println("Yes or No");
String answer = scan.nextLine();
if(answer.equalsIgnoreCase("yes")){
goodStart();
}
if(answer.equalsIgnoreCase("no")){
badStart();
}
}
public static void goodStart(){
System.out.println("You walk up to the nearest person to you.");
System.out.println("nWould you like to talk to them or attack them?");
System.out.println("nTalk or Attack");
String answer = scan.nextLine();
if (answer.equalsIgnoreCase("Talk")){
System.out.println("nChapter One: nGETTING ACQUAINTED");
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
System.out.println("nHey there! What's your name?");
String yourName = scan.nextLine();
System.out.println("nYou: nI'm " + yourName + ". What's going on? Where are we?");
System.out.println("nCarla: nI don't know what is going on. I do know, however,");
System.out.println("that we are at Beaver River.");
System.out.println("nYou: nHow do you know that?");
System.out.println("nCarla: nWhen we woke up, I looked through the bags to see what was in there.");
System.out.println("I'm a nurse, so the bag with the first aid kit made sense for me-");
System.out.println("n Theresa: nCarla, who's this?");
System.out.println("nCarla: nTheresa, this is " + yourName + ". " + yourName + " just woke up.");
System.out.println(yourName + ", this is Theresa. She is a Botonist and a life long");
System.out.println("Girl Scout. There was nothing in any of the bags for plants,");
System.out.println("but there was a flint and magneseum strip in the bag.");
System.out.println("nWhat's up? You must be " + yourName + ". My name is Isaac and I'm a Blacksmith.");
System.out.println("There was just enough material for me to make one single bullet.");
System.out.println("nWho needs bullets? There was an axe and a metal rod in one of the bags anyway.");
System.out.println("nIsaac: nI don't know Jordan, but I will make one anyway.");
System.out.println("nnThis is Jordan. He's one of those guys you see that always look at maps.");
System.out.println("What's that called again?");
System.out.println("nJordan: nA Cartogropher? nBut yes, " + yourName + ", I study maps. We all");
System.out.println("have PDA's and I was the lucky one with a map. You must be the...");
System.out.println("n*passes out and falls*");
System.out.println("nYou: nI wonder what's wrong with him?");
System.out.println("nCarla: nI don't know but we better get a camp set up and let Jordan");
System.out.println("rest while we figure all this out...");
}
}
public static void badStart(){
System.out.println("You have decided to stay away from the group for the time being.");
System.out.println("Eventually you may want to approach them as there is usually ");
System.out.println("safety in numbers.");
System.out.println("nWould you like to look around the area?");
System.out.println("nYes or No");
String answer = scan.nextLine();
if(answer.equalsIgnoreCase("yes")){
System.out.println("As you scan the area you see a bunch of trees a large rock");
System.out.println("and what looks to be a structure in the distance.");
}
if(answer.equalsIgnoreCase("no")){
System.out.println("");
}
}
public static void main(String args[]){
noteToPlayers();
}
}
Solution
The biggest issue with the code you wrote is not so much the code itself, but rather that the content of your application (i.e. the data) is inside the code. This has several disadvantages, including:
-
Every change to any of the content requires the application to be compiled again, which not only can become time-consuming, but also…
-
…makes it difficult to focus on the program’s behavior, which is what the code should dictate. In other words, the code should neither know nor care about what text is being shown to the player(s).
-
If your future self decides that
System.out.println()
is no longer an appropriate method of displaying text to the user, you have to go fix hundreds of calls to it in your source code.
As you can see, you only have a tiny part of your adventure written, and it’s already nearly 150 lines of code, almost all of which is just text for the player.
Before you go on writing more of the adventure, I would strongly suggest for you to decide upon some form of file storage that your program can read the text from, which can be as simple as a plain text file with some tokens (for the various actors) and delimiters (for the sections).
Just as a small example, take this section:
System.out.println("nCarla: nTheresa, this is " + yourName + ". " + yourName + " just woke up.");
System.out.println(yourName + ", this is Theresa. She is a Botonist and a life long");
System.out.println("Girl Scout. There was nothing in any of the bags for plants,");
System.out.println("but there was a flint and magneseum strip in the bag.");
Imagine instead that you had something like this in a plain text file:
@nurseActor: @botanistActor, this is @playerActor. @playerActor just woke up.
@playerActor, this is @botanistActor. She is a Botanist and a life long Girl Scout.
There was nothing in any of the bags for plants,
but there was a flint and magnesium strip in the bag.
Your program can then simply read that from the file, and substitute the various @something
tokens (or whatever other format you come up with) for the actual text, which, incidentally, could also be read from a file.
Some other formats you could consider to store your data, which are well-worn standards and easily supported by Java (and every other programming platform) are JSON or XML, either of which would provide a well-structured and human-readable way to store your content/data outside of the application’s code.
As far as structuring into classes and such, at this time there is not a whole lot that can be said, being that you have not implemented any players, items, etc. into your program. This would be a good item to address for a future code review question once you come up with what kinds of things a player, item, etc. can do.
There are a good number of text-based game questions already on this site, perhaps you can explore adventure-game questions for inspiration. Don’t be afraid to look at non-Java examples either; a lot of the other languages use the same kinds of principles.
I’ll second what Phrancis said about separating out the text descriptions into some sort of file structure. But you’ll find it rapidly gets a lot more complicated than that (I know, I tried this same thing years ago). Consider, for example, what happens to the descriptions and available actions if you take that magnesium flare out of the bag and set light to it and then carry the bag to a different place.
It’s a huge task you’ve set yourself. I suggest you take a look at Graham Nelson’s Inform, which is a language specifically designed for text adventures – as it comes with some really good thorough documentation about the ins and outs of writing text adventures. If you want to get a bit further under the hood, the previous version (Inform 6) is still around somewhere, and there is also a Z-machine interpreter in Java at Sourceforge which does almost exactly the sort of thing you are starting out on.
I know this isn’t quite in the spirit of a Code Review answer, but it will probably get you started in the right direction quicker than more specific comments will. Even if all you do is sketch out the beginning part of your adventure in Inform, you’ll then have something of substance to translate back into Java.
EDIT: Here’s one thing I just remembered that helped me enormously. Maybe try mapping out something familiar (I did my house and family as a little text adventure) to get the code working and tidy. I found that way I wasn’t distracted from the coding task by thinking what I wanted to happen next in the story.
First of all, the code is very clear, considering you started two weeks ago.
I’d suggest to make a running / playable approach as minimal as possible. Besides removing all the sys-outs, make one deciscion, one player, one weapon, leave the age, leave the first aid, and so on. Make the game winnable and losable. Like ‘a dragon appears you want to run or attack? attack -> critical hit -> you win. Run -> you lose, simple as that. With that, it’s much easier to improve that code by yourself and it’s much easier for us to give you some hints. And it will be much easier for you to adapt object oriented concepts and add new features. And it’s easier to refactor.
With that said, some suggestions, in how to think in portals … err objects… at least a little bit:
- To initialize the game within your main method, you might want to write a class
GameSetup
. The GameSetup does only take the player’s name, and stores it in a classPlayer
. - If the setup has finished, you get the
Player
from theGameSetup
and inject it into a classGame
->Game game = new Game(player); game.start();
- In the
Game
class you write your story and go to the “dragon-decision”.
If you got that, you start to add the ‘fight mechanic’, you maybe add in the GameSetup a new step ‘choose your weapon’ (so, a new type Weapon
), the player chooses it and the GameSetup
sets it to the Player
object…
And please note, many newcomers have that assumption, that you can only represent real things from the real world as objects, like House and Door. But you can also have things like DamageCalculator
and StoryPrinter
… it’s about splitting problems into smaller problems.
Also I’d suggest to read about test driven development, or at least testing in general. It’s a more advanced technique and maybe new starter shouldn’t be bothered, but in my opinion, very very, like really very important – to be honest, as important as the production code. Test driven development actually helps to make your code more clear, improves the design of your application and also helps to think more or better in objects. And it tests your code.
Hope that helps…