So my program is supposed to read a list of names from a URL in order to play guess the name game; however, the program does not seem to be able to read anything from the URL, let alone add it onto an ArrayList. When running the program, all I get is "There are 0 names in this list" meaning that no names had been added from the URL.
When I use the debugger and step into the URL, I get an error saying "can't step, selected thread is not suspended."
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class NameGuesser {
private ArrayList<String> lastNames = new ArrayList<String>();
Scanner input = new Scanner(System.in);
public void readNames() throws IOException, MalformedURLException {
// Read the last names
URL url = new URL(
"http://www2.census.gov/topics/genealogy/1990surnames/dist.all.last");
Scanner in = new Scanner(url.openStream());
while (in.hasNext()) {
// Read the last name
String lastName = in.next();
lastNames.add(lastName);
// Ignore the statistical information
// in.nextDouble();
// in.nextDouble();
// in.nextInt();
}
in.close();
// Print out the number of names in the file and
// Sort the names using Collections
Collections.sort(lastNames);
System.out.println("There are " + lastNames.size() + " names in this list");
}
public int guessName() {
int counter = 0;
int low = 0;
int high = lastNames.size();
int mid = high / 2;
boolean notFound = true; //variables to hold game info
String userInput = "";
while (notFound) { //while the name is not found
System.out.println("Does your name come before " + lastNames.get(mid) + " in the dictionary? (Y/N), or is " + lastNames.get(mid) + " your name? (S)");
userInput = input.next(); //ask if it is in the middle
if (userInput.equalsIgnoreCase("Y")) { //if before, set new upper bound
high = mid;
mid = ((high - low)/2) + low;
counter++;
} else if(userInput.equalsIgnoreCase("N")){ //if after, set new lower bound
counter++;
low = mid;
mid = ((high - low)/2) + low;
}
else{ //if name is found, return counter
System.out.println("Your name, " + lastNames.get(mid) + ", was found with " + counter + " guesses.");
input.close();
return counter;
}
if(high == low){ //if upper and lower bounds are equal
System.out.println("Is your name: " + lastNames.get(mid) + " ? (Y/N)");
userInput = input.next(); //ask if name is found
if(userInput.equalsIgnoreCase("Y")){ //if yes, print success, counter, and return counter
System.out.println("Your name, " + lastNames.get(mid) + ", was found with " + counter + " guesses.");
input.close();
return counter;
}
else if(userInput.equalsIgnoreCase("N")){ //if no, inform user that guesser failed
System.out.println("Name not found. Attempted locating with " + counter + " guesses");
input.close();
return counter;
}
}
}
input.close();
return counter;
}
}
Tester Method:
import java.io.IOException;
import java.net.MalformedURLException;
public class NameGame {
public static void main(String[] args) throws MalformedURLException, IOException {
NameGuesser game = new NameGuesser();
game.readNames();
}
}
Have you tried opening the URL in a browser? It redirects to a secure protocol (HTTPS).
Change your URL to "https://www2.census.gov/topics/genealogy/1990surnames/dist.all.last" and it should work fine.
Related
So, I am working on a basic math game, and I have a question related to bufferedReaders. During the first part of the application, the output displays some introductory messages showing how the game works. After that the game starts.
My only problem is that during the introductoryMessage() method, which comes before the startGame() method obviously, is that the user can input and submit items while it is still in the intro phase, possibly messing up the game. Is it possible to delay a bufferedReader so that it will only run when the startGame() method is run? Here is some code.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class mainMathClass {
public static void introductoryMessages() throws InterruptedException {
System.out.println("Hello! This is an output based addition game.");
TimeUnit.SECONDS.sleep(2);
System.out.println("\nThe rules are simple. I will ask a math" +
"\nquestion, and you will input the answer" +
"\nunderneath the most recent question.");
TimeUnit.SECONDS.sleep(3);
System.out.println("\nHere is an example:");
TimeUnit.SECONDS.sleep(2);
System.out.println("\nWhat is 10/5?");
TimeUnit.SECONDS.sleep(2);
System.out.println("2");
TimeUnit.SECONDS.sleep(2);
System.out.println("\nIt is as simple as that. Each correct answer is " +
"worth +1 point. Incorrect answers are worth -1 " +
"points");
TimeUnit.SECONDS.sleep(2);
System.out.println("Here is question 1:");
TimeUnit.SECONDS.sleep(3);
}
public static void startGame() throws IOException, InterruptedException {
//Global variables. Do not move.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String userInput;
int correctAnswerCount = 0;
int points = 0;
int i;
for (i = 1; i <= 10; i++) {
/*The following variables must be declared in
* in the for loop. If they are not, they cannot
* change, meaning the for loop will not work
* properly.
*/
Random r = new Random();
int low = 1;
int high = 20;
int a = r.nextInt(high - low) + low;
int b = r.nextInt(high - low) + low;
int problemAnswer = (a + b);
/*Change the math symbol in problemAnswer
*to change the way the game is played.
*Be sure to change the string "+" to whatever
*symbol you replaced the plus symbol with in problemAnswer
*/
String aToString = Integer.toString(a);
String bToString = Integer.toString(b);
//Questions start here
System.out.println("What is " + aToString + " + " + bToString + "?");
userInput = br.readLine();
int userInputToString = Integer.parseInt(userInput);
//Check if userInputToString is equal to the math questions answer.
//Display a certain message depending on if the users answer is correct.
if (userInputToString == problemAnswer) { //Beginning of if-statement #1
System.out.println("\nYou said " + userInputToString + ". That is correct!" +
"\nYou earned 1 point!");
points++;
correctAnswerCount++;
TimeUnit.SECONDS.sleep(2);
System.out.println();
} else {
System.out.println("\nYou said " + userInputToString + ". That is incorrect." +
"\nYou lost one point. :(");
points--;
TimeUnit.SECONDS.sleep(2);
System.out.println();
}
}
TimeUnit.SECONDS.sleep(2);
System.out.println("You have " + correctAnswerCount + " questions answered correctly.");
TimeUnit.SECONDS.sleep(2);
System.out.println("\nYou have " + points + " points.");
} //End of initializeProblem() method
public static void main(String[] args) throws IOException, InterruptedException {
}
}
Also, I have been looking up how to make an application only take numbers as input, and display an error when the input is not an integer, and move on. A lot of them involve a try-catch block, I just do not know where to put it. If someone could help me with that while they are here, that would be great. Thank you.
I'm having trouble with a problem. I can't figure out why my code is working incorrectly on this problem. The problem description is this -
Ask the user for the file name of the file they want to read from.
If a file is specified that is not available, throw an exception and output "File not found." and close the program.
Otherwise, open the specified file.
Each file will have a list of users' names and their (integer) high scores for the game.
Each line will have one name and one score. This is guaranteed - you don't have to plan for anything else.
Go through all of the users and determine who won first, second, and third place.
You can assume that each file will always have at least three names/scores.
The file I'm working with is a text file called Game1Winners. This is the content of the file:
Mario 58
Link 576
Bowser 354
Yoshi 798
Waluigi 39
Wario 521
Toadsworth 7
Pikachu 21
Luigi 243
This is my code but it's working incorrectly..It's printing out first place correctly, but second and third place are out of order..
import java.util.*;
import java.io.*;
public class HighScores
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
System.out.print("What file? ");
String filename = kb.nextLine();
Scanner theFile = null;
try
{
theFile = new Scanner(new FileInputStream(filename));
}
catch(Exception e)
{
System.out.println("File not found.");
System.exit(0);
}
int score = 0;
int high_Score = 0;
int second_Place = 0;
int third_Place = 0;
String name = "";
String store1 = "";
String store2 = "";
String store3 = "";
while(theFile.hasNextLine())
{
name = theFile.next();
score = theFile.nextInt();
if(score > high_Score)
{
high_Score = score;
store1 = name + " with a score of " + high_Score;
}
if(score > second_Place && score < high_Score)
{
second_Place = score;
store2 = name + " with a score of " + second_Place;
}
if(score > third_Place && score < second_Place)
{
third_Place = score;
store3 = name + " with a score of " + third_Place;
}
}
System.out.println("First place: " + store1);
System.out.println("Second place: " + store2);
System.out.println("Third place: " + store3);
}
}
I am creating a simple games score report generator program which takes input and turns it into a .txt file. It takes a name, a game name, an achievement score and minutes played and I want to be able to tally up the amount of games input, add up the achievement score and also add up the minutes (and convert to hours).
This is an example of how my output to .txt looks at the moment -
This is an example of how I would like an output to look -
How do I aggregate data that was input into the console and stored in an array to get results that I want?
PrintWriter writer = new PrintWriter(new FileOutputStream("Gaming Report Data", true));
writer.println("Player : " + gamerName);
writer.println();
writer.println("--------------------------------");
writer.println();
String[] report = gamerReport.split(":");
writer.println("Game: " + report[0] + ", score= " +report[1] + ", minutes played= " +report[2]);
writer.println();
writer.close();
Source code
package JavaProject;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.nio.file.*;
public class JavaProject {
private static final int minutesPlayed = 0;
private static char[] input;
public static void main(String[] args) {
//variables
int hrs = minutesPlayed * 60;
int mins;
String gamerName, gamerReport = null;
int gameCount;
int errorCount;
//Main data storage arrays
String[] gameNames = new String[100];
int[] highScores = new int[100];
int[] minutesPlayed = new int [100];
#SuppressWarnings("resource")
Scanner Scan = new Scanner(System.in);
//formatting for output and input
System.out.println("////// Game Score Report Generator \\\\\\\\\\\\");
System.out.println(" ");
//User enters either their name or quit. Entering a name will move on to next part
for ( ; ; )
{
System.out.print("Enter your Name.");
System.out.println(" ");
gamerName = Scan.nextLine();
for(int b = 1; b < 99; b++ ) { //this is making the code loop 100 times
//user is given an example of input format
System.out.println(" ");
System.out.println("Input Gamer Information " + "Using Format --> Game : Achievement Score : Minutes Played");
System.out.println("FALSE DATA FORMAT WILL CAUSE ERROR");
System.out.println(" ");
//another data input guide which is just above where data input is in console
System.out.println("Game : Achievement Score : Minutes Played");
gamerReport = Scan.nextLine();
String[] splitUpReport; // an array of string
if (gamerReport.equalsIgnoreCase("quit")) {
System.out.println("You have quit!");
return;
}
splitUpReport = gamerReport.split(":");
int i = 0;
//copy data from split text into main data storage arrays
gameNames[i] = splitUpReport[0];
highScores[i] = Integer.parseInt(splitUpReport[1].trim() );
minutesPlayed[i] = Integer.parseInt(splitUpReport[2].trim());
//output to file using a PrintWriter using a FileOutPutStream with append set to true within the printwriter constructor
//
try
{
PrintWriter writer = new PrintWriter(new FileOutputStream("Gaming Report Data", true));
writer.println("Player : " + gamerName);
writer.println();
writer.println("--------------------------------");
writer.println();
String[] report = gamerReport.split(":");
writer.println("Game: " + report[0] + ", score= " +report[1] + ", minutes played= " +report[2]);
//writer.println("Games Played : " + minutesPlayed);
writer.close();
} catch (IOException e)
{
System.err.println("You have made an error with data input");
}
}
System.out.println("You have quit!");
}
}
public static char[] getInput() {
return input;
}
public static void setInput(char[] input) {
JavaProject.input = input;
}
}
So I am assuming that your array data structure looks like this:
Object[] report = new Object[] {new String(), new Integer(), new Integer()}
where the first entry is the game name, the second is the score, and the third is the time played.
I would suggest that you bundle this data into its own object instead of tracking every 3 positions in an array. Try:
public class Game
{
private String name; public String getName() { return name; }
private int score; public int getScore() { return score; }
private int minutesPlayed; public int getMinutesPlayed() { return minutesPlayed; }
public Game(String name, int score, int minutesPlayed)
{
this.name = name;
this.score = score;
this.minutesPlayed = minutesPlayed
}
#Override
public String toString()
{
return "Game: " + name + ", score= " + score + ", minutes played= " + minutesPlayed);
}
}
You can then use this object to represent game data and hold and array of these objects like this:
Game[] games = new Game[]{
new Game("Game 1", 52, 89),
new Game("Game 2", 57, 58),
new Game("Game 3", 67, 86)
};
This array allows us to access each game as a single entity; for example games[0] would get the reference to the 1st game object in the array. These games can have their data accessed by calling the "getters" for the 3 fields contained in the Game object. games[0].getName() would return the name for the first Game object; likewise, games[0].getMinutesPlayed() would return the minutes played for the first game.
Since we overrode the toString method offered to all classes from java's object class to output a string of the data desired in the way your first file I/O was structured. You can call writer.println(games[i]) where i is and index in your array of games to write the data for a individual game.
To concatenate this data into the output you desired. We can do the following:
// get the number of games played
int gamesPlayed = games.length;
// get the raw data on score and time
int totalScore = 0;
int totalMinutesPlayed = 0;
for(int i = 0; i < games.length; i++)
{
totalScore += games[i].getScore();
totalMinutesPlayed += games[i].getMinutesPlayed;
}
// compile the output string
String output = "Games Played: " + gamesPlayed
+ "\n\nTotal Achievement: " + totalScore
+ "\n\nTotal Time: " + totalMinutesPlayed
+ " (" + totalMinutesPlayed / 60
+ " hours and " + totalMinutesPlayed % 60
+ " minutes).";
// write the string to the file
writer.println(output);
Suggestion:
Create a model of the data as a new simple class:
public class GameReportModel{
String gamename = null;
String username = null;
int score = 0;
int minutesplayed = 0;
}
Now you can use an ArrayList of this model to store data before generate the report:
//Declare
ArrayList<GameReportModel> myArray = new ArrayList<GameReportModel>();
//Populate (example) for each input
GameReportModel myobj = new GameReportModel();
myobj.gamename = "My Game"; //<<from input source
myobj.username = "John"; //<<from input source
myobj.score = 20; //<<from input source
myobj.minutesplayed = 45; //<<from input source
myArray.add(myobj);
// Iterate
for(GameReportModel line : myArray){
writer.println("Player : " + line.username);
... and sumarize for each Player
}
Now you can build some scripts to sort by name, game. This method turn it easy but consume more virtual machine resources (memory and steps). But you can manipulate data with another perspective.
Add and remove Array elements easy.
I'm working on a programming project for my intro class. I have a code that I'm trying to compile, but I'm having a hard time getting it to work after I added the PrintWriter. All was running well until I tried to print to a text file. Can someone help me figure out how to get it to run?
(Also, if you find any errors in my logic/layout/whatever, try to contain it! I still want to debug the program myself, I just can't do that until it runs :)
Attempt: (so far)
import java.util.Scanner; //import scanner
import java.util.Random; //import randomizer
import java.io.*; //needed for throws clause
public class randomLottery
{
public static void main(String[] args) throws IOException
{
String fullName;
Scanner keyboard = new Scanner( System.in );
//so we can generate random numbers
Random rand = new Random();
//declare a constant number of numbers
final int LOTTERY_NUMBERS = 5;
//Retrieve names
System.out.print("Please enter a first and last name for lottery "
+ "entry (type 'quit' to end): ");
fullName = keyboard.nextLine();
while(!fullName.contains(" "))
{
System.out.print("Please enter BOTH a first and last name."
+ " Try Again: ");
fullName = keyboard.nextLine();
}
while(!fullName.contains("quit"))
{
//separate first/last name
String[] parts = fullName.split(" ");
String firstName = parts[0];
String lastName = parts[1];
//Open the file
PrintWriter outputFile = new PrintWriter("LotteryEntrants.txt");
//Print the name onto the file
outputFile.print(lastName + ", " + firstName + ": ");
int number;
for (number = 1; number <= LOTTERY_NUMBERS; number++)
{
if (number == LOTTERY_NUMBERS)
{
int lotteryNumber = rand.nextInt(100) + 1;
outputFile.println(lotteryNumber);
}
else
{
int lotteryNumber = rand.nextInt(100) + 1;
outputFile.print(lotteryNumber + ", ");
}
}
//get the next name
System.out.print("Please enter BOTH a first and last name."
+ " Try Again: ");
fullName = keyboard.nextLine();
}
//Winning Lottery Numbers
outputFile.print("The winning numbers are: ");
int winning;
for (winning = 1; winning <= LOTTERY_NUMBERS; winning++)
{
if (winning == LOTTERY_NUMBERS)
{
int lotteryNumber = rand.nextInt(100) + 1;
outputFile.print(lotteryNumber);
}
else
{
int lotteryNumber = rand.nextInt(100) + 1;
outputFile.print(lotteryNumber + ", ");
}
}
outputFile.close();
}
}
PrintWriter outputFile = new PrintWriter("LotteryEntrants.txt");
Should be outside (before) the while loop. Having it inside the loop means it is not in the scope of your other uses of outputFile after the while loop.
I'm making a program that gives random lottery numbers to inputted names. The problem though is that I have to make sure the user entered both a first and last name. I'm using a method of finding the space in the users input, then creating substrings from that data, but I keep on getting the error "incompatible type" right under my for loop. Any help would be greatly appreciated!
enter code here
import java.util.Scanner; //Import scanner class
import java.util.Random; //Import random number generator
import java.io.*; //Import PrintWriter
public class Lab4ZinkovskyFl //Program that lets user enter a name and generates random lottery numbers for that name
{
public static void main (String[] args) throws IOException
{
Scanner keyboard = new Scanner (System.in);
Random randomNumbers = new Random();
String again = "y"; //Control the loop
int r1 = randomNumbers.nextInt(100)+ 1; //*******************
int r2 = randomNumbers.nextInt(100)+ 1; //* Random lottery
int r3 = randomNumbers.nextInt(100)+ 1; //* numbers for
int r4 = randomNumbers.nextInt(100)+ 1; //* program
int r5 = randomNumbers.nextInt(100)+ 1; //*******************
while (again.equalsIgnoreCase ("y")) // Allows the user to continue the loop
{
System.out.println ("Please enter first and last name to enter the lottery.");
String fullName = keyboard.nextLine();
boolean space = false; // Checks for first and last name
for (int i = 0; i < fullName.length(); i++)
{
if (fullName.indexOf(i) == " ")
{
space = true;
spaceIndex = i;
}
else
{
System.out.println ("Error, please enter both first and last name to continue.");
}
}
String firstName = fullName.substring (0, spaceIndex);
String lastName = fullName.substring (spaceIndex, fullName.length());
System.out.println (lastName + ", " + firstName + ": " + r1 + ", " + r2 + ", " + r3 + ", " + r4 + ", " + r5);
System.out.println ("Run the lottery again? (y=yes)");
again = keyboard.nextLine();
}
}
}
You can split the user input by " ", like this:
String[] names = fullName.split(" ");
And then you create a method to return true if the user do enters the full name.
for (int i = 0 ; i < names.length ; i++) {
if (names[i].trim().equals("")) {
names[i] = null;
}
}
int elementsWithText = 0;
for (int i = 0 ; i < names.length ; i++) {
if (names[i] != null) {
elementsWithText++;
}
}
return elementsWithText == 2;
Something like that. Hopefully you figure what I am doing. If you don't know what the methods calls are doing, they are all from String. Here is the docs:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
indexOf() takes in a char as input (in your case). Change i to " "(space)
You need to write like this
if (fullName.indexOf(" ") == -1)
{
System.out.println ("Error, please enter both first and last name to continue.");
}
else
{
space = true;
spaceIndex = i;
}
But why you choose for loop?
#sweeper has given the best solution.