simple UDP / TCP java Hangman - java

i have an assignment to write simple game using UDP / TCP connection. I already have a simple Hangman game on java. i want the game to be played between 2 client or between server client. this is my hangman code
package gameexample;
import java.util.Arrays;
import java.util.Scanner;
public class Hangman{
public static void main(String[] args) {
String[] words = {"writer", "that", "program"};
// Pick random index of words array
int randomWordNumber = (int) (Math.random() * words.length);
// Create an array to store already entered letters
char[] enteredLetters = new char[words[randomWordNumber].length()];
int triesCount = 0;
boolean wordIsGuessed = false;
do {
// infinitely iterate through cycle as long as enterLetter returns true
// if enterLetter returns false that means user guessed all the letters
// in the word e. g. no asterisks were printed by printWord
switch (enterLetter(words[randomWordNumber], enteredLetters)) {
case 0:
triesCount++;
break;
case 1:
triesCount++;
break;
case 2:
break;
case 3:
wordIsGuessed = true;
break;
}
} while (! wordIsGuessed);
System.out.println("\nThe word is " + words[randomWordNumber] +
" You missed " + (triesCount -findEmptyPosition(enteredLetters)) +
" time(s)");
}
public static int enterLetter(String word, char[] enteredLetters) {
System.out.print("(Guess) Enter a letter in word ");
// If-clause is true if no asterisks were printed so
// word is successfully guessed
if (! printWord(word, enteredLetters))
return 3;
System.out.print(" > ");
Scanner input = new Scanner(System.in);
int emptyPosition = findEmptyPosition(enteredLetters);
char userInput = input.nextLine().charAt(0);
if (inEnteredLetters(userInput, enteredLetters)) {
System.out.println(userInput + " is already in the word");
return 2;
}
else if (word.contains(String.valueOf(userInput))) {
enteredLetters[emptyPosition] = userInput;
return 1;
}
else {
System.out.println(userInput + " is not in the word");
return 0;
}
}
asterisks were printed, otherwise return false */
public static boolean printWord(String word, char[] enteredLetters) {
// Iterate through all letters in word
boolean asteriskPrinted = false;
for (int i = 0; i < word.length(); i++) {
char letter = word.charAt(i);
// Check if letter already have been entered bu user before
if (inEnteredLetters(letter, enteredLetters))
System.out.print(letter); // If yes - print it
else {
System.out.print('*');
asteriskPrinted = true;
}
}
return asteriskPrinted;
}
public static boolean inEnteredLetters(char letter, char[] enteredLetters) {
return new String(enteredLetters).contains(String.valueOf(letter));
}
public static int findEmptyPosition(char[] enteredLetters) {
int i = 0;
while (enteredLetters[i] != '\u0000') i++;
return i;
}
}
can anyone show me how to write this code to client server program, with 2 player waiting turn for each guess? and the game is finished when one of them guess the last letter ?

Related

How to break from a loop after finding a word

