I want to make a game kind of like those Oregon Trail games, and everything goes fine, until the User actually has to input something, like if they want to hunt, or shop, or move on. The console prints the messages 3 times, but no error is shown. The message is supposed to print once, and I cannot figure out why this is happening.
Console:
[1]: https://i.stack.imgur.com/NMC4C.png
Code:
class Started{
static int DaysPassed = 1;
static double Food = 100;
static boolean city = true;
public void start()
throws java.io.IOException{
System.out.println("You have passed " + DaysPassed + " days");
System.out.println("You have " + Food + " food left");
if(city = true){
System.out.println("There is a city here");
}
System.out.println("Press M, H, or T to shop, hunt or travel respectively");
char decision = (char) System.in.read();
switch(decision){
case 'M':
if (city = true){
//open market interface
DaysPassed = DaysPassed + 1;
Food = Food - 10;
} else {
System.out.println("There is no city here, try next route");
}
break;
case 'H':
//open hunt interface
Food = Food - 10;
DaysPassed = DaysPassed + 1;
double hunter = Math.floor(Math.random());
System.out.println("You got" + hunter * 10 + " food");
Food = Food + hunter * 10;
System.out.println("Your food is now " + Food);
start();
break;
case 'T':
DaysPassed = DaysPassed + 1;
Food = Food - 10;
start();
break;
default:
System.out.println("Not a valid Character, remember that it has to be caps or it won't work");
start();
}
}
}
public class CalifornianTrail {
public static void main(String[] args)
throws java.io.IOException{
//some filler start code
System.out.println("Welcome to Californian Trail, a Console based video game based on Oregon Trail");
System.out.println("Starting Simulation");
System.out.println("Game does not have a save function");
System.out.println("This is game version 1.0 Alpha");
System.out.println("Today is the day you start your new journey as a pioneer.");
Started Menu = new Started();
Menu.start();
}
}
It was a long time since I worked with console programs, so I had to use the debugger this time.
This line is the reason:
char decision = (char) System.in.read();
and should be replaced with these two:
Scanner sc = new Scanner(System.in);
char decision = sc.next().charAt(0);
Why was your code executed three times?
Because when you type a char and press enter, a string like this is created M\n, so you have two chars inside the stream System.in. Each System.in.read() reads the first char after the last char that was read. You had two chars each time, so your code was executed three times.
Additionally, your code has a recurrence (the start method calls the start method). After a long time, you will run out of memory. The simplest way to avoid recurrence is to use a loop instead. A break command or return command can break it.
Please learn asap:
How to use a debugger
Naming conventions in java
Related
This is the code I have at the moment and I am trying to figure out how to jump back up from case "A" to the top of the do-while loop to allow the user to selection another action. The idea is that the user would be able to check their balance and then go back after checking their balance and either top-up their card or buy a wash. I only know how to end the loop from this point, not how to jump backwards to the previous input.
do {
System.out.println("Please select an option:\nPress [A] to CHECK FUNDS, press [B] to TOP-UP CARD, press [C] to BUY WASH or press [Q] to quit.");
String actionSelection = scan.nextLine();
switch (actionSelection) { //I haven't defined all the cases yet! //The other cases should not need to refer to other classes, all the actions are within the WashCard
case "A":
System.out.println("Your current balance is: " + this.cardBalance + ".00 DKK.");
sentinel = true;
System.out.println("Would you like to do something else? Press [B] to go back or [Q] to quit.");
break;
case "B":
System.out.println("How much would you like to deposit?\nPlease type in a number between 200 and 1000.");
//user input
break;
case "C":
//any selection should display card balance
//insufficient funds conditional statement:
if (this.cardBalance < 50) {
sentinel = true;
System.out.println("Not enough credit! Please top-up your card first");
System.out.println("Your current balance is: " + this.cardBalance + ".00 DKK.");
}
//only 50 DKK left on the card:
else if (this.cardBalance == 50) {
sentinel = false;
System.out.println("You only have enough credit for the ECONOMY WASH.");
System.out.println("Your current balance is: " + this.cardBalance + ".00 DKK.");
}
//any other choice:
else {
sentinel = false;
System.out.println("Your current balance is: " + this.cardBalance + ".00 DKK.");
}
break;
default:
sentinel = true;
System.out.println("Please enter a valid input!");
}
} while ( sentinel == true );
You do not need this. This soulution breaks OOP pricniples. To solve it you should encapsulate different logic in different methods.
public class Foo {
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
proceed(scan);
}
private static final char CHECK_FUNDS = 'A';
private static final char TOP_UP_CARD = 'B';
private static final char BUY_WASH = 'C';
private static final char QUIT = 'Q';
public static void proceed(Scanner scan) {
while (true) {
System.out.println("Please select an option:");
System.out.format("[%s] - CHECK FUNDS\n", CHECK_FUNDS);
System.out.format("[%s] - TOP-UP CARD\n", TOP_UP_CARD);
System.out.format("[%s] - BUY WASH\n", BUY_WASH);
System.out.format("[%s] - quit\n", QUIT);
System.out.print("> ");
String menu = scan.nextLine().toUpperCase();
char ch = menu.length() == 1 ? menu.charAt(0) : '\0';
if (ch == CHECK_FUNDS)
onCheckFunds();
else if (ch == TOP_UP_CARD)
onTopUpCard();
else if (ch == BUY_WASH)
onBuyWash();
else if (ch == QUIT)
return;
System.err.println("incorrect input");
}
}
private static void onCheckFunds() {
System.out.println("onCheckFunds");
}
private static void onTopUpCard() {
System.out.println("onCheckFunds");
}
private static void onBuyWash() {
System.out.println("onBuyWash");
}
}
EDIT - The game now ends when the player correctly enters a phrase, need a break in my for loop. However, when printing who wins, it prints the last name in the arraylist, when I want it to print who correctly guessed the phrase.
So far, everything else works in my code, such as it listing the amount of players one entered into an array list, lists their earnings after the round ends, etc. But what I am now trying to do is list the name of the person who guessed the phrase. Whenever I try to print the name of the person who guessed it, it prints the next players name instead, not the person who got the phrase. I'm going to post two parts of the code where I think the error could be located.
The first is where the stats are displayed, the second block is where the players keep guessing until the phrase is reached, and the third block is the getname and getwinnings methods However, the game continues and lets other players get one more guess. I want it to print out whoever got the phrase correct first.
Lastly the final block is the entire code for the game class, not the entire program, but the code where the error is occurring (error as in not printing out who won)
This could also be fixed if the puzzle ends once the phrase is guessed, which should happen when !puzzleSolved is called in the second block, but it continues for some reason until all players finish guessing.
if (guess.compareToIgnoreCase(phrase) == 0) {
System.out.println("Congratulations! You guessed it!");
System.out.println("Now pass it to the next person, they get one chance to guess the phrase!");
puzzleSolved = true;
// Round is over.
System.out.println("The player who won is " +players.getName());
System.out.println("Everyone's earnings are ");
for (Player earnings : Players){
System.out.println(earnings.getName());
System.out.println("$" +earnings.getWinnings());
}
public void playGame() throws InterruptedException {
// while the puzzle isn't solved, keep going
while (!puzzleSolved) {
// let the players take turns guessing
int guess = 0;
for (Player turn : Players) { // Enhanced (for each) look to cycle through players
Players.get(guess);
guess++;
playTurn(turn);
}
}
}
public int getWinnings() {
return winnings;
}
/**
* Adds amount to the player's winnings
* #param amount int money to add
*/
public void incrementScore(int amount) {
if (amount < 0) return;
this.winnings += amount;
}
/**
* Getter
* #return String player's name
*/
public String getName() {
return name;
}
public WofFortuneGame(Wheel wheel) throws InterruptedException {
// get the wheel
this.wheel = wheel;
// do all the initialization for the game
setUpGame();
}
/**
* Plays the game
*
* #throws InterruptedException
*/
public void playGame() throws InterruptedException {
// while the puzzle isn't solved, keep going
while (!puzzleSolved) {
// let the players take turns guessing
int guess = 0;
for (Player turn : Players) { // Enhanced (for each) look to cycle through players
Players.get(guess);
guess++;
playTurn(turn);
}
}
}
/**
* Sets up all necessary information to run the game
*/
private void setUpGame() {
addPhrase(); // Calling method to add more phrases to the game
// create a single player
player1 = new Player("Player1");
// ask how many people are going to play
System.out.println("How many players will be participating today?");
Scanner playerCount = new Scanner(System.in);
int player = playerCount.nextInt();
System.out.print(+player);
if (player == 0) {
System.out.println(" You can't play a game with 0 players!"); // "Easter Egg"
System.exit(0);
}
System.out.println(" players will be playing, please enter their names"); // ask for players names
for (int i = 0; i < player; i++) {
Scanner playerName = new Scanner(System.in);
String name = playerName.nextLine();
players = new Player(name);
Players.add(players);
} // add players to Players array list
// print out the rules
System.out.println("RULES!");
System.out.println("Each player gets to spin the wheel, to get a number value");
System.out.println("Each player then gets to guess a letter. If that letter is in the phrase, ");
System.out.println(" the player will get the amount from the wheel for each occurence of the letter");
System.out.println("If you have found a letter, you will also get a chance to guess at the phrase");
System.out.println("Each player only has three guesses, once you have used up your three guesses, ");
System.out.println("you can still guess letters, but no longer solve the puzzle.");
System.out.println();
// User can enter own phrase
System.out.println("Would you like to enter your own phrase? (Y/N)");
Scanner customPhrase = new Scanner(System.in); // Scanner for if yes or no to create custom phrase
char letter = customPhrase.next().charAt(0);
if ((letter == 'Y') || (letter == 'y')) {
System.out.println("Please enter your phrase!");
Scanner typePhrase = new Scanner(System.in); // Scanner to type custom phrase
String custom = typePhrase.nextLine();
phrase = custom;
System.out.println("Now let's play!");
} else {
Random randomPhrase = new Random();
phrase = Phrases.get(randomPhrase.nextInt(Phrases.size()));
}
// for each character in the phrase, create a letter and add to letters arraylist
for (int i = 0; i < phrase.length(); i++) {
// letter_array[i] = new Letter(phrase.charAt(i)); stores in standard array
Letters.add(new Letter(phrase.charAt(i))); // stores in array list
}
// setup done
}
/**
* Method to add a number of phrases to implement into the game. Using
* ArrayList, one could easily add more phrases if the game becomes boring.
*/
private void addPhrase() {
String phrase1 = "Where the Sun Dont Shine";
Phrases.add(phrase1);
String phrase2 = "High Noon";
Phrases.add(phrase2);
String phrase3 = "Fly Me to the Moon";
Phrases.add(phrase3);
String phrase4 = "Im Batman";
Phrases.add(phrase4);
String phrase5 = "Happy Halloween";
Phrases.add(phrase5);
String phrase6 = "Rock and Roll";
Phrases.add(phrase6);
String phrase7 = "Stay in School";
Phrases.add(phrase7);
String phrase8 = "There is no place like home";
Phrases.add(phrase8);
String phrase9 = "Survival of the Fittest";
Phrases.add(phrase9);
String phrase10 = "No Mans Sky";
Phrases.add(phrase10);
String phrase11 = "Offense is the Best Defense";
Phrases.add(phrase11);
String phrase12 = "I Play to Win";
Phrases.add(phrase12);
}
/**
* One player's turn in the game Spin wheel, pick a letter, choose to solve
* puzzle if letter found
*
* #param player
* #throws InterruptedException
*/
private void playTurn(Player player) throws InterruptedException {
int money = 0;
Scanner sc = new Scanner(System.in);
System.out.println(player.getName() + ", you have $" + player.getWinnings());
System.out.println("Spin the wheel! <press enter>");
sc.nextLine();
System.out.println("<SPINNING>");
Thread.sleep(200);
Wheel.WedgeType type = wheel.spin();
System.out.print("The wheel landed on: ");
switch (type) {
case MONEY:
money = wheel.getAmount();
System.out.println("$" + money);
break;
case LOSE_TURN:
System.out.println("LOSE A TURN");
System.out.println("So sorry, you lose a turn.");
return; // doesn't get to guess letter
case BANKRUPT:
System.out.println("BANKRUPT");
player.bankrupt();
return; // doesn't get to guess letter
default:
}
System.out.println("");
System.out.println("Here is the puzzle:");
showPuzzle();
System.out.println();
System.out.println(player.getName() + ", please guess a letter.");
//String guess = sc.next();
char letter = sc.next().charAt(0);
if (!Character.isAlphabetic(letter)) {
System.out.println("Sorry, but only alphabetic characters are allowed. You lose your turn.");
} else {
// search for letter to see if it is in
int numFound = 0;
for (Letter l : Letters) {
if ((l.getLetter() == letter) || (l.getLetter() == Character.toUpperCase(letter))) {
l.setFound();
numFound += 1;
}
}
if (numFound == 0) {
System.out.println("Sorry, but there are no " + letter + "'s.");
} else {
if (numFound == 1) {
System.out.println("Congrats! There is 1 letter " + letter + ":");
} else {
System.out.println("Congrats! There are " + numFound + " letter " + letter + "'s:");
}
System.out.println();
showPuzzle();
System.out.println();
player.incrementScore(numFound * money);
System.out.println("You earned $" + (numFound * money) + ", and you now have: $" + player.getWinnings());
System.out.println("Would you like to try to solve the puzzle? (Y/N)");
letter = sc.next().charAt(0);
System.out.println();
if ((letter == 'Y') || (letter == 'y')) {
solvePuzzleAttempt(player);
}
}
}
}
/**
* Logic for when user tries to solve the puzzle
*
* #param player
*/
private void solvePuzzleAttempt(Player player) {
if (player.getNumGuesses() >= 3) {
System.out.println("Sorry, but you have used up all your guesses.");
return;
}
player.incrementNumGuesses();
System.out.println("What is your solution?");
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\n");
String guess = sc.next();
if (guess.compareToIgnoreCase(phrase) == 0) {
System.out.println("Congratulations! You guessed it!");
System.out.println("Now pass it to the next person, they get one chance to guess the phrase!");
puzzleSolved = true;
// Round is over.
System.out.println("The player who won is " +players.getName());
System.out.println("Everyone's earnings are ");
for (Player earnings : Players){
System.out.println(earnings.getName());
System.out.println("$" +earnings.getWinnings());
}
// TODO
} else {
System.out.println("Sorry, but that is not correct.");
}
}
/**
* Display the puzzle on the console
*/
private void showPuzzle() {
System.out.print("\t\t");
for (Letter l : Letters) {
if (l.isSpace()) {
System.out.print(" ");
} else if (l.isFound()) {
System.out.print(Character.toUpperCase(l.getLetter()) + " ");
} else {
System.out.print(" _ ");
}
}
System.out.println();
}
/**
* For a new game reset player's number of guesses to 0
*/
public void reset() {
players.reset();
}
}
So I'm working on a copy of a simple Dice game that was an example from the Maxwell Sanchez YouTube JAVA on Eclipse tutorials. What I started playing around with is simple ways to implement a text based menu of sorts.
What I'm trying to accomplish is a Y or N input method of either restarting the program, or killing it. I'm a total noob, coming here after a tiny bit of Arduino. I'm liking JAVA but there are many things I don't understand.
My problem right now is, everything appears to work so far, except that if you get to the end and type N to quit, It requires 2 inputs of N to actually execute the else if statement. Is that something that is a bug? Or am I just mis-programing what I'm trying to accomplish.
import java.util.*;
public class diceGame
{
static int money;
static Scanner in = new Scanner(System.in);
static Random random = new Random();
static String userName;
static String tryAgain;
public static void main(String[] args)
{
money = 1000;
System.out.println("Welcome to this simple dice game! " +
"Please enter your name.");
String userName = in.nextLine();
System.out.println("Hey " + userName + ".");
rollDice();
}
public static void rollDice()
{
System.out.println("You have " + money + " coins!");
System.out.println("Please select a number (1-6) to bet on!");
int betRoll = in.nextInt();
System.out.println("Please place your bet!");
int betMoney = in.nextInt();
while (betMoney > money)
{
System.out.println("You don't have enough coins... you only " +
"have " + money + "coins.");
System.out.println("Please place a realistic bet!");
betMoney = in.nextInt();
}
int dice;
dice = random.nextInt(6)+1;
if (betRoll == dice)
{
System.out.println("You Win!");
money+=betMoney*6;
System.out.println("You have " + money + " coins.");
}
else
{
System.out.println("Snap! You lost your coins!");
money-=betMoney;
System.out.println("You have " + money + " coins.");
}
if (money <= 0)
{
System.out.println("You've lost all yer coins!");
System.out.println("Play again?" + " Type y or n");
if (in.next().equalsIgnoreCase("y"))
{
System.out.println("Maybe you'll win this time!");
money = 1000;
rollDice();
}
else if (in.next().equalsIgnoreCase("n"))
{
System.out.println("Maybe next time...");
System.exit(0);
}
else
{
System.out.println("Invalid character");
}
}
else
{
rollDice();
}
}
}
Store the input in a variable, and compare it... or you'll have to input twice.
String choice = in.next();
if (choice.equalsIgnoreCase("y"))
{
System.out.println("Maybe you'll win this time!");
money = 1000;
rollDice();
}
else if (choice.equalsIgnoreCase("n")) // <-- not in.next()
Every time you call in.next() you read user input.
if (in.next().equalsIgnoreCase("y"))
else if (in.next().equalsIgnoreCase("n"))
In this code, you are calling in.next() twice, once for each condition, so it will read two inputs.
You need to separate the reading from the comparison.
String input = in.next();
if (input.equalsIgnoreCase("y"))
else if (input.equalsIgnoreCase("n"))
I am having some problems making a small game for myself. The piece of code I am having problems with is a timeout for user input. For example: The game will show a letter on the screen. The user has to enter that letter by a certain time; if they don't, they take damage. If someone could explain what I could use to fix this problem it would be great.
package weapons;
import java.util.Random;
import java.util.Scanner;
class wepons {
public static void main(String args[]){
int weapondamage =0 , health = 0 , hits = 0, potion = 0, beast = 0, beastdmg = 0, letter = 0;
String weapon;
;
Scanner in = new Scanner (System.in);
System.out.println ("please pick a wepon that will kill the boss \n");
weapon = in.nextLine().toLowerCase();
if (weapon.equals("sword")){
System.out.println("you have picked the sword");
weapondamage = (int) ((Math.random()*100));
health = weapondamage*3;
}
System.out.println("Sword damage is " + weapondamage);
System.out.println("Boss health is " + health);
System.out.println("Enter the amount of hits it will take to kill the boss.");
hits = in.nextInt();
if(hits == health/weapondamage) {
System.out.println("you have killed the boss.The boss had droped a potion.\nYou pick up the potion and drink it!\nYour health has now gone up to 350hp");
}
else {
System.out.print("You have failed to kill the boss");
}
potion = (int)350;
beastdmg = (int) ((Math.random()*60));
System.out.println("By killing the boss you have awoken the beast!");
System.out.println("The beast nocks you onto your back");
System.out.println("The beast will hit you for"+beastdmg+"damage");
System.out.println("You can block the beast damage by hitting the write key");
Random r = new Random();
int c = r.nextInt(26) + (byte)'a';
System.out.println((char)c);
letter = in.next().charAt(0);
if( letter == ((char)c)){
System.out.println("You blocked the beast damage");
}
else {
System.out.print("You took damage");
}
}
} // main
There are various ways to do this, I'm answering using the OP's style, in the simplest possible way, so measuring user time to press the letter. Here's a functioning snippet:
System.out.println("You can block the beast damage by hitting the write key");
long startTime = System.currentTimeMillis();
Random r = new Random();
int c = r.nextInt(26) + (byte) 'a';
System.out.println((char) c);
char letter = in.next().charAt(0);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
if (letter == ((char) c) && elapsedTime <=5000) {
System.out.println("You blocked the beast damage");
} else {
System.out.print("You took damage");
}
Hope it helps.
You'd need to take a look at Threads.
With threads, you can execute several processes at once, rather than just linear coding line by line.
For example, you could say:
while(health > 0){
Thread.sleep(5000); //parameter for sleep is milliseconds, so this is 5 seconds
if(weapon == null){
health -= damage;
}else{ break; }
}
The problem with this is that you might need to create a separate class which extends Thread to invoke the damage loss... If the timed aspect is that necessary I would suggest reading up on threads. Don't take this code snipped literally, this is just a basic outline... From my experience with threads you would need to create a method that would return the weapon value, because you want your Thread to check if the user inputed the value for a weapon.
You also may want to refer to this threading tutorial:
https://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html
for the following code, I need to stop the code by typing the word "quit", but without using "break" or "system.exit" statements. anyone can help me out? I think boolean could solve this but i have no idea how to use it.
I placed the quit statement in the first two lines of the loop,
but im not sure if it belongs there. Im in my learning phase, so dont be too strict :))
import java.util.*;
public class Game {
public static void main (String[]args){
Game guessing = new Game();
guessing.start();
}
public void start() {
System.out.println("Welcome to guessing game!");
System.out.println("Please enter the number between 1 and 1000");
Scanner input = new Scanner(System.in);
String playerName;
String currentGuess;
String quit = "quit";
boolean playGame = true;
int tries = 0; //number of times player guessed
int guess = 0; //number that player inputs
long startTime = System.currentTimeMillis(); //start timer after first guess
int randomNumber = (int) (Math.random() * 999 + 1); // generating random number
System.out.println(randomNumber); // to be deleted after game is finished
currentGuess = input.nextLine();
do{
if (currentGuess.equalsIgnoreCase(quit)) {
System.out.println("Thanx for playing");}
if (currentGuess.matches("[0-9]+")) {
int PlayerGuessInt = Integer.parseInt(currentGuess);
}
else {
System.out.println("You have netered non-numeric value,please try again");
currentGuess = input.nextLine();
continue;
}
guess = Integer.parseInt(currentGuess);
if(guess<1 || guess>1000 ){
System.out.println("The number is out of range! Please try again");
currentGuess = input.nextLine();
continue;
}
if (guess>randomNumber){
System.out.println("Oops,too high!");
currentGuess = input.nextLine();
tries++;
}
else if (guess<randomNumber){
System.out.println("Sorry, to low!");
currentGuess = input.nextLine();
tries++;
}
}
while (guess!=randomNumber);
if (guess==randomNumber){
tries++;
long endTime = System.currentTimeMillis();
long gameTime = endTime - startTime;
System.out.println("Well done! You won the game in " + tries + " guesses " + "and " + gameTime/1000 + " seconds!");
System.out.println("Please enter your name: ");
playerName = input.nextLine();
}
}
}
Change your while loop so that it checks for the value of current guess being "quit". That way it will stop looping when the quit command is given e.g.
while(guess!=randomNumber && !currentGuess.equalsIgnoreCase(quit))
Put inside the while in one (or all of the if )
if (currentGuess.equals("quit") {
playGame = false
}
and change the while to be:
while (guess!=randomNumber && playGame)
Here's the answer:
Global boolean variable:
bool userWantsToQuit = false;
so if someone types int quit (shouln't it be "quit" because it's string?)
if (currentGuess.equalsIgnoreCase(quit))
{
userWantsToQuit = true; // we mark that someone wants to quit
System.out.println("Thanx for playing"); // we output message
continue; // skip execution of the rest (or you could use else if)
}
at the bottom you change while statement to stop the game if userWantToQuit is true:
(guess!=randomNumber && !userWantsToQuit)
It's been long time since I used java and I didn't test it, but it's definitely in good direction.