changing 'invisible' chaaracters to letters, game of hangman - java

so in my program im trying to incorporate a couple of different classse into my main program which i am coming up with the code.
What i am given
Dictionary() {
dictionary = new String[NUMBER_OF_WORDS];
Scanner inputStream = null;
try {
inputStream = new Scanner(new File(FILE_NAME));
}catch (FileNotFoundException e) {
System.out.println("Dictionary class cannot find file \"dictionaryData.txt\".");
System.out.println("Please make sure that the file is in the project folder.");
System.exit(0);
}
for (int i = 0; i < NUMBER_OF_WORDS; i++) {
dictionary[i] = inputStream.next();
}
}
public String getRandomWord(){
Random generator = new Random();
String temp = new String();
temp += dictionary[generator.nextInt(NUMBER_OF_WORDS)];
return temp;
}
public boolean find(String word) {
int count = 0;
int lowerIndex = 0;
int upperIndex = NUMBER_OF_WORDS - 1;
int middleIndex;
while(lowerIndex <= upperIndex){
middleIndex = (lowerIndex + upperIndex) / 2;
count++;
if(word.equalsIgnoreCase(dictionary[middleIndex])) { // found it
return true;
}
else if (word.compareToIgnoreCase(dictionary[middleIndex]) < 0) { // word smaller than middle
upperIndex = middleIndex - 1;
}
else { // word is larger than middle
lowerIndex = middleIndex + 1;
}
}
return false;
}
}
along with another class WordHider
WordHider() {
secretWord = new String();
wordMask = new String();
}
public String getWordMask() {
return wordMask;
}
public String getSecretWord() {
return secretWord;
}
public void setSecretWord(String newSecretWord) {
secretWord = newSecretWord.toLowerCase();
if (secretWord.length() > 0) {
wordMask = HIDE_CHAR;
for (int i = 1; i < secretWord.length(); i++) {
wordMask += HIDE_CHAR;
}
}
}
public boolean isHiddenWordFound() {
for (int i = 0; i < wordMask.length(); i++) {
if(wordMask.charAt(i) == HIDE_CHAR.charAt(0)) {
return false;
}
}
return true;
}
public int revealLetter(String letter) {
int count = 0;
String newFoundWord = "";
if (letter.length() == 1) {
for (int i = 0; i < secretWord.length(); i++) {
if ((secretWord.charAt(i) == letter.charAt(0))
&& (wordMask.charAt(i) == HIDE_CHAR.charAt(0))) {
count++;
newFoundWord += letter;
}
else {
newFoundWord += wordMask.charAt(i);
}
}
}
wordMask = newFoundWord;
return count;
}
}
and using those classes i have to come up with code that looks like this:
Word: ********** Guesses Left: 5
Enter your guess: a
Miss!
Word: ********** Guesses Left: 4
Enter your guess: e
Miss!
Word: ********** Guesses Left: 3
Enter your guess: i
Word: i**i*i**** Guesses Left: 3
Enter your guess: o
Word: i**i*i*o** Guesses Left: 3
And ive got a couple of questions about this,
1) i have a dictionaryData.text that i was given and have to implement
that into my code. it contains a list of 81thousand words and im not
sure how to have my program recognize its there. Dictionary class
cannot find file "dictionaryData.txt". Please make sure that the file
is in the project folder. ^ i get that error when i try and print a
random word
2) How do i get my program to change the letters of a word to
stars(Hide the word)
3) put it all in a loop?

Parts of the Dictionary class and the WordHider class are missing. Nevertheless, I'll try and answer your questions.
1) Like I said, you're missing part of the Dictionary class. You incorporate the class like this:
Dictionary dictionary = new Dictionary();
String word = dictionary.getRandomWord();
2) Like this:
wordHider.setSecretWord(word);
3) I'm not sure what "it" is, but yes, your user has to guess a letter. Then you have to check to see if the letter is in the word. Like this:
wordHider.revealLetter(letter);
Then you have to display the word and let the user guess another letter. This guess / check / display has to be in a loop.

Related

Taking user input until <<EOF>> is entered