I am trying to create a Hangman and I have 2 problems.
1) The first problem is when the user finds the word, the loop does not stop.
2) I have a variable attempts which allows to know the number of attempts. Even if the user finds the letter, the number of attempts decrease.
The word to find is no
Here is a demonstration:
1) I enter the letter n
You have 5 attempts.
--
Enter your letter : n
2) I enter the letter o
The letter is good.
You have 4 attempts.
n-
Enter your letter : o
3) Normally the loop should stop.
The letter is good.
You have 3 attempts.
no
Enter your letter :
If you have an idea thank you in advance.
Scanner input = new Scanner(System.in);
char letter = 0;
String[] words = {/*"yes",*/ "no"};
String word_random = words[(int) (Math.random() * words.length)];
boolean[] word_found = new boolean[word_random.length()];
int attempts = 5;
while(attempts > 0){
System.out.println("You have " + attempts + " attempts.");
for(int i=0; i<word_random.length(); i++) {
if ( word_found[i] ) {
System.out.print(word_random.charAt(i));
}
else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
for(int i=0; i<word_random.length();i++){
if(word_random.charAt(i) == letter){
System.out.println("The letter is good. ");
word_found[i] = true;
}
}
attempts--;
}
}
}
You are just missing a checking loop or method. Check the solution below.
Scanner input = new Scanner(System.in);
char letter = 0;
String[] words = {/*"yes",*/ "no"};
String word_random = words[(int) (Math.random() * words.length)];
boolean[] word_found = new boolean[word_random.length()];
int attempts = 5;
while(attempts > 0){
System.out.println("You have " + attempts + " attempts.");
for(int i=0; i<word_random.length(); i++) {
if ( word_found[i] ) {
System.out.print(word_random.charAt(i));
}
else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
for(int i=0; i<word_random.length();i++){
if(word_random.charAt(i) == letter){
System.out.println("The letter is good. ");
word_found[i] = true;
}
}
boolean done = true;
for(boolean b : word_found)
done = done && b;
if(done) break;
else attempts--;
}
I will follow to your solution, not suggest a better one.
Ad 1. Add a check if the array word found contains only true after your first for cycle and if there are only true values in the array, print "you won" and set attempts to 0
Ad 2. Move attempts-- to the else case of your first for cycle OR add attempts++ in the true case of your first for cycle
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
char letter = 0;
String[] words = { /* "yes", */ "no" };
String word_random = words[(int) (Math.random() * words.length)];
boolean[] word_found = new boolean[word_random.length()];
int attempts = 5;
while (attempts > 0) {
System.out.println("You have " + attempts + " attempts.");
for (int i = 0; i < word_random.length(); i++) {
if (word_found[i]) {
System.out.print(word_random.charAt(i));
} else {
System.out.print('-');
}
}
System.out.println("");
System.out.print("Enter your letter : ");
letter = input.next().charAt(0);
boolean match = false;
for (int i = 0; i < word_random.length(); i++) {
if (word_random.charAt(i) == letter) {
System.out.println("The letter is good. ");
word_found[i] = true;
match = true;
if (i == word_found.length - 1) {
System.out.println("THE END: attempts: " + attempts);
return;
}
}
}
if (!match) {
attempts--;
}
}
System.out.println("THE END");
}
I suggest you to modify the last part of your code like I did, and it should work.

Creating simple hangman program in java, trouble with for loop

