I am making a guessing game where you are supposed to guess the capital of x country, the user is supposed to be prompted each time if they want to guess again there is an array of 15 CountryCards which I need to read through in a random order, I also cannot use the same card twice. When I run my current code I get through 14 iterations of the array and then the last one just gets stuck on the very start of the while loop (after inputting 1 into yesNo nothing happens) Here is the relevant code, any help is appreciated:
while (CountryCard.instances < 30) {
System.out.println("Would you like to guess the capital of a country?"
+ " Hit 1 for yes, or 2 for no (Case sensitive)");
yesNo = input.nextInt();
if (yesNo == 2) {
return;
}
Random generator = new Random();
int randomNumber = generator.nextInt(game.length);
while (game[randomNumber].used == true && CountryCard.uses < 15) {
randomNumber = generator.nextInt(game.length);
}
System.out.println("What is the Capital of "
+ game[randomNumber].getName() + "?");
game[randomNumber].usedCard(1);
guess = input.next();
if (guess.equals(game[randomNumber].getCapital())) {
System.out.println("Correct! :)");
} else {
System.out.println("Incorrect! :(");
}
}//end of while
System.out.println("Thanks for playing :)");
Why not just shuffle your CountryCard list in place with Collections.shuffle each time you play the game?
Something like:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
class Game {
private static final List<CountryCard> countryCards = new ArrayList<>(
Arrays.asList(
new CountryCard("Canada", "Ottawa"),
new CountryCard("USA", "Washington, D.C."),
new CountryCard("France", "Paris"),
new CountryCard("Germany", "Berlin"),
new CountryCard("Spain", "Madrid"),
new CountryCard("Turkey", "Ankara"),
new CountryCard("Sudan", "Khartoum"),
new CountryCard("Brazil", "Brasilia")
// TODO add more countries as needed
));
private Scanner input = new Scanner(System.in);
public void play() {
// shuffle the country card list before playing
Collections.shuffle(countryCards);
for (CountryCard randomCountryCard: countryCards) {
System.out.println("What is the capital of " + randomCountryCard.getName() + "?");
String guess = input.next();
if (randomCountryCard.getCapital().equalsIgnoreCase(guess)) {
System.out.println("Correct!");
} else {
System.out.println("Incorrect!");
}
System.out.println("Answer: " + randomCountryCard.getCapital() + "\n");
}
}
public static void main(String[] args) {
Game game = new Game();
game.play();
}
}
class CountryCard {
private String name;
private String capital;
CountryCard(String name, String capital) {
this.name = name;
this.capital = capital;
}
public String getName() {
return name;
}
public String getCapital() {
return capital;
}
}
If your collection/array has only 15 elements you can just use Collections.shuffle() and then iterate it.
If you don't want to change the initial array you can generate the collection with indexes (from zero to array.length) and then shuffle it.
I previously mentioned in a comment that because you are randomly generating numbers in a while loop while looking for the last 1/15 number, it is very difficult to do. What you could do is implement open addressing collision handling. Of this, you can utilise either linear probing or double hashing.
Linear probing:
if random generated number is x, x is already used, instead of generating new random num, take x+1. If x+1 is used, take x+2 and so on.
double hashing:
if random generated number x is not used, continue as normal, but if it is used, utilise a hash to add a variable constant value to your x.
If it works only 14 times, then issue will be in the loop condition.
Try changing CountryCard.uses<15 to CountryCard.uses<=15
Also check the value of game.length
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
so here i wanna say that in the code every thing is working fine,
except the random no. generator. its basically a dank memer" discord
bot ripoff. so im showing the code, in the rand_int variable ive set it to generate random nos.
but still it doesnt work pls check the code i wanna generate the rand_int throughout the program
import java.util.*;
public class dumMemerFromScratch
{
public static void main()
{
System.out.println("sup nerds,im dum memer");
System.out.println("im not gunna write everything here so just type <plij help>");
int bal = 0;
int min = 0;
int max = 11;
int maxBEG = 3500;
int minBEG = 500;
Scanner sc = new Scanner(System.in);
int rand_int = (int)Math.floor(Math.random()*(max-min+1)+min);
// i want to keep this rand_int keep generating integers even when the program is running
//i know i can place this in a loop but it doesnt work
int i = 1;
while (i == 1)
{
String cmd = sc.next();
if (cmd.equalsIgnoreCase("plij_help"))
{
System.out.println("follow these: ");
System.out.println("(P.S. you can also write <plij help |command|> for more info on the command!");
System.out.println("<plij beg> to beg for some coins lol");
System.out.println("<plij scout> OR <plij search> to search a specific place n get a chance to get some coins n some times even items!!");
System.out.println("<plij crime> to commit a crime n get a chance to get some coins");
System.out.println("<plij hunt> to hunt for animals in the forest(you need a hunting rifle for this)");
System.out.println("<plij fish> to fish for fishes in the lake(you need a fishing pole for this");
System.out.println("<plij postmeme> OR <plij pm> to post a meme(you need a laptop for this");
}
else if (cmd.equalsIgnoreCase("plij_beg"))
{
while (i == 1)
{
switch(rand_int)
{
case 1 :
{
System.out.println("Bo Burnham: ");
System.out.println("\"ew go away\"");
}
case 2 :
{
int randBEG_int = (int)Math.floor(Math.random()*(maxBEG-minBEG+1)+minBEG);
System.out.println("Selena Gomez: ");
System.out.println("\"Oh you poor little beggar, take " + randBEG_int + " \"");
bal = bal + randBEG_int ;
}
case 3 :
{
int randBEG1_int = (int)Math.floor(Math.random()*(maxBEG-minBEG+1)+minBEG);
System.out.println("Rick Astley: ");
System.out.println("\" Here, take " + randBEG1_int + " \"");
bal = bal + randBEG1_int ;
}
case 4 :
{
System.out.println("Justin Beiber: ");
System.out.println("oh i wouldnt pay for your gambling addiction");
}
case 5 :
{
int randBEG2_int = (int)Math.floor(Math.random()*(maxBEG-minBEG+1)+minBEG);
System.out.println("Tom Cruise: ");
System.out.println("\"oh u jobless person, take " + randBEG2_int + "\"");
bal = bal + randBEG2_int ;
}
case 6 :
{
System.out.println("Theresa May: ");
System.out.println("\"Honestly why are you even begging, get a job\"");
}
}
}
}
else if (cmd.equalsIgnoreCase("quit"))
{
System.out.println("Aight then no fun");
break;
}
else
{
System.out.println("sorry i dont understand that, type <plij help> for more info");
}
}
}
}
This is not the way to generate random numbers. Standard library provides quite a few ways to do what you're trying to achieve.
Random Class
import java.util.Random;
public class generateRandom {
public static void main(String args[])
{
// create instance of Random class
Random rand = new Random();
// Generate random integers in range 0 to 999
int rand_int1 = rand.nextInt(1000);
// Print random integers
System.out.println("Random Integers: " + rand_int1);
}
}
SecureRandom Class
import java.security.SecureRandom;
public class generateRandom {
public static void main(String args[])
{
// create instance of SecureRandom class
SecureRandom rand = new SecureRandom();
// Generate random integers in range 0 to 999
int rand_int1 = rand.nextInt(1000);
// Print random integers
System.out.println("Random Integers: " + rand_int1);
}
}
I'd recommend the latter approach since it provides a cryptographically strong random number generator.
Reference:
https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html
I'm taking a programming II class in which we've been working on programming classes. Now we've been assigned homework to write a driver class to incorporate these classes. The homework states
Using the die, dice, and player classes completed in class, write a
driver class to have three players taking turns rolling the dice.
First player to accumulate a total score of 35 or more is the winner."
For example, if player 1 rolls a 3, their score is 3. Then player 2
rolls. Then player 3. As each player rolls, their roll is added to
their previous score.
I've started writing it, but have been given the error that several items in my program cannot be resolved to a type. I also have absolutely no idea how to even begin creating a loop to do what is being asked. This is what I have so far:
import java.util.Scanner;
public class DiceRace {
public static void main(String[] args){
Player player1;
Player player2;
Player player3;
Dice dice;
Scanner keyboard;
keyboard=new Scanner(System.in);
dice=new Dice();
System.out.print("First player's name: ");
player1=keyboard.next();
System.out.print("Second player's name: ");
player2=keyboard.next();
System.out.print("Third player's name: ");
player3=keyboard.next();
}//Ending bracket of method main
}//Ending bracket of class DiceRace
You can create 3 methods, for each player, and a method that plays the game. In each player's method, it first calls the play method with a parameter containing the player name, and the play method prints it out so that the player knows who's turn it is. once the play method is done, it will call the next player method, then the player after that, and finally back to player 1.
It looks like you're a beginner. You should do some tutorials or stuff like that to know the basics :) Also, if you start getting familiar with an IDE (like Eclipse) then programming will be far more easy for you as IDEs can give you detailed descriptions of errors, even while writing the code.
In your above example you need to create two classes by yourself Dice and Player, as they are not in Java by default.
The method keyboard.next() reads an input from the console and returns it as object of the type String, not Player. Thus, you can not assign the variable player1 the result, a String.
What you probably want is a Player object having a member variable String name. Here's an example:
public final class Player {
private String mName;
public Player(final String name) {
mName = name;
}
public String getName() {
return mName;
}
}
Then you can do something like this in your main-method:
player1 = new Player(keyboard.next());
System.out.println("Name of player1 is: " + player1.getName());
Next you probably want a Dice to have a roll method:
public final class Dice() {
private Random mRandom;
public Dice() {
mRandom = new Random();
}
public int roll() {
// Returns a random number between 1 and 6 (inclusive)
return mRandom.nextInt(6) + 1;
}
}
Then, in your main you can do:
Dice dice = new Dice();
System.out.println("Let's roll the dice: " dice.roll());
Now to the games logic, let's keep it very simple, beginner friendly:
int player1Score = 0;
int player2Score = 0;
int player3Score = 0;
boolean finished = false;
boolean player1One = false;
boolean player2One = false;
boolean player3One = false;
// 0 is first player, 1 second and 2 third
int currentPlayer = 0;
while(!finished) {
int rollValue = dice.roll();
if (currentPlayer == 0) {
player1Score += rollValue;
} else if (currentPlayer == 1) {
player2Score += rollValue;
} else {
player3Score += rollValue;
}
player1One = player1Score >= 35;
player2One = player2Score >= 35;
player3One = player3Score >= 35;
finished = player1One || player2One || player3One;
// Increment and modulo 3 (numbers between 0 and 2)
currentPlayer = ((currentPlayer + 1) % 3);
}
Good luck :)
I'm trying to come up with a reverse guessing game. Computer to guess my selected number with a range of 1-100. I do have the binary search algorithm, but when I tell the computer it's first guess is Too High, it will give me another High guess instead of going lower.
import java.util.Random;
import java.util.Scanner;
public class ComputersGuessGame {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random value = new Random();
int computerGuess;
int highValue = 100;
int lowValue = 1;
String myAnswer;
do {
computerGuess = value.nextInt(highValue - lowValue +1)/2;
/*
*Above line should use the binary algorithm so the computer can
*make guesses and not just guess my number by going one number at a time
*/
System.out.println("I'm guessing that your number is " + computerGuess);
myAnswer = in.nextLine();
if (myAnswer.equals("tl")){
highValue = computerGuess + 1;//Too Low Answer
}
else if (myAnswer.equals ("th")){
lowValue = computerGuess - 1;//To High Answer
}
} while (!myAnswer.equals("y")); //Answer is correct
in.close();
System.out.println("Thank you, Good Game.");
}
}//Comptuer keeps making random guesses, but if I say too high, it will guess another high number instead of going low.
I think your logic to guess the next number was wrong. You should have interchange the setting the lower & high value,and change the logic to generate next guess.
here is the working solution of your problem
import java.util.Random;
import java.util.Scanner;
public class Guess {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random value = new Random();
int computerGuess;
int highValue = 100;
int lowValue = 1;
String myAnswer;
do {
computerGuess = value.nextInt(highValue - lowValue)+lowValue;
System.out.println("I'm guessing that your number is " + computerGuess);
myAnswer = in.nextLine();
if (myAnswer.equals("tl")){
lowValue = computerGuess + 1;
} else if (myAnswer.equals ("th")){
highValue = computerGuess - 1;
}
} while (!myAnswer.equals("y"));
in.close();
System.out.println("Thank you, Good Game.");
}
}
you should try to approximate to your guess. you should try nested intervals. your working with class random, of course your computer could guess another high number again, when only lowering the range by one.
you should work with at least 2 new variables, rangeLow and rangeHigh. when to high, your new rangeHigh is your last guess. when to low, your new rangeLow is your last guess.
computerGuess = value.nextInt(rangeLow,rangeHigh);
I'm having some trouble opening and reading in a simple input.txt file to a Java program I'm creating in one of my computer science classes (basic premise of the program is to take lottery data from the file, such as players name and their lottery numbers, and compare it to the user's number that are provided as input). First, when I compile and try to run the program (Eclipse IDE), it cannot see the input.txt file even though it is in the same directory. I have to type in "src/Assignment1/input.txt" in the command line for it to properly find the file. I looked in to the Path utility of Java to see if that could resolve it, but not sure how to implement that code or if there is an easier way.
Also, when the program does find the file, I have my readFile method taking the first number in the text file as the number of tickets sold, and then having a linked list created to hold the data for each person. I am getting a compile error in the second nested for loop in the readFile method shown below:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
No enclosing instance of type lottery is accessible. Must qualify the allocation with an enclosing instance of type lottery (e.g. x.new A() where x is an instance of lottery).
at Assignment1.lottery.readFile(lottery.java:89)
at Assignment1.lottery.main(lottery.java:214)
I've provided a copy of what is in the input.txt below and my code as well under that, any guidance would be appreciated!
5
Llewellyn Mark
1 15 19 26 33 46
Young Brian
17 19 33 34 46 47
Guha Arup
1 4 9 16 25 36
Siu Max
17 19 34 46 47 48
Balci Murat
5 10 17 19 34 47
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
public class lottery {
// Enumeration method that holds constants for how many matches correlate to how much in winnings
public enum PayOut
{
MATCHTHREE(10), MATCHFOUR(100), MATCHFIVE(10000), MATCHSIX(1000000);
private int winnings;
public int getval()
{
return winnings;
}
private PayOut(int amount)
{
this.winnings = amount;
}
}
// Method call to create linked list with purchaser's data in each node
static LinkedList<PurchaserList> purchasers = new LinkedList<>();
// Data structure for purchaser information, contained in each node in linked list
public class PurchaserList
{
public String lastName;
public String firstName;
public int[] numbers;
public PurchaserList (String last, String first, int[] nums)
{
lastName = last;
firstName = first;
numbers = nums;
}
public String getLastName()
{
return lastName;
}
public String getFirstName()
{
return firstName;
}
public int[] getNumbers()
{
return numbers;
}
}
// Method to open and read in data from input file
public static void readFile (String file) throws IOException
{
File fileName = new File(file);
try
{
Scanner in = new Scanner(fileName);
int numTickets = in.nextInt();
for(int i = 0; i < numTickets; i++)
{
String lastName = in.next();
String firstName = in.next();
int[] numbers = new int[6];
for(int j = 0; j < 6; j++)
{
numbers[j] = in.nextInt();
}
PurchaserList current = new PurchaserList(lastName, firstName, numbers);
purchasers.add(i, current);
}
in.close();
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
}
public static void compareNumbers(int[] winningNumbers)
{
// Creates array to hold winning numbers
List<Integer> winningNums = new ArrayList<>(); //creates a list to store all the winning numbers
// For loop to store winning numbers in prior array
for(int num : winningNumbers)
{
winningNums.add(num);
}
//For loop to go through each purchaser in the linked list and get their lottery numbers
for (PurchaserList purchaser : purchasers)
{
// Generating list that stores all the numbers from the current purchaser
List<Integer> playerNums = new ArrayList<>();
// For loop to add numbers to the list
for(int num : purchaser.getNumbers())
{
playerNums.add(num);
}
//Converts list in to a set
Set<Integer> similar = new HashSet<>(playerNums);
//Compares set of winning numbers to purchaser's numbers, keeps similar values
similar.retainAll(winningNums);
//Calls enum method to look for winning amount based on the numbers matched, returns enumeration
PayOut matchesFound = matches(similar.size());
//Only display winnings if matches are 3 or greater
if(matchesFound != null)
{
displayPrices(matchesFound, purchaser.getFirstName(), purchaser.getLastName(), similar.size());
}
}
}
public static PayOut matches(int num)
{
PayOut numMatches;
if(num == 3)
{
numMatches = PayOut.MATCHTHREE;
}
else if(num == 4)
{
numMatches = PayOut.MATCHFOUR;
}
else if(num == 5)
{
numMatches = PayOut.MATCHFIVE;
}
else if(num == 6)
{
numMatches = PayOut.MATCHSIX;
}
else
{
return null;
}
return numMatches;
}
private static void displayPrices(PayOut numMatches, String first, String last, int matches)
{
switch(numMatches)
{
case MATCHTHREE:
System.out.printf("%n%s %s matched %d numbers and won $%d. %n", first, last, matches, PayOut.MATCHTHREE.getval());
break;
case MATCHFOUR:
System.out.printf("%n%s %s matched %d numbers and won $%d. %n", first, last, matches, PayOut.MATCHFOUR.getval());
break;
case MATCHFIVE:
System.out.printf("%n%s %s matched %d numbers and won $%d.%n", first, last, matches, PayOut.MATCHFIVE.getval());
break;
case MATCHSIX:
System.out.printf("%n%s %s matched %d numbers and won $%d. %n", first, last, matches, PayOut.MATCHSIX.getval());
break;
default:
System.out.println("None of the players matched any numbers %n");
break;
}
}
// Main method
public static void main(String[] args) throws IOException
{
Scanner scan = new Scanner(System.in);
// Asking user for input file
System.out.println("Enter the name of the file with the ticket data: ");
String fileName = scan.nextLine();
//Method call to open and read in data from input file
readFile(fileName);
// Creates array to store winning lottery numbers
int[] winningNumbers = new int[6];
// Asking user for winning lottery numbers, in ascending order
System.out.println("Enter the winning Lottery numbers (in ascending order separated by spaces): ");
// For loop to scan in winning lottery numbers to array
for(int i = 0; i < 6; i++)
{
winningNumbers[i] = scan.nextInt();
}
//Method call to compare winning numbers to purchaser's numbers
compareNumbers(winningNumbers);
// Close input file
scan.close();
}
}
The PurchaserList class is not static. Therefore, it must be accessed like lotteryInstance.new PurchaserList() (because as it's not static, it belongs to Lottery instances).
So, making PurchaserList static should fix it.
Hey Guys. thanx for the major help regarding my obstacles.
What my problem this time is, how can I sort the array list that is provided in my code basically dont know WhatI need to add in the provied code below, just to simplyfive it I got 3 arraylist that i want to make them into one arraylist, so they can be sorted in amont of guesses and tries( if 2 players have the same guesses then the time should determine) .
Pretty hard to explain it but i tried my best.............the best thing is to run it then you will figure it what whats the issue is?
Here is the code:
import java.util.*;
import java.util.Scanner.*;
import java.util.ArrayList.*;
public class Main {
public static String ToString(int a, double b, String c)
{
String aS = Integer.toString(a);
String bS = Double.toString(b);
String scoreList = (aS + "\t\t" + bS + "\t\t" + c);
return scoreList;
}
private static void start() {
int tries = 0 ;
int guess = -1;
String name ;
String quit = "quit";
String y = "yes";
String n = "no";
String currentGuess;
String another = ("y") ;
Scanner input = new Scanner (System.in);
ArrayList<String> scores = new ArrayList<String>();
boolean a=false;
do {
a=false;
int answer = (int) (Math.random() * 1000 + 1) ;
System.out.println( " Welcome to Guessing Game " ) ;
System.out.print("Please enter a number between 1 and 1000 : ");
currentGuess = input.nextLine();
long startTime = System.currentTimeMillis();
do
{
if (currentGuess.equalsIgnoreCase(quit))
{
System.out.println("Leaving Us So Soon?");
System.exit(0);
}
try {
guess = Integer.parseInt(currentGuess);
} catch (NumberFormatException nfe)
{
System.out.println(" Dude Can You Read, Only Digits ");
currentGuess = input.nextLine();
}
if (guess < 1 || guess > 1000)
{
System.out.println("Stupid Guess I Wont Count That.");
currentGuess = input.nextLine();
}
if (guess < answer )
{
System.out.println("too low "+answer);
currentGuess = input.nextLine();
tries++;
}
else if(guess > answer )
{
System.out.println("too high "+answer);
currentGuess = input.nextLine();
tries++;
}
else if (guess == answer)
{
//stop stop watch
long endTime = System.currentTimeMillis();
//calculate game time
long gameTime = endTime - startTime;
System.out.println("You Rock Dude, Good Job!");
System.out.println("You guessed " + tries + " times in " + (int)(gameTime/1000) + " seconds.");
System.out.println("Please enter your name.");
name = input.nextLine();
//create score object
String TOString =ToString(tries, gameTime, name);
//add score to arrayList
scores.add(TOString);
boolean s = false ;
while (s==false)
{
System.out.print("Want to go again?(y/n).....");
currentGuess = input.nextLine();
if (currentGuess.matches("y"))
{
System.out.println("HighScore: \nGuess \t Time in milisec\tName");
//print out high score list
for (int i = 0;i < scores.size(); i++)
{
System.out.println(scores.get(i));
}
// Main.start
s=true;
}
//if user doesn't want to play again
if (currentGuess.matches("n"))
{
System.out.println("HighScore:\nGuess \tTime in milisec\tName");
//print out high score list
for (int i = 0;i < scores.size(); i++)
{
System.out.println(scores.get(i));
}
System.out.println("Thanx For Playing.");
a=true;
s=true;
System.exit(0);
}
}
}
} while (guess != answer);
}while(a==false);
}
public static void main(String[] args) {
// ArrayList<Score> scores = new ArrayList<Score>();
Main.start();
}
}
Use Collections.sort() and make sure your class implements Comparable or use something like this:
Collections.sort(list, new Comparator<T>() {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}});
You can use something like input.nextInt() to read in the next integer instead of the next String. I can see no reason why you are storing Strings instead of ints in your code. Then you can use what everyone else has suggested to combine the lists and/or sort them.
I also think you should do some more reading by yourself. Some of the questions you've asked in your comments are answered in the Java documentation.
When someone posts a suggestion, at the very least look it up in the API and try to understand it. People won't be giving you all the code here, they will just give you hints that you need to follow.
To sort an ArrayList you can use the Collections.sort() method; either with only a List of Comparable elements or with a Comparator.
This is the simplest way.
In your case Collections.sort(scores) will do the thing.
To sort a list, use java.util.Collections.sort( list ).
To make one list out of three, you can use alist.addAll(anotherList). Then sort aList as suggested by Collin Hebert.
I helped to answer this in your previous post. However, I will add it here as well. I think you may want a List instead of a list of Strings. This will allow you to sort on the number of tries the end user has attempted, in a natural way. In addition to the other answers here, the simplest way is then to make a call to Collections.sort(list)
Additionally the toString() method is used for debugging purposes, or to provide human readable information. It shouldn't be used to create objects in the way that you are utilizing it. Just my .02
If you absolutely require a list to be sorted at all times, don't use an ArrayList, use a PriorityQueue. It can be constructed to use the content's natural sort order (i.e. via the Comparable interface on each object), or via a Comparator. The advantage of PriorityQueue is it is always sorted even after new items are added.