I'm going to start off by saying I already looked at the thread called "I have to make a loop taking users input until "done" is entered" I had no luck with the code answers that were given there.
The description I've been given for my edit command is this:
"Edits a text file if exists. Otherwise, creates new text file. The command waits for the user to type in text(must support multiple lines of text). The user ends the input by typing <<EOF>> and hitting enter."
Right now the code I have is this:
else if (spaceSplit[0].equals("edit")) {
String name = spaceSplit[1];
boolean endOfFile = false;
String content = "";
while(endOfFile == false){
String userInput = s.next();
content += userInput;
if(content.contains("<<EOF>>")){
endOfFile = true;
}
}
FileSystem.edit(name, content);
}
Nothing errors-out, but my else statement prints. My else statement code is this:
else {
System.out.println("That is not a command. Please try again.");
}
What is also funky is that the program goes through the whole do while loop then prints the else. I know this because what is exactly printed is: $That is not a commond. Please try again.
Here is the beginning of my do while loop:
do {
System.out.print("$");
String input = s.nextLine();
input = input.toLowerCase();
spaceSplit = input.split(" ");
Quite confusing. Also my edit(String name, String content) function is as follows:
public static void edit(String name, String content){
for(int i = 0; i < texts.size(); i++){
if(texts.get(i).getName().equals(name)){
texts.get(i).setContent(content);
} else {
texts.add(new TextFile(name,content));
for(int j = 0; j < directories.size(); j++){
if(directories.get(j).getName().equals(wDir.getName())){
texts.get(texts.size() - 1).setParent(directories.get(j));
System.out.println("The parent of " + name + " is " + directories.get(j).getName());
}
}
}
}
}
As you can see I've done a check at the end of my edit(name,content) method to check if the file is correctly created by printing out the parent directory of the text file.
This is how my program should function once I call the edit command:
$mkdir d
$cd d
$edit stuff.txt
Hello everyone, this is just an example!<<EOF>>
The parent of stuff.txt is d
$exit
Good Bye!
Any help provided would be greatly appreciated.
Here is the whole do while loop:
do {
System.out.print("$");
String input = s.nextLine();
input = input.toLowerCase();
spaceSplit = input.split(" ");
if (spaceSplit[0].equals("mkdir")) {
if (spaceSplit[1].equals("-p")) {
for (int i = 3; i < spaceSplit.length; i++) {
}
} else if (spaceSplit[1].contains("/")){
//This method will create a directory farther down the tree like creating c in a/b/c
String[] dirSplit = spaceSplit[1].split("/");
int length = dirSplit.length;
FileSystem.mkdir(dirSplit[length-1]);
int directoriesLength = FileSystem.directories.size();
for(int i = 0; i < FileSystem.directories.size(); i++){
if(dirSplit[length-2].equals(FileSystem.directories.get(i))){
FileSystem.directories.get(i).addChild(FileSystem.directories.get(directoriesLength-1));
//Checking if this works
System.out.println("The child was created succesfully");
}
}
} else {
for (int i = 1; i < spaceSplit.length; i++) {
FileSystem.mkdir(spaceSplit[i]);
}
}
} else if (spaceSplit[0].equals("cd")) {
FileSystem.cd(spaceSplit[1]);
} else if (spaceSplit[0].equals("pwd")) {
FileSystem.pwd();
} else if (spaceSplit[0].equals("ls")) {
} else if (spaceSplit[0].equals("edit")) {
String name = spaceSplit[1];
boolean endOfFile = false;
String content = "";
while(endOfFile == false){
String userInput = s.next();
content += userInput;
if(content.contains("<<EOF>>")){
endOfFile = true;
}
}
FileSystem.edit(name, content);
} else if (spaceSplit[0].equals("cat")) {
for(int i = 1; i < spaceSplit.length; i++){
FileSystem.cat(spaceSplit[i]);
}
} else if (spaceSplit[0].equals("updatedb")) {
} else if (spaceSplit[0].equals("locate")) {
} else if (spaceSplit[0].equals("exit")) {
exitProg = true;
System.out.println("Good bye!");
} else {
System.out.println("That is not a command. Please try again.");
}
} while (exitProg == false);
Alright, well I guess I'll answer my own question here. Everything works perfectly now.
else if (spaceSplit[0].equals("edit")) {
if(spaceSplit.length > 1) {
String name = spaceSplit[1];
boolean endOfFile = false;
String content = "";
while (!(content.contains("<<EOF>>"))) {
String userInput = s.nextLine();
content += userInput + " ";
}
String end = "<<EOF>>";
content = content.replace(end, "");
int size = tree.getTexts().size();
if (size != 0) {
for (int i = 0; i < size; i++) {
if (tree.getTexts().get(i).getName().equals(name)) {
tree.getTexts().get(i).setContent(content);
}
}
tree.edit(name, content);
} else {
tree.edit(name, content);
}
}
}

More then one Indexes

I would like to have this code be able to locate more than one X and output it as Location1, location2,.......
i.e input: xuyx
i would have it output 0,3
import java.util.Scanner;
public class findinline {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str;
str = input.nextLine();
int pos = str.indexOf("x");
if (pos < 0){
System.out.println("No X Detected");
}
else{
System.out.println(pos);
}
}
}
String has the method indexOf(String str, int fromIndex) http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
So just increment the starting index to where you found the last one.
String xStr = "xuyx";
int index = xStr.indexOf("x", 0);
while(index >= 0)
{
System.out.println(index);
index = xStr.indexOf("x", index + 1);
}
or better yet...
public List<Integer> getIndexesOfStr(String fullStr, String strToFind){
ArrayList<Integer> listOfIndexes = new ArrayList<>();
int index = fullStr.indexOf(strToFind, 0);
while(index >= 0)
{
listOfIndexes.add(index);
index = fullStr.indexOf(strToFind, index + strToFind.length());
}
return listOfIndexes;
}
You could do it like this. Iterate through the characters and print out the indexes where you hit an x.
boolean any = false;
for (int pos = 0; pos < str.length(); ++pos) {
if (str.charAt(pos)=='x') {
if (any) {
System.out.print(',');
}
any = true;
System.out.print(pos);
}
}
if (!any) {
System.out.println("No x found");
} else {
System.out.println();
}
Bear in mind you'd have to fix the case if you want to detect capital X as well.
Or, as kingdamian42 says, you could use indexOf(txt, fromindex)