public class Game {
public static void main(String[] args) {
String secretWord = "frog";
System.out.println("Word has " + secretWord.length() + " letters.");
System.out.println("Guess a letter: ");
int correctGuesses = 0;
int strikes = 5;
Scanner input = new Scanner(System.in);
while (strikes > 0) {
here the loop cycles through the characters in a String, and checks if the user input guessedLetter matches a char in the string. right now the loop cycles through each char starting with the first char in the string through the last, the user must guess the letters in the exact order of they are arranged in the string, how can I fix this so that any character input matching a character in the String will be correct rather than the characters having to be in order?
for (int i = 0; i < secretWord.length(); i++) {
char guessedLetter = input.next().charAt(0);
char currentLetter = secretWord.charAt(i);
if (guessedLetter == currentLetter) {
correctGuesses++;
System.out.printf("Correct Guess! %d Letters Left!\n", secretWord.length() - correctGuesses);
}
else if (guessedLetter != currentLetter) {
strikes--;
System.out.printf("Incorrect: You Have %d Chances Left..\n", strikes);
}
if (strikes == 0) {
System.out.println("You Are Out of Chances! Game over!");
}
else if (correctGuesses == secretWord.length()) {
System.out.println("You Got It! The Word is: " + secretWord);
}
}
}
}
You could try it as follows:
move all the characters of secretWord to a map (key would be the character and the value would be incidences of that character in the string).
read the character from the keyboard and interate (basically, your logic).
Here is the code.
public static void main(String[] args) {
String secretWord = "frog";
Map<Character, Integer> mapOfLetters = new HashMap<>();
for (char c : secretWord.toCharArray()) {
int count = 1;
if (mapOfLetters.containsKey(c)) {
count = mapOfLetters.get(c) + 1;
}
mapOfLetters.put(c, count);
}
System.out.println("Word has " + secretWord.length() + " letters.");
System.out.println("Guess a letter: ");
int correctGuesses = 0;
int strikes = 5;
Scanner input = new Scanner(System.in);
while (strikes > 0 && !mapOfLetters.isEmpty()) {
char guessedLetter = input.next().charAt(0);
if (mapOfLetters.containsKey(guessedLetter)) {
correctGuesses++;
System.out.printf("Correct Guess! %d Letters Left!\n", secretWord.length() - correctGuesses);
int count = mapOfLetters.get(guessedLetter) - 1;
if (count == 0) {
mapOfLetters.remove(guessedLetter);
} else {
mapOfLetters.put(guessedLetter, count);
}
} else {
strikes--;
System.out.printf("Incorrect: You Have %d Chances Left..\n", strikes);
}
}
if (strikes == 0) {
System.out.println("You Are Out of Chances! Game over!");
} else if(mapOfLetters.isEmpty()){
System.out.println("You Got It! The Word is: " + secretWord);
}
}
guessedLetter = input.next().charAt(0);
If you want to match the whole UserInput there should not be charAt(0).
On the other hand, if you just want to match any character, at first time you can test guessedLetter == currentLetter is true, then just exit program.
By the way, if you like, just google "KMP algorithm" to learn how to match String.

java source code hangman

I am having trouble with my hangman programm in java class I don't seem to get the lost lives counter to work properly and also displaying the already guessed letters that are right don't display in the sequence when you make the next correct guess.
import java.util.Scanner; //imports scanner so I could use user input
import java.util.Random; // imports random picker for words, to pick a random word
public class javaxx {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
StringBuffer sb = new StringBuffer();
StringBuffer buffer = new StringBuffer();
String wordToGuess;
int wordLength;
int wordToGuessLength;
int position;
int livesLost = 0;
int totalLives = 7;
int lettersRemaining;
boolean guessInWord;
char guess;
StringBuffer prevGuessedLetters;
//declare variable
//String wordToGuess[] = new String[29];
//insert array for words and their values
String[] myStringArray = new String[]{"programming","exhaustive","violin","selection","repetition","serendipity","watermelon","football","mobilephone","handbag","teddybear","cardigan","waterfall","cupcake","pineapple","strawberry","collection","chicken","tablecloth","candlestick","notebook","radiator","champagne","wineyard","parent","circus","snowbell","clocktower","mermaid","cardigan"};
//Display the rules of the game
System.out.println("You are playing the game Hang Man. You have to guess the letters in the word. You will see how many letters are in the word and you have 7 changes to be wrong. ");
//choose a random word from the array
wordToGuess = myStringArray[(int) (Math.random() * myStringArray.length)];
//determine the length of the word
wordLength = wordToGuess.length();
//show the player how many letters are in the word
System.out.println("The word you are quessing has " + wordLength + " letters in it");
lettersRemaining = wordLength;
for (position = 0; position < wordLength; position++) {
sb.append("_ ");
}
System.out.println(sb.toString());
//loop starts
while (lettersRemaining > 0 && livesLost < 7) {
//prompt user to guess a letter
System.out.println("Guess a letter:");
guess = myScanner.findWithinHorizon(".", 0).charAt(0);
//check if the letter guessed is in the secretWord
guessInWord = (wordToGuess.indexOf(guess)) != -1;
if (guessInWord == false) {
livesLost++;
System.out.print("Sorry, you have lost a life. You still have ");
System.out.print(totalLives -= livesLost);
System.out.println(" life/lives left. Keep trying.");
} else {
System.out.println("That was a good guess, well done!");
for (position = 0; position < wordLength; position++) {
if (wordToGuess.charAt(position) == guess) {
System.out.print(guess);
lettersRemaining--;
} else {
System.out.print("_ ");
}
}
}
System.out.println();
prevGuessedLetters = buffer.append(guess);
System.out.print("Previously guessed letters: ");
System.out.println(prevGuessedLetters);
System.out.print("Letters remaining: ");
System.out.println(lettersRemaining);
}
if (livesLost == totalLives) {
System.out.println("Sorry, you lose!");
} else {
System.out.print("Well done, you win! The word was ");
System.out.println(wordToGuess);
}
}
}
change this line
System.out.print(totalLives -= livesLost);
to
System.out.print(totalLives - livesLost);
this was the problem with liveslost counter.

How do I make a String unusable the second time in a loop?

