import java.util.Random;
import java.util.Scanner;
public class PassGen {
public static void main(String[] args) {
String[] characters = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"};
StringBuilder b = null;
Scanner scan = new Scanner(System.in);
System.out.println("Enter password length.");
int length = scan.nextInt();
while (length > 20 || length < 6) {
System.out.println("Password must be between 6 and 20 characters long.");
length = scan.nextInt();
}
Random rand = new Random();
for (int i = 0; i <= length; i++) {
int x = rand.nextInt(characters.length) + 1;
b = new StringBuilder(length + 1);
String s = characters[x];
b.append(s);
}
System.out.println("Your password is: " + b.toString());
}
}
For some reason when I run this program it only runs through the for loop once before displaying a single random character regardless of the length entered.
No, the loop is running multiple iterations - but on every iteration, you're creating a new StringBuilder:
// This is inside the loop, but should be outside.
b = new StringBuilder(length + 1);
Note that sometimes, I'd expect the loop to throw an exception - and if it doesn't, you'll end up with a string which is longer than you want anyway. Basically, you have three off-by-one errors... you should have:
b = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int x = rand.nextInt(characters.length);
b.append(characters[x]);
}
Also note that it would be simpler if you just had a string instead of an array of strings, and used charAt:
String characters = "ABCDE...9";
...
int x = rand.nextInt(characters.length());
b.append(characters.charAt(x));
b = new StringBuilder(length + 1);
needs to be outside of the for loop. The way you have it, b is created each time the for loop is run.
You always recreate your b object inside your loop. It will always contain only one character.
Related
import java.util.;
import java.io.;
public class Hangman {
public static void main(String[] args) throws Exception {
// read file and title
System.out.println("H A N G M A N");
System.out.println("________________________");
ArrayList<String> words = new ArrayList<String>();
ArrayList<Integer> indexes = new ArrayList<Integer>();
ArrayList<String> spaces = new ArrayList<String>();
File file = new File("C:\\Users\\nithi\\OneDrive\\Documents\\temp\\hangmanwords.txt");
Scanner reader = new Scanner(file);
Scanner input = new Scanner(System.in);
int numLives = 7;
while(reader.hasNextLine())
{
words.add(reader.nextLine()); // read a file using the Scanner class in this way.
}
int num = (int)(Math.random() * words.size()) + 1;
String word = words.get(num);
for(int i = 0; i < word.length(); i++)
{
spaces.add("_ ");
}
for(int i = 0; i < spaces.size(); i++)
{
System.out.print(spaces.get(i));
}
while(numLives > 7)
{
if(numLives == 0)
{
break;
}
System.out.println("Enter guess of letter: ");
String letterGuess = input.nextLine();
if(word.contains(letterGuess)) // if the word contains the letter guessed, then we must go through the word to find the indexes of each of the parts that contain the letterGuess. Replace all the indexes of the word with the letterGuess inputted.
{
for(int i = 0; i < word.length() - 1; i++)
{
if(word.substring(i, i + 1) == letterGuess)
{
indexes.add(word.indexOf(letterGuess));
}
}
for(int i = 0; i < word.length() - 1; i++)
{
if(word.charAt(indexes.get(i)) == '_')
{
word.replaceAll("_ ", letterGuess);
}
}
}
}
}
}
I have a problem with program constantly ending when running. How do I make it so it does not do this, and actually goes through until the end of my code?
I have tried getting rid of comments, I have tried commenting out certain parts of code, but all attempts have not resolved my issue. Is there anything I am missing here?
Your issue is that you start off by setting numLives to 7 and then you run a while loop for while (numLives > 7). This while loop will never run as the condition is never true.
I would suggest replacing the 7 with 0, meaning that the while loop will run for as long as the variable numLives is greater than 0. This also means that you can get rid of the check for if numLives is equal to 0 (see below):
while(numLives > 7)
{
if(numLives == 0)
{
break;
}
to
while(numLives > 0)
{
However, this will run forever as numLives is never decreased from 7. To fix this, I would suggest adding an else statement after the if statement that checks if the letter is in the word. Inside this else statement, you would decrease numLives (i.e. numLives--;), as the letter is not in the word.
I've written a Reverse digit program but need to check this program to see if it is working correctly. What am I missing an if/else statement?
import java.util.*;
public class IT145_Homework_7_3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// input int parameter
System.out.print("Enter number to reverse: ");
//sets variables
int original = scanner.nextInt();
int reverse = 0;
int remainder;
//original number equals 542
while (original != 0) {
remainder = original % 10; //2 //4 //5
reverse = reverse * 10 + remainder; //2 //24 //245
original = original / 10; //54 //5 //0
}
//Prints out numbers in Reverse
System.out.println("Reverse of number is: " + reverse);
}
}
Here's one way to do the check, but you have to keep an int of the original before you change the original. I called it originalInt
// sets variables
int original = scanner.nextInt();
int originalInt = original; // Save it off here
// all of your code to run the reverse...
// Code to run the check...
String revStr = String.valueOf(reverse);
String orgStr = String.valueOf(originalInt);
// In case you are inputting negative ints
orgStr = orgStr.replace("-", "");
revStr = revStr.replace("-", "");
// remove all trailing zeros from original and check if they are equal
// This is for the cases where the input is '900' and your reverse is '9'
orgStr = orgStr.replaceAll("0*$", "");
boolean worked = true;
// if the lengths are equal, then check if the chars match in opposite directions.
if (revStr.length() == orgStr.length())
{
int len = orgStr.length();
for (int i = 0; i < len; i++)
{
if (orgStr.charAt(i) != revStr.charAt(len - (i+1)))
{
worked = false;
break;
}
}
}
else
{
worked = false;
}
System.out.println("Worked: " + worked);
EDIT: First code had bug.
it can also be done as
int no=scanner.nextInt();
StringBuffer sb= new StringBuffer(no+"");
System.out.println(Integer.parseInt(new String(sb.reverse())));
I have a test for a class that displays a word randomly chosen from an array.
I'm trying to display the word with several chars hidden
I have taken the string, then converted it to an array of chars, but I'm confused as to where to go from here.
import java.util.Scanner;
public class wordTest {
public static void main (String args[])
{
Scanner scanner = new Scanner(System.in);
String readString = scanner.nextLine();
char[] stringArray;
String [] gamewords = { "dog", "cat", "coffee", "tag", "godzilla", "gamera", "lightning", "flash", "spoon", "steak", "moonshine", "whiskey", "tango", "foxtrot", "ganymede"
, "saturn", "enterprise", "reliant", "defiant", "doom", "galapagos", "jidai", "sengoku"};
arrayWords wl = new arrayWords();
// Words w = new Words();
Word n = new Word();
int a = 0;
int b = gamewords.length;
RandNum rand = new RandNum(a,b);
n.setWord(gamewords[rand.nextRandomIntegerInRange()]);
stringArray = n.getWord().toCharArray();
int blank1 = 1;
int blank2 = 4;
RandNum blanks = new RandNum(blank1,blank2);
n.setWord(gamewords[rand.nextRandomIntegerInRange()]);
do{
int i = 0;
//scanner.nextLine();
for( i = 0; i < stringArray.length; i++){
for( i = 0 ; i < blanks.nextRandomIntegerInRange() ; i++ ){
stringArray[i] = '*';
}
System.out.println(stringArray[i]);
}
}while(scanner.nextLine().equals(""));
}
}
Since you haven't given clear definition on what you want to do, here I assume for every string, you are randomly masking 2 characters, in pseudo code, it looks like:
if inputString.length < 2 {
mask all character
} else {
loop until 2 character masked {
r = random from 0 to inputString.length-1
if (inputString[r] is not masked) {
set inputString[r] to mask character
}
}
}
some hints:
to make "inputString" modifiable, make use of a StringBuilder
Way to check if certain position is masked, you can either simply check if the character in the string == mask character, or you can use a Set to keep all masked position
In order to find out number of position masked, you can keep a counter, or simply use the size of the Set in 2 if you choose to use a Set.
Okay, so I think I've found the solution:
for (int i = 0; i < stringArray.length ; i++) {
stringArray[blanks.nextRandomIntegerInRange()] = '_';
System.out.print(stringArray[i] + " " );
}
I have created a loop below that will display around 50 numbers 'at random' between 1 & 999.
The problem I have is that I need to print out the entire array outside the loop (as attempted) but I need it in the same format I have printed it within the loop.
I have tried a few ways of doing it, but it keeps throwing errors, mainly to do with 'illegal conversions'.
// Imports
import java.util.Arrays;
import java.text.DecimalFormat;
// Class
public class Random50
{
public static void main(String[] args)
{
// Declaration
double[] Random50Array = new double[51];
DecimalFormat df = new DecimalFormat("000");
int i;
// Loops
for(i = 0; i < Random50Array.length; i++)
{
Random50Array[i] = (int)(Math.random() * 999);
System.out.print(df.format(Random50Array[i]) + ", ");
}
System.out.println("");
System.out.println("");
String RandomArray = (Arrays.toString(Random50Array));
System.out.printf("%03d", RandomArray);
}
}
I appreciate any future guidance given. :)
You could append the formatted strings within the loop together, and print them out all at once at the end.
// ...
StringBuilder builder = new StringBuilder();
for(i = 0; i < Random50Array.length; i++)
{
Random50Array[i] = (int)(Math.random()*999);
String output = df.format(Random50Array[i])+ ", ";
System.out.print(output);
builder.append(output);
}
System.out.println("");
System.out.println("");
System.out.print(builder.toString());
Note that you shouldn't use System.out.printf("%03d", "..."); to print strings, since the "%03d" means that the argument you are passing is a number. This is the cause of the errors you are experiencing.
Optimized Code: You do not need double array, don't you
StringBuilder builder = new StringBuilder();
for(i = 0; i < Random50Array.length; i++)
{
String output = df.format((int)(Math.random()*999)+ ", ";
builder.append(output);
}
System.out.println("");
System.out.println("");
System.out.print(builder.toString());
import java.util.Scanner;
/**
*
* #author Cutuk
*/
public class JavaApplication3 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String a;
Scanner in = new Scanner (System.in);
a = in.nextLine();
char first = a.charAt(0);
System.out.print(first);
int v= a.length()-1;
char last = a.charAt(v);
int k= a.length();
int random=0;
char x='\u0000';
char middle= '\u0000' ;
for (int i=1; i<a.length()-1;i++){
random= (int )(Math.random() * (k-2) + 1);
middle=a.charAt(random);
x=middle;
System.out.print(x);
}
System.out.print(last);
}
}
I am supposed to take a word, shuffle the letters inside, but keep the first and the last letter unchanged. I managed to randomize, but I cannot keep it from repeating.
Your approach is incorrect: when you pick middle letters at random, it is impossible to guarantee that all letters from the middle of the word would be printed (and as a consequence, that other letters would not be repeated).
There are several ways of fixing this:
Each time you generate a random index, mark that index in an array of booleans. The length of the array is equal to the length of the word. Check the array before using each new index that you generate; if the index is marked, continue generating new random indexes until you hit an empty one.
Create an array of integer indexes of letters inside the word (i.e. 1 through length-1, inclusive). Do a random shuffle on the array, and use the shuffled indexes to pick middle letters.
Similar to 2, except you put all middle letters in an array, and shuffle it.
If I understand your question, I would suggest you start by building a List<Character> and then use Collections.shuffle(List) and finally build your return String with a StringBuilder like
private static String shuffleLetters(String in) {
if (in == null || in.length() < 3) {
return in;
}
char first = in.charAt(0);
char last = in.charAt(in.length() - 1);
List<Character> chars = new ArrayList<>();
for (char ch : in.substring(1, in.length() - 1).toCharArray()) {
chars.add(ch);
}
Collections.shuffle(chars);
StringBuilder sb = new StringBuilder();
sb.append(first);
for (char ch : chars) {
sb.append(ch);
}
sb.append(last);
return sb.toString();
}
Assuming "shuffling" can allow a middle character to sometimes be swapped with itself, you can do something like:
private static final String[] TEST_WORDS = {"apple", "banana", "pear", "raspberry", "cucumber", "watermelon", "a", "ab", "", null};
public static void main(String[] args)
{
for (String word: TEST_WORDS)
{
System.out.println(shuffleInside(word));
}
}
private static String shuffleInside(String word)
{
String ret = word;
if (word != null)
{
Random r = new Random();
int strLen = word.length();
if (strLen > 2)
{
char[] middleChars = word.substring(1, strLen - 1).toCharArray();
shuffle(middleChars, r);
ret = word.charAt(0) + new String(middleChars) + word.charAt(strLen - 1);
}
}
return ret;
}
private static void shuffle(char[] chars, Random r)
{
for (int i = chars.length - 1; i > 0; i--)
{
int index = r.nextInt(i + 1);
char c = chars[index];
chars[index] = chars[i];
chars[i] = c;
}
}
Which handles the case where the word is null, one character, two characters, or two or more characters and produces the following output on a single run:
apple
bnaana
paer
rerrsbpay
cbuemucr
waomteerln
a
ab
null
You could simply create a List<Integer> for storing the random numbers that you generated.
Here is your code from above, cleaned up, with meaningful naming and the List for looking up the history:
public class Main {
public static void main(String[] args) {
final Scanner in = new Scanner(System.in);
final Random rnd = new Random(System.currentTimeMillis());
final List<Integer> rndHistory = new LinkedList<>(); // <-- your history
System.out.print("Please type a word: ");
final String input = in.nextLine();
System.out.print(input.charAt(0));
for (int i = 1, random = 0; i < input.length() - 1; i++) {
do {
random = rnd.nextInt(input.length() - 2) + 1;
} while (rndHistory.contains(random)); // check the history
rndHistory.add(random); // add to the history
System.out.print(input.charAt(random));
}
System.out.println(input.charAt(input.length() - 1));
}
}
Main differences:
final Random rnd = new Random(System.currentTimeMillis()); Using
the the java.util.Random class is a better way for generating
random numbers.
final List<Integer> rndHistory = new LinkedList<>(); This is the actual difference, part of the mechanism to prevent double shuffles
System.out.print("Please type a word: "); a meaningful prompt for
the user (who is going to know what to do, when you program is
executed and there is nothing on the screen?)
and finally:
do {
random = rnd.nextInt(input.length() - 2) + 1;
} while (rndHistory.contains(random)); // check the history
rndHistory.add(random); // add to the history
The 'prevent a random number from being used twice' mechanics
For your random try this: Random generator = new Random(System.currentTimeMillis());