Currently compiling, but receiving nothing but end to program?

import java.util.Scanner;
public class PD {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
System.out.print("Enter your number: " );
int number = input.nextInt();
for (int count = 2; count < number; count++) {
String blank = "";
String Snumber = count + blank;
if (isPalindromic(count) && isPrime(count) &&
isPalindromic((int)(Snumber.length())) &&
isPrime((int)(Snumber.length()))){
System.out.println( count + "is double palidromic prime");
}
else
continue;
}
}
// method to find palindromic
public static boolean isPalindromic(int count) {
String blank = "";
String convert = count + blank;
for (int i = 0, q = 1; i <= (convert.length()/2 - 1); i++, q++) {
if (convert.substring(i,q) == convert.substring(convert.length() - q, convert.length() - i)){
return true;
}
}
return false;
}
// method to find prime
public static boolean isPrime(int count ) {
for (int divisor = 2; divisor <= count/2; divisor++) {
if (count % divisor == 0) {
return false;
}
}
return true;
}
}
Currently the thing compiles and ask for input, but it always results in nothing.
Does someone see something wrong with my program that is obvious wrong.
Overall, the program receives input and has to look through values 2 until it hits the value the user wants and print the ones that follow the if statement.
Your isPalindromic method is not functioning properly. It is not returning true for palindromic numbers. Change it to this:
public static boolean isPalindromic(int count) {
String blank = "";
String convert = count + blank;
int n = convert.length();
for (int i = 0; i < (n / 2 + 1); i++) {
if (convert.charAt(i) != convert.charAt(n - i - 1)) {
return false;
}
}
return true;
}

Compression algorithm in java