I'm new to this site. I've decided to create a console base hangmaan game and I've been doing ok up till now. My current problem has me stuck.
I'm trying to make it so that if the user has input a letter and it has been marked as correct or incorrect. The program should then not let the user input that same letter again in later iterations of the while loop.
The comments should give you a better idea of what I'm talking about.
Can anyone please help me?
package hangMan2;
import java.io.IOException;
import java.util.Scanner;
public class mainClss {
public static void main(String[] args) {
int point = 0;
int numberOfLetterInWord;
// prompt user for input and store input into String word
System.out.println("Enter a word in lower case from the dictionary: ");
Scanner inputWord = new Scanner(System.in);
String word = inputWord.next();
// letters remaining in word equals the length of the word at the start
int lettersRemainingInWord = word.length();
for (int i = 0; i < 30; i++) {
System.out.println("\b");
}
// while points are above 7 (7 is when man is hung) and there's more
// than one letter remaining do all the following:
while (point > -7 && lettersRemainingInWord >= 1) {
//prompts user to input letter guess and stores in letter
System.out.print("\nEnter a letter for this " + word.length()
+ " letter word: ");
Scanner inputLetter = new Scanner(System.in);
String letter = inputLetter.next();
if (word.contains(letter)) {
System.out.println("Correct!");
point += 1;
System.out.println("Score: " + point);
lettersRemainingInWord -= 1;
//I need code here to remove the current letter from being able to be used again
if (lettersRemainingInWord > 0) {
continue;
}
else {
System.out.println("\nYou win!!!");
System.out.println("The word was: " + word);
break;
}
}
else {
System.out.println("Incorrect\n");
point -= 1;
System.out.println("Score: " + point);
//I need code here to remove the current letter from being able to be used again
if (lettersRemainingInWord > 0) {
continue;
}
else {
System.out.println("Game over! You lose!");
System.out.println("Score: " + point);
System.out.println("The word was: " + word);
break;
}
}
}
if (point <= -7) {
System.out.println("Game over! You lose!");
System.out.println("Score: " + point);
System.out.println("The word was: " + word);
}
}
}
You could test whether the letter is in a Set. If not, accept it and add it to the set. If so, then reject it.
Set<String> usedLetters = new HashSet<String>();
boolean isUsedLetter(String letter) {
if (usedLetters.contains(letter)) {
return true;
} else {
usedLetters.add(letter);
return false;
}
}
You can use an ArrayList to hold the characters that have already been typed and then check the list to see if the character is in there.
List<Character> used = new ArrayList<Character>();
char let = //letter that they inputted
if(used.contains(let)) {
//do something
}
else {
used.add(let);
}

How to create a Java Text-Based Hangman Game and other issues

I am creating a Hangman Game in Java and it almost works perfectly. So I have two problems. The first being that:
When the user inputs a letter and the word has repeated letters, how can I make it print both instances of the letter.
I have created a while loop however this loop does not output the Modified word until after the next go. If that makes sense?
The second problem:
I need to be able to prevent the user from entering the same letter twice
I have attempted Lists and arrays and hash sets. All sorts but none seem to work.
My code is below:
There may be other threads with same questions but none seem to help as I cannot implement it into this person's code.
import java.util.Scanner;
import java.util.Arrays;
public class Hangman{
public static void main(String []args){
Scanner Input = new Scanner(System.in);
String[] CollectionOfWords = {"","gravity","banana","gate","processor","momentum","earth","star","light","television","pan","cupboard"};
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length);
int counter = 10;
String radmWord = CollectionOfWords[radmNumber];
char[] genRadmLetter = radmWord.toCharArray();
char[] genRadmLetter2 = radmWord.toCharArray();
for (int x = 0; x<genRadmLetter.length; x++){
genRadmLetter[x]='?';
}
System.out.println(String.valueOf(genRadmLetter));
System.out.println("Hello. Guess a letter.");
char guessedLetter = Input.next().charAt(0);
int RW = radmWord.indexOf(guessedLetter);
if (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
System.out.println(genRadmLetter);
}
if (RW == -1){
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
while (counter != 0) {
System.out.println("Guess a letter.");
guessedLetter = Input.next().charAt(0);
RW = radmWord.indexOf(guessedLetter);
if (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
System.out.println(genRadmLetter);
}
if (RW == -1){
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
} else {
System.out.println(genRadmLetter);
while (RW >= 0 ){
genRadmLetter[RW] = guessedLetter;
RW = radmWord.indexOf(guessedLetter, RW+1);
}
}
boolean result = Arrays.equals(genRadmLetter, genRadmLetter2);
if (result == true){
break;
}
if (counter == 0){
break;
}
}
if (counter == 0){
System.out.println("You lose. The word was: " + radmWord);
}
else {
System.out.println("Well done, you have guessed the word.");
System.out.println("Your final score is: " + counter);
}
}
}
Instead of using...
int RW = radmWord.indexOf(guessedLetter);
To determine if the entered value matches a character, which will only return the first index, you should, instead, use a loop of some kind to check every character
boolean found = false;
for (int rw = 0; rw < genRadmLetter2.length; rw++) {
if (genRadmLetter2[rw] == guessedLetter) {
genRadmLetter[rw] = guessedLetter;
found = true;
}
}
Now, because you're relying on the value of RW to determine if a match was found or not, I changed it so that the boolean found flag can used instead, for example...
if (!found) {
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
You also have duplicate sets of code, which can be reduced to a single do-while loop instead, which will make it easier to read and make changes, for example...
do {
//...
} while (counter != 0);
To your second problem, a Set of some kind would be the simplest solution...
Set<Character> guesses = new HashSet<Character>();
//...
char guessedLetter = Input.next().charAt(0);
if (guesses.contains(guessedLetter)) {
System.out.println("You've used this guess, guess again");
} else {
guesses.add(guessedLetter);
For example...
And because it's not always easy to translate code snippets ... this is my test code...
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Hangman {
public static void main(String[] args) {
Scanner Input = new Scanner(System.in);
String[] CollectionOfWords = {"", "gravity", "banana", "gate", "processor", "momentum", "earth", "star", "light", "television", "pan", "cupboard"};
int radmNumber = (int) Math.ceil(Math.random() * CollectionOfWords.length);
int counter = 10;
String radmWord = "banana"; //CollectionOfWords[radmNumber];
char[] genRadmLetter = radmWord.toCharArray();
char[] genRadmLetter2 = radmWord.toCharArray();
for (int x = 0; x < genRadmLetter.length; x++) {
genRadmLetter[x] = '?';
}
Set<Character> guesses = new HashSet<Character>();
do {
System.out.println("Guess a letter.");
System.out.println(String.valueOf(genRadmLetter));
System.out.println("Hello. Guess a letter.");
char guessedLetter = Input.next().charAt(0);
if (guesses.contains(guessedLetter)) {
System.out.println("You've used this guess, guess again");
} else {
guesses.add(guessedLetter);
boolean found = false;
for (int rw = 0; rw < genRadmLetter2.length; rw++) {
if (genRadmLetter2[rw] == guessedLetter) {
genRadmLetter[rw] = guessedLetter;
found = true;
}
}
if (!found) {
System.out.println("Wrong letter, try again.");
counter = counter - 1;
System.out.println("Lives left: " + counter);
}
}
boolean result = Arrays.equals(genRadmLetter, genRadmLetter2);
if (result == true) {
break;
}
if (counter == 0) {
break;
}
} while (counter != 0);
if (counter == 0) {
System.out.println("You lose. The word was: " + radmWord);
} else {
System.out.println("Well done, you have guessed the word.");
System.out.println("Your final score is: " + counter);
}
}
}
There are multiple issues with the code:
the typical beginners problem of length vs. max element number
unnecessary duplicate code
a logic issue with the output
as for 1.:
you are using this:
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length)
if you use
int radmNumber = (int) Math.ceil (Math.random() * CollectionOfWords.length-1)
you can start the arrey without a empty string and it wont randomly crash
on to 2.
you wont need to duplicate the input code if you use this:
System.out.println(String.valueOf(genRadmLetter));
System.out.print("Hello.");
char guessedLetter;
int RW;
while (counter != 0)
{
System.out.println("Guess a letter.");
...
and finally 3.(your main question)
you do the output before changing it. so this fixes your problem:
...
else
{
while (RW >= 0)
{
genRadmLetter[RW] = guessedLetter;
RW = radmWord.indexOf(guessedLetter, RW + 1);
}
System.out.println(genRadmLetter);
}
So simply move the output behind the while.
I made a little helper clas that could help you...
static class GuessString {
private char[] mask;
private String solution;
private boolean lastGuessResult;
GuessString(String word) {
this.solution = word;
this.mask=word.toCharArray();
Arrays.fill(mask, '?'); // Build a mask like: ??????
}
public String guess(char guess) {
char c = Character.toLowerCase(guess); // case insensitive
int i = solution.indexOf(c);
lastGuessResult = i != -1; // -1 means "not found)
if (lastGuessResult)
while (i != -1) { // this will loop till c is replaced everywhere.
mask[i] = c;
i = solution.indexOf(c, i+1);
}
return new String(mask); // return the updated mask.
}
public boolean lastGuessIsRight() {
return lastGuessResult;
}
public String getCurrent() {
return new String(mask);
}
public boolean isSolved() {
return getCurrent().equals(solution);
}
}

Categories

Resources