I'm trying to make a little, basic game of Nim. I'm a beginner in java. When I run the code, it just runs for a second, and stops without doing what I ask of it. It's probably a simple solution but I had to ask. Does anyone have any idea? Here's my code.
import java.util.Scanner;
import java.util.Random;
public class Nim {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Random rand = new Random();
int playernum;
int cpunum = rand.nextInt(3)+1;
int gamenum = 21;
boolean win = false;
boolean turn = true;
while((win = false) && (turn = true)){
System.out.println("The number is 21. Enter a number from 1 - 3");
playernum = input.nextInt();
int remaining = gamenum - playernum;
System.out.println("The number is now " + remaining);
turn = false;
if((turn = false) && (gamenum > 0)){
System.out.println("Computer is thinking...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
When using boolean variables in if statements and loop headers, there's no need to check if they equal true or false, just use the variables themselves like so,
while(!win && turn){
System.out.println("The number is 21. Enter a number from 1 - 3");
playernum = input.nextInt();
int remaining = gamenum - playernum;
System.out.println("The number is now " + remaining);
turn = false;
if(!turn && gamenum > 0){
System.out.println("Computer is thinking...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Also, another issue before was that when you were checking the boolean variables you were using the wrong operator =. You should have used == to compare equality between primitive types but with booleans it's not necessary. If you wanna check if a boolean variable is true, just use the boolean variable itself as the condition. And if you wanna check if a boolean variable is 'false', just use the negation of the boolean variable by using the ! operator in the condition.
Related
I am creating a rock paper project which has the following requirement:
Continually plays rounds of rock, paper, scissors until one of the players wins three rounds. At that point, the program outputs the winner and the number of rounds it took them to win. If there is no winner after 10 rounds, the competition is declared a tie
Something seems to be missing which I am not quite able to understand or notice. How would I make my game stop after the rounds and declare a winner?
Note: No arrays, external libraries other than scanner, or any built-in methods of java allowed
This is my attempt:
import java.util.Scanner;
public class Rockpaper{
public static void main(String[]args){
Scanner keyboard = new Scanner(System.in);
String player1 = keyboard.next();
String player2 = keyboard.next();
String player = "Player1";
int round = 1;
boolean go = true;
boolean win = false;
while(go){
if (player1.equals("r") && player2.equals("p")){
win = true;
}
else if (player1.equals("p") && player2.equals("r")){
win = true;
}
else if (player1.equals("p") && player2.equals("s")){
win = true;
}
else if (player1.equals("s") && player2.equals("p")){
win = true;
}
else if (player1.equals("s") && player2.equals("r")){
win = true;
}
else if (player1.equals("r") && player2.equals("s")){
win = true;
}
else if (player1.equals("r") && player2.equals("r")){
win = false;
}
else if (player1.equals("p") && player2.equals("p")){
win = false;
}
else if (player1.equals("s") && player2.equals("s")){
win = false;
}
if (round < 5){
System.out.println(win+" after "+round+" rounds!");
go = false;
}else{
System.out.println("Tie - No winner after "+round+" rounds!");
}
if (player.equals("Player1"){
Player = "Player2";
}else{
Player = "Player1";
}
}
}
}
The problem I see is that there needs to be a separate variable that counts each of the win possibilities, for example, "win1" which would count the player1 win possibility and "win2" that would count the player2 wins. I am not quite sure about the rounds variable that would initially start counting the rounds up to 10 which is the maximum.
Sample input/output:
Currently you read the input only once, before the loop:
String player1 = keyboard.next();
String player2 = keyboard.next();
After every match, you should ask if players should continue playing. If so, then you must ask for their input again. This is, just move the "playerX" variable declaration and initialization inside the loop:
//comment/remove these
//String player1 = keyboard.next();
//String player2 = keyboard.next();
//inside the loop
while(go){
String player1 = keyboard.next();
String player2 = keyboard.next();
if (player1.equals("r") && player2.equals("p")){
/* rest of your code */
}
Also, this section:
if (round < 5){
System.out.println(win+" after "+round+" rounds!");
go = false;
}else{
System.out.println("Tie - No winner after "+round+" rounds!");
}
if (player.equals("Player1"){
Player = "Player2";
}else{
Player = "Player1";
}
}
It seems odd for two things:
round is never increased.
The else after round < 5 will be always executed, wrongly stating that there's a tie.
Reassigning Player variable for asking user input is not necessary. Instead, you could use 2 variables to store names of your players that are initialized before the game begins.
One more thing: instance of Scanner is Closeable, so each time you use it to read user input, you make sure that the instance is closed after is not needed anymore, in this case, at the end of the program.
More hints:
Reduce several if/else with the same output to a single if evaluation
You could make use of methods to ease game result.
With all this in mind, your code may look like this:
import java.util.Scanner;
public class RockPaperScizzorGame {
public static int getGameResult(String player1Move, String player2Move) {
int result = 0; //assume the game will be a tie
//player 2 wins
if (player1Move.equals("r") && player2Move.equals("p")
|| player1.equals("p") && player2.equals("s")
|| player1.equals("s") && player2.equals("r")
) {
result = 2;
}
//player 1 wins
if (player1.equals("p") && player2.equals("r")
|| player1.equals("s") && player2.equals("p")
|| player1.equals("r") && player2.equals("s")) {
result = 1;
}
//return the result: 0, 1 or 2
return result;
}
public static void main (String[] args) {
try (Scanner keyboard = new Scanner(System.in)) {
String player1Name = "Player 1";
String player2Name = "Player 2";
int round = 0;
boolean go = true;
int winsPlayer1 = 0;
int winsPlayer2 = 0;
while (go) {
System.out.println("Make your move " + player1Name + ": ");
String player1Move = keyboard.next();
System.out.println("Make your move " + player2Name + ": ");
String player2Move = keyboard.next();
int gameResult = getGameResult(player1Move, player2Move);
switch(gameResult) {
case 1:
winsPlayer1++;
break;
case 2:
winsPlayer2++;
break;
}
round++;
if (winsPlayer1 == 3) {
System.out.println(player1Name + " won after " + round + " rounds!");
go = false;
} else if (winsPlayer2 == 3) {
System.out.println(player2Name + " won after " + round + " rounds!");
go = false;
} else {
if (round == 5 && winsPlayer1 < 3 && winsPlayer2 < 3) {
System.out.println("Tie - No winner after "+round+" rounds!");
go = false;
}
}
} catch (IOException e) {
System.out.println("Issues when trying to accept user input.");
e.printStacktrace();
}
}
}
You can improve the code even more:
Use more methods to ease the code in main method.
Since your main loop depends more on a counter rather than a boolean flag, you may use a for loop rather than a while.
You may ask for user input for the name of the players.
You may create a class to encapsulate data of your players: name, currentMove, number of wins.
Problems with your code:
Not using separate variables for individual players.
Not putting input statements inside the loop as a result of which the input statements run only once.
Not changing the value of the variable, round but using its value in the condition, if (round < 5) which will always evaluate true if the value of round is not increased.
Solution
import java.util.Scanner;
public class Rockpaper {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int round = 1;
boolean go = true;
int player1Score = 0;
int player2Score = 0;
while (go && round <= 10) {
String player1 = keyboard.next();
String player2 = keyboard.next();
if (player1.equals("r") && player2.equals("p")) {
player2Score++;
} else if (player1.equals("p") && player2.equals("r")) {
player1Score++;
} else if (player1.equals("p") && player2.equals("s")) {
player2Score++;
} else if (player1.equals("s") && player2.equals("p")) {
player1Score++;
} else if (player1.equals("s") && player2.equals("r")) {
player2Score++;
} else if (player1.equals("r") && player2.equals("s")) {
player1Score++;
}
if (player1Score >= 3) {
System.out.println("Player1 wins " + " after " + round + " rounds!");
go = false;
}
if (player2Score >= 3) {
System.out.println("Player2 wins " + " after " + round + " rounds!");
go = false;
}
round++;
}
if (round > 10) {
System.out.println("Tie - No winner after " + (round - 1) + " rounds!");
}
}
}
First sample run:
p
r
r
s
s
s
r
r
p
r
Player1 wins after 5 rounds!
Second sample run:
p
p
p
r
r
r
s
s
p
p
s
s
s
s
p
p
r
p
s
p
Tie - No winner after 10 rounds!
I am relatively new to java programming. I am currently working on building a mini guessing game, as a project to learn more Java. I am having some issues with the following:
Here are the 4 main things I am having trouble solving.
Record the answer for each user, if incorrect.
If the user was correct, skip them in subsequent rounds.
Once all players have guessed their correct number, print out the number of guesses it took for each one to guess correctly, the incorrect responses, and show a ranking of the players.
Ask if the user(s) wish to play again. If so, reset all values.
Here are the methods that I have written;
import java.io.*;
public class MultiPlayerRandomGame {
// this method asks how many users will be playing and returns the number of users
public static int howManyUsers() {
System.out.println("How many users will be playing?");
int players = IO.readInt();
return players;
}
// this method generates and returns a random number
public static int generateRandomNumber() {
int randomNumber = (int) (Math.random() * 100);
return randomNumber;
}
// this method compares user's entered guess and the generated random number then returns true/false
public static boolean compareGuess(int guess, int randomNumbers) {
boolean isGuessCorrect = false;
if (guess == randomNumbers) {
System.out.println("CORRECT!");
isGuessCorrect = true;
} else if (guess > randomNumbers) {
System.out.println("Too High");
} else if (guess < randomNumbers) {
System.out.println("Too Low");
}
System.out.println("test1");
return isGuessCorrect;
}
// this method determines whether Player N is correct or incorrect
public static boolean nextPlayer(int numOfUsers, int[] numberOfGuesses, int[] randomNumbers, int[][] numberBoard) {
for (int n = 0; n < numOfUsers; n++) {
int guessedNumber = numberOfGuesses[n];
/* if (guessedNumber == 0) {
return false;
}*/
if (numberBoard[n][guessedNumber] != randomNumbers[n]) {
return false;
}
}
return true;
}
/* this method is supposed to print out the number of guesses it took each player to guess their correct number
* CORRECTION: change the logic of this method to printing the number of guesses for one player then
* in the main method or wherever, make a for loop that prints out the number of guesses for each player
*/
public static void amountOfGuesses(int numOfUsers, int [] numberOfGuesses, int [][] numberBoard) {
int n = 0;
for ( int i = 0; i < numOfUsers; i++ ) {
n = n + 1;
System.out.println("Player " + n + " guessed " + numberOfGuesses[i]+ " time(s)");
}
}
// this method determines whether the user(s) would like to play again
public static boolean playAgain(String answer) {
boolean userWillPlayAgain;
if (answer.compareToIgnoreCase("no") == 0) {
userWillPlayAgain = false;
}
else {
userWillPlayAgain = true;
}
return userWillPlayAgain;
}
// this method controls the entire game
public static boolean playGame(){
boolean gameTerminate = false;
int numOfUsers = howManyUsers();
int [] randomNumbers = new int[numOfUsers];
int [] numberOfGuesses = new int [numOfUsers];
int [][] numberBoard = new int [numOfUsers][100];
// this for loop assigns the n random number(s) to the n player(s)
for (int n = 0; n < numOfUsers; n++){
randomNumbers[n] = generateRandomNumber();
System.out.println("PLAYER " + (n+1) + "'s RANDOM NUMBER: " + randomNumbers[n]);
}
do {
for (int i = 0; i < numOfUsers; i++) {
int guessedNumber = numberOfGuesses[i];
if (guessedNumber == 0 || numberBoard[i][guessedNumber-1] != randomNumbers[i]) {
System.out.println("Enter your guess Player " + (i+1) + ":");
int enteredGuess = IO.readInt();
numberBoard[i][guessedNumber] = enteredGuess;
numberOfGuesses[i] = guessedNumber + 1;
if(compareGuess(enteredGuess, randomNumbers[i])){
return true;
}
}
}
/* int n = 0;
* for ( int j = 0; j < numOfUsers; j++ ) {
n = n + 1;
System.out.println("Player " + n + " guessed " + numberOfGuesses[j]+ " time(s)"); }
*/
} while (nextPlayer(numOfUsers, numberOfGuesses, randomNumbers, numberBoard) == false);
// System.out.println("test");
return gameTerminate;
}
public static void main(String[] args){
boolean playing = true;
while (playing) {
playGame();
System.out.println("Would you like to play again?");
String answer = IO.readString();
playing = playAgain(answer);
}
System.out.println("OK, goodbye!");
}
}
Main issue as of right now: The game terminates and asks if user would like to play again after a player guesses their number, rather than after every player guesses their number.
Do I need actual Objects to make this happen and track every player or can this still be solved without objects? This is a territory I am unfamiliar with.
Right now your playGame method returns true back to main whenever any guess returns correct from compareGuess.
I would recommend setting up another array boolean[] correctGuess in playGame and mark the player number index as true if a player guesses correctly. You can use this new array to skip players who have guessed correctly, also. Once all players are marked true you can return to main.
This won't help improve your current code, but the same game can easily implemented using objects. In my opinion, the code is cleaner and easier to read.
Objects allow you to encapsulate the data required by each class. The target, number of guesses, and whether they were correct is stored in the Person object instead of in a multi-dimensional array. The values can be accessed by referencing the Person object - e.g. person.numGuesses or person.target.
By using objects, you can keep specific functionality scoped out of the main class. i.e. abstract away the implementation. In a future version of the game, you may want to change the way the target value is incremented; by using objects, the change can be made in the class which sets and checks the value - without affecting any other classes.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Game {
private final List<Person> personList = new ArrayList<>();
private Game(int numPlayers) {
for (int i = 0; i < numPlayers; i++) {
personList.add(new Person(i)); // Fill the player list
}
}
public static void main(String[] args) {
System.out.print("Enter the number of players: ");
Scanner sc = new Scanner(System.in);
int numPlayers = sc.nextInt();
// Initialise with the number of players
Game g = new Game(numPlayers);
g.mainLoop(); // Play the game
boolean playAgain = false;
do {
System.out.print("Do you wish to play again?: ");
String in = sc.next();
playAgain = "yes".equals(in);
if (playAgain) {
g.resetAll();
g.mainLoop();
}
} while (playAgain); // Only loop if they answered "yes"
}
private boolean allCorrect() {
// Check if all players have answered correctly
return personList.stream().allMatch(p -> p.correct);
}
private void resetAll() {
for (Person p : personList) {
p.reset(); // Reset each person
}
}
private void mainLoop() {
while (!allCorrect()) {
for (Person p : personList) {
p.doGuess(); // Ask for the guess
}
}
// Everyone is correct, print the scores.
for (Person p : personList) {
System.out.println("Player " + p.id + " => " + p.numGuesses + " guesses");
}
}
}
class Person {
final int id;
int numGuesses;
boolean correct;
private int target;
Person(int id) {
this.id = id;
target = new Random().nextInt(100); // Each player has a random target between 0-100
}
void doGuess() {
if (correct) {
// Skip turn if they're already correct
return;
}
numGuesses++;
System.out.print("Player " + id + " guess " + numGuesses + "(" + target + "): ");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt(); // Read the guess
if (i == target) {
correct = true;
System.out.println("Correct!");
}
}
void reset() {
target = new Random().nextInt(100); // New target between 0-100
numGuesses = 0; // Reset the counter
correct = false;
}
}
I've made something that rolls five dice until it gets a five-of-a-kind. I will paste my code below so you can see it. I HAVE set my while condition to false if the five-of-a-kind is successful. Nothing happens after it says "Rolling...". Should I be using .equals()?
package omega;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class One {
public static void main(String[] args) throws InterruptedException {
Random random = new Random();
Scanner scan = new Scanner(System.in);
int one = 1+random.nextInt(6);
int two = 1+random.nextInt(6);
int three = 1+random.nextInt(6);
int four = 1+random.nextInt(6);
int five = 1+random.nextInt(6);
boolean rolling = true;
int rollCount = 0;
System.out.println("====================");
System.out.println(" Yahtzee! ");
System.out.println("====================");
System.out.println("");
System.out.println("Type 0 to roll.");
int roll = scan.nextInt();
System.out.println("Rolling...");
while(rolling == true) {
switch(roll) {
case 0 :
if(two == one && three == one && four == one) {
rollCount++;
rolling = false;
}
else {
rollCount++;
}
break;
default :
System.out.println("Invalid roll!");
}
}
System.out.println("Yahtzee!");
System.out.println("Took " + rollCount + " rolls!");
}
}
You're not rerolling inside the loop. If roll isn't 0, it'll be an infinite loop, printing "Invalid roll!" over and over and over.
You need to change rolling to false if roll is not 0.
default :
System.out.println("Invalid roll!");
rolling = false;
Thus when your while loop re-runs, it will notice the false condition and break.
There is few things that can lead to infinite loop here
First one is your roll variable always zero you are not
rolling again or not changing that variable.
Second one is there is less possibility that the one to five variables
going through the if condition.
if(two == one && three == one && four == one) {
rollCount++;
rolling = false;
}
Also you do not need to use while(rolling == true) instead you can use while(rolling) because your rolling variable initialized as true.
Here is what I came up with
while(rolling) {
switch(roll) {
case 0 :
if(two == one && three == one && four == one) {
rollCount++;
rolling = false;
}
else {
rollCount++;
System.out.println("If you want to stop roll press -1: ");
System.out.println("Or type 0 to roll again.");
roll = scan.nextInt();
if(roll == -1){
System.out.println("Yahtzee!");
System.out.println("Took " + rollCount + " rolls!");
return;
}
}
break;
default :
System.out.println("Invalid roll!");
roll = 0;
}
}
System.out.println("Yahtzee!");
System.out.println("Took " + rollCount + " rolls!");
I was wandering, why this code doesn't print out anything?
package Main;
import java.util.Random;
import java.util.Scanner;
public class Counter {
public static void main(String[] args) {
Random rand = new Random();
int numberOfTries = 0;
int numberToGuess = rand.nextInt(1000);
Scanner input = new Scanner(System.in);
int guess;
boolean win = false;
while (win = false) {
System.out.println("Guess a number between 0 and 1000");
guess = input.nextInt(50);
numberOfTries++;
{
System.out.println("Number of Tries is " + numberOfTries);
}
if (guess == numberToGuess) {
System.out.println("You win");
win = true;
} else if (guess < numberToGuess) {
System.out.println("Number is higher");
} else if (guess > numberToGuess) {
System.out.println("Number is Lower");
}
}
}
}
There is an error in the while statement, it should be while (win == false). A single = acts as assignment operator and consequently return the same value of the assignment (false). The proper logical operator to test equality is ==.
Your code has two problems. The = in while (win = false) { is the assignment operator, not the logical operator. Instead you should have
while (win == false) {
Second, the nextInt method in the Scanner class does not take an argument. Remove the 50 from guess = input.nextInt(50);
guess = input.nextInt();
I was able to run your program after those two modifications.
Change
while (win = false) // this is not a logical operator
to
while (win == false) // this is
Also note you might be confusing
rand.nextInt(50); // generates a random number within the bound = 50
with
guess = input.nextInt(50); // expects the user input which should be of type int using radix 50
So you shall change this to
guess = input.nextInt();
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.