My goal is to write a program that compresses a string, for example:
input: hellooopppppp!
output:he2l3o6p!
Here is the code I have so far, but there are errors.
When I have the input: hellooo
my code outputs: hel2l3o
instead of: he213o
the 2 is being printed in the wrong spot, but I cannot figure out how to fix this.
Also, with an input of: hello
my code outputs: hel2l
instead of: he2lo
It skips the last letter in this case all together, and the 2 is also in the wrong place, an error from my first example.
Any help is much appreciated. Thanks so much!
public class compressionTime
{
public static void main(String [] args)
{
System.out.println ("Enter a string");
//read in user input
String userString = IO.readString();
//store length of string
int length = userString.length();
System.out.println(length);
int count;
String result = "";
for (int i=1; i<=length; i++)
{
char a = userString.charAt(i-1);
count = 1;
if (i-2 >= 0)
{
while (i<=length && userString.charAt(i-1) == userString.charAt(i-2))
{
count++;
i++;
}
System.out.print(count);
}
if (count==1)
result = result.concat(Character.toString(a));
else
result = result.concat(Integer.toString(count).concat(Character.toString(a)));
}
IO.outputStringAnswer(result);
}
}
I would
count from 0 as that is how indexes work in Java. Your code will be simpler.
would compare the current char to the next one. This will avoid printing the first character.
wouldn't compress ll as 2l as it is no smaller. Only sequences of at least 3 will help.
try to detect if a number 3 to 9 has been used and at least print an error.
use the debugger to step through the code to understand what it is doing and why it doesn't do what you think it should.
I am doing it this way. Very simple:
public static void compressString (String string) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
int count = 1;
while (i + 1 < string.length()
&& string.charAt(i) == string.charAt(i + 1)) {
count++;
i++;
}
if (count > 1) {
stringBuffer.append(count);
}
stringBuffer.append(string.charAt(i));
}
System.out.println("Compressed string: " + stringBuffer);
}
You can accomplish this using a nested for loops and do something simial to:
count = 0;
String results = "";
for(int i=0;i<userString.length();){
char begin = userString.charAt(i);
//System.out.println("begin is: "+begin);
for(int j=i+1; j<userString.length();j++){
char next = userString.charAt(j);
//System.out.println("next is: "+next);
if(begin == next){
count++;
}
else{
System.out.println("Breaking");
break;
}
}
i+= count+1;
if(count>0){
String add = begin + "";
int tempcount = count +1;
results+= tempcount + add;
}
else{
results+= begin;
}
count=0;
}
System.out.println(results);
I tested this output with Hello and the result was He2lo
also tested with hellooopppppp result he2l3o6p
If you don't understand how this works, you should learn regular expressions.
public String rleEncodeString(String in) {
StringBuilder out = new StringBuilder();
Pattern p = Pattern.compile("((\\w)\\2*)");
Matcher m = p.matcher(in);
while(m.find()) {
if(m.group(1).length() > 1) {
out.append(m.group(1).length());
}
out.append(m.group(2));
}
return out.toString();
}
Try something like this:
public static void main(String[] args) {
System.out.println("Enter a string:");
Scanner IO = new Scanner(System.in);
// read in user input
String userString = IO.nextLine() + "-";
int length = userString.length();
int count = 0;
String result = "";
char new_char;
for (int i = 0; i < length; i++) {
new_char = userString.charAt(i);
count++;
if (new_char != userString.charAt(i + 1)) {
if (count != 1) {
result = result.concat(Integer.toString(count + 1));
}
result = result.concat(Character.toString(new_char));
count = 0;
}
if (userString.charAt(i + 1) == '-')
break;
}
System.out.println(result);
}
The problem is that your code checks if the previous letter, not the next, is the same as the current.
Your for loops basically goes through each letter in the string, and if it is the same as the previous letter, it figures out how many of that letter there is and puts that number into the result string. However, for a word like "hello", it will check 'e' and 'l' (and notice that they are preceded by 'h' and 'e', receptively) and think that there is no repeat. It will then get to the next 'l', and then see that it is the same as the previous letter. It will put '2' in the result, but too late, resulting in "hel2l" instead of "he2lo".
To clean up and fix your code, I recommend the following to replace your for loop:
int count = 1;
String result = "";
for(int i=0;i<length;i++) {
if(i < userString.length()-1 && userString.charAt(i) == userString.charAt(i+1))
count++;
else {
if(count == 1)
result += userString.charAt(i);
else {
result = result + count + userString.charAt(i);
count = 1;
}
}
}
Comment if you need me to explain some of the changes. Some are necessary, others optional.
Here is the solution for the problem with better time complexity:
public static void compressString (String string) {
LinkedHashSet<String> charMap = new LinkedHashSet<String>();
HashMap<String, Integer> countMap = new HashMap<String, Integer>();
int count;
String key;
for (int i = 0; i < string.length(); i++) {
key = new String(string.charAt(i) + "");
charMap.add(key);
if(countMap.containsKey(key)) {
count = countMap.get(key);
countMap.put(key, count + 1);
}
else {
countMap.put(key, 1);
}
}
Iterator<String> iterator = charMap.iterator();
String resultStr = "";
while (iterator.hasNext()) {
key = iterator.next();
count = countMap.get(key);
if(count > 1) {
resultStr = resultStr + count + key;
}
else{
resultStr = resultStr + key;
}
}
System.out.println(resultStr);
}

Null Pointer Exceptions Without Apparent Reason

StackOverflow. I am attempting to make a program that uses a text menu to to a multitude of things to manipulate a single string. One of the methods turns the string into an array of strings. This works fine. However, all of the methods that manipulate it as an array(one prints it out, one reverses the word order, and one sorts them using an exchange sorting method) return a NullPointerException when called. I have looked all through the code and do not see where it is coming from. Here is the .Java file containing all of the code. My problem is only happening when I call the printArray(), reverse(), and sort() methods, near the bottom. Any and all help is appreciated. Sorry for the sloppy code, I have not cleaned it up yet.
Code:
/*
Computer Programming Lab 11
Jim Kimble
3 Mar 2013
Work with strings and implementing a menu.
Acknowledgements:
Uses main structure of HUTPanel as designed at UMU, 2002-2012
*/
import java.io.*;
import java.awt.*;
import javax.swing.*;
public class HUTPanel extends JPanel
{
/***************************************************
* Class-level data members should be declared here.
***************************************************/
int numVowels;
String[] words;
String str;
String vowels;
String menuChoice;
String oString = "A tong lime ago, a daggy shog bossed a cridge over a pillmond,\n"
+"When in the course of human events\n"
+"Mary had a little lamb.\n"
+"The girls' basketball team repeated as tournament champion this weekend.";
public HUTPanel(JFrame frame)
{
// Set panel background color
setBackground(Color.WHITE);
setLayout(null);
setPreferredSize(new Dimension(810, 410));
/***************************
* Now add your code below:
***************************/
// Create a frame around this panel.
frame.setTitle("Computer Programming Lab/Program # 11");
frame.getContentPane().add(this);
str = "A tong lime ago, a daggy shog bossed a cridge over a pillmond,\n"
+"When in the course of human events\n"
+"Mary had a little lamb.\n"
+"The girls' basketball team repeated as tournament champion this weekend.";
System.out.println("Lab 11: Text Manipulation");
//getTheText();
System.out.println("The string is: '"+str+"'.");
handleTheMenu();
} // end of constructor
/*************************
* Add your methods here:
*************************/
// Get a text sequence from the keyboard and put it in str
public void getTheText()
{
Boolean inputDone = false;
while (!inputDone)
{
System.out.print("Enter your text: ");
inputDone = grabText();
}
}
private Boolean grabText()
{
try {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
menuChoice = inputReader.readLine();
return true;
}
catch(IOException e)
{
System.out.println("Error reading input. Please try again.");
}
return false;
}
public void handleTheMenu()
{
int choice = -1;
Boolean OK;
while (choice != 0)
{
choice = -1;
System.out.println("Menu:");
System.out.println();
System.out.println(" 1. Count the vowels"); //"There are ... vowels in the text."
System.out.println(" 2. Remove all letter e's"); //then print it.
System.out.println(" 3. Replace all t's with '+'"); //then print it
System.out.println(" 4. Search for a requested word (will reset the string)"); //Does 'word' exist in the text?
System.out.println(" 5. Print the words on individual lines");
System.out.println(" 6. Reset the string.");//Reset the string to the original
System.out.println(" 7. Put the words in an array"); //then print it
System.out.println(" 8. Reverse the text word order"); //then print it
System.out.println(" 9. Sort the words in an array"); //Once the words are put into an array
System.out.println();
System.out.print(" 0 to quit --> ");
OK = grabText();
if (OK)
{
try
{
choice = Integer.parseInt(menuChoice);
}
catch(NumberFormatException e)
{
System.out.println("Not a number; please try again.");
System.out.println();
}
switch(choice)
{
case 0: System.out.println();
System.out.println("Thank you.");
break;
case 1: countVowels();
break;
case 2: removeAllEs();
break;
case 3: changeTToPlus();
break;
case 4: find();
break;
case 5: listWords();
break;
case 6: reset();
break;
case 7: makeArray();
break;
case 8: reverse();
break;
case 9: sort();
break;
default: System.out.println("Not a valid choice; please try again.");
}
}
}
}
private void countVowels() {
//count the vowels in str
vowels = "aeiouAEIOU";
numVowels = 0;
for( int i = 0; i < vowels.length(); i ++) {
for(int j = 0; j < str.length(); j++) {
if (str.charAt(j) == vowels.charAt(i)) {
numVowels += 1;
}
}
}
System.out.println("The string has " + numVowels + " vowels in it.");
}
private void removeAllEs() {
String str3 = str.replace('e', ' ');
System.out.print(str3);
str = str3;
}
private void changeTToPlus() {
String str2 = str.replace('t', '+');
System.out.println(str2);
str = str2;
}
private void find() {
str = oString;
getTheText();
if(str.indexOf(menuChoice) != -1)
{
System.out.println("The word " +menuChoice+ " is at index " +str.indexOf(menuChoice));
}
else
{
System.out.println("The word " +menuChoice+ " is not in the string.");
}
}
private void listWords() {
int pos = 0;
int i = 0;
while(i > -1)
{
i = str.indexOf(' ', pos);
if (i > -1)
{
System.out.println(str.substring(pos, i));
pos = i + 1;
}
}
}
private void reset() {
str = oString;
System.out.println();
System.out.println("String reset.");
System.out.println();
}
private void makeArray() {
int n = 1;
String[] words = new String[n];
int pos = 0;
int i = 0;
int j = 0;
while(j > -1)
{
for (i = 0; i < 1000; i++)
{
n += 1;
j = str.indexOf(' ', pos);
if (j > -1)
{
words[i] = str.substring(pos, j);
pos = j + 1;
}
}
}
//printArray();
}
//***FIX***
private void printArray() {
for (int k = 0; k < words.length -1; k++){
System.out.println(words[k]);
}
}
//***FIX***
private void reverse() {
int i = 0;
int j = words.length - 1;
String temp;
while (i < j){
temp = words[i];
words[i] = words[j];
words[j] = temp;
i++;
j--;
}
}
private void sort() {
String temp = "";
for (int i = 1; i < words.length - 1; i++) {
for (int j = i + 1; j < words.length; j++) {
int x = words[i].compareTo(words[j]);
if (x > 0) {
temp = words[i];
words[i] = words[j];
words[j] = temp;
}
}
}
for (int p = 0; p < words.length -1; p++) {
System.out.println(words[p]);
}
}
}
You Error is here:
private void makeArray() {
int n = 1;
String[] words = new String[n];//At This line you are creating local array words.The instance variable words is still null.
int pos = 0;
int i = 0;
int j = 0;
while(j > -1)
{
for (i = 0; i < 1000; i++)
{
n += 1;
j = str.indexOf(' ', pos);
if (j > -1)
{
words[i] = str.substring(pos, j);
pos = j + 1;
}
}
}
use:
words = new String[n]; instead of String[] words = new String[n];
As mentioned by Luiggi Mendoza in the comment section, the local variable words defined within makeArray method is shadowing the instance variable words defined within HUTPanel class.
As side note I want to point out the unnecessary creation of new BufferedReader objects in method grabText() each time you are calling it in getTheText(). It would be much efficient if your make inputReader an instance variable in your class , and instantiate it once within the constructor using inputReader = new BufferedReader(new InputStreamReader(System.in));. This way your grabText method becomes like this :
private Boolean grabText()
{
try {
//No more new object creation for BufferedReader for each call of this method.
menuChoice = inputReader.readLine();
return true;
}
catch(IOException e)
{
System.out.println("Error reading input. Please try again.");
}
return false;
}
Make sure you always you always start with option 7, so your words array gets initialized. This is in fact not something that the user should do. The application should handle it so that the user either can't select other options, or does it automatically.
Update: Vishal K is correct, but this is still a weak point in your application.

Categories