// project Made By: Night9O/Naito
// Hello :D thank you for checking my code, please i very much appreciate constructive criticism and opinions
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
public class GuessTheName
{
public static void main(String[] args) throws IOException {
int PlayerLevel = 1; // the level of the player
int PlayerGuesses = 0; //how many time the player guessed right (player score)
int ChosenLength = 2; //the minimum amount of alphabets a name can have is 2.
System.out.println("Welcome to my minigame: Guess My Name");
System.out.println("you have to guess a specific name chosen by the system ");
System.out.println("you have 15 tries in order to guess 1 name");
System.out.println("the game will start easy and become harder with each level");
System.out.println("if you guessed 2 names right you level will increase and the difficulty with it ");
System.out.println("Try to guess as much names as possible, Good luck!");
System.out.println("--------------------------------------------------------------------------");
System.out.println("Please be careful: ");
System.out.print("write one alphabet, if you write multiple alphabets,");
System.out.println(" only the first character will be considered");
System.out.println("Also the name may contain hyphens (-)");
System.out.println("--------------------------------------------------------------------------");
System.out.println("");
System.out.println("");
GameLoop(PlayerLevel,ChosenLength, PlayerGuesses);
}
public static String RandomNameGenerator(int PlayerLevel, int ChosenLength) throws IOException {
// the File.txt has organized names, meaning that each line contains a name
//the idea here is to get a random integer, use that random integer as index (expl 10 = line 10 = name number 10)
String randomName = "";
int txtnumlines = 0; // how many lines the txt file has (equivalent of how many names the file has)
ArrayList<String> AllNames = new ArrayList<>(); //array that stores all names
Scanner file = new Scanner(new File("Names.txt")); //loads the txt file
// we will store all names in a list to make things easier, and we will count the number of name the file has
while (file.hasNext()) //counts the number of lines + puts each name in the list
{
String names = file.nextLine();
txtnumlines += 1;
if (!names.equals("\n")) //remove any potential empty indexes in the list
{
AllNames.add(names);
}
}
// now we will shuffle randomly the Array list
Collections.shuffle(AllNames); //shuffles randomly the list
// to make the game interesting, i made a method that checks the player level and then decide the difficulty
// of the name based on a Probability Distribution table, you can check that table in the source code folder
// the name of the method is NameLength Probability
ChosenLength = NameLengthProbability(PlayerLevel, ChosenLength); //the amount of characters/alphabets the name
// will have
for (int i = 0; i < AllNames.size(); i++)
//tell the compiler to get the first name that has the same character number as the chosenlength variable
{
if (ChosenLength == AllNames.get(i).length())
{
randomName = AllNames.get(i);
break;
}
}
// for some reasons the compiler add empty spaces after name,
// expl : jhon'' jhon has 4 alphabets but compiler outputs 5 thanks to these spaces
StringBuffer sbf = new StringBuffer(randomName);
for (int i = 0; i < randomName.length(); i++)
{
if (randomName.charAt(i) == ' ') // remove any annoying spaces the name might have
{
sbf.deleteCharAt(i);
}
}
randomName = sbf.toString();
file.close();
return randomName;
}
public static int NameLengthProbability(int PlayerLevel, int ChosenLength) //Used in randomName Generator method
{
Random random = new Random();
// check the Probability Distribution Table for this section can't explain this in comments :V
int Probability = random.nextInt(100);
if (PlayerLevel == 1)
{
if (Probability <= 60) { ChosenLength = NextIntInRange(2, 4); }
else if (Probability <= 90) { ChosenLength = NextIntInRange(5, 7); }
else if (Probability <= 95) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(11, 13); }
return ChosenLength;
}
if (PlayerLevel == 2)
{
if (Probability <= 40) { ChosenLength = NextIntInRange(2, 4); }
else if (Probability <= 80) { ChosenLength = NextIntInRange(5, 7); }
else if (Probability <= 90) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 95) { ChosenLength = NextIntInRange(11, 13); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(13, 15); }
return ChosenLength;
}
if (PlayerLevel == 3)
{
if (Probability <= 30) { ChosenLength = NextIntInRange(2, 4); }
else if (Probability <= 70) { ChosenLength = NextIntInRange(5, 7); }
else if (Probability <= 85) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 95) { ChosenLength = NextIntInRange(11, 13); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(13, 15); }
return ChosenLength;
}
if (PlayerLevel == 4)
{
if (Probability <= 10) { ChosenLength = NextIntInRange(2, 4); }
else if (Probability <= 60) { ChosenLength = NextIntInRange(5, 7); }
else if (Probability <= 80) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 90) { ChosenLength = NextIntInRange(11, 13); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(13, 15); }
return ChosenLength;
}
if (PlayerLevel == 5)
{
if (Probability <= 0) { ChosenLength = NextIntInRange(2, 4); }
else if (Probability <= 45) { ChosenLength = NextIntInRange(5, 7); }
else if (Probability <= 75) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 95) { ChosenLength = NextIntInRange(11, 13); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(13, 15); }
return ChosenLength;
}
if (PlayerLevel == 6)
{
if (Probability <= 0) { ChosenLength = NextIntInRange(2, 4); }
else if (Probability <= 20) { ChosenLength = NextIntInRange(5, 7); }
else if (Probability <= 60) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 90) { ChosenLength = NextIntInRange(11, 13); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(13, 15); }
return ChosenLength;
}
if (PlayerLevel == 7)
{
if (Probability <= 0) { ChosenLength = NextIntInRange(2, 7); } // both (2,4) and (5,7) are 0%
else if (Probability <= 40) { ChosenLength = NextIntInRange(8, 10); }
else if (Probability <= 80) { ChosenLength = NextIntInRange(11, 13); }
else if (Probability <= 100) { ChosenLength = NextIntInRange(13, 15); }
return ChosenLength;
}
return ChosenLength;
}
private static int NextIntInRange(int min, int max) //used in NameLengthProbability Method
//simple algorithm to generate a random integer between a min and max variables (min <= x <= max)
{
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
return (int)(Math.random() * ((max - min) + 1)) + min;
}
public static String PlayerHelper(String randomName)
{
//this method will try to help the player by giving him some hints, like the place of a certain character
Random random = new Random();
String HelperString = randomName; // the output of the function expl: "M---I-"
StringBuffer sbf = new StringBuffer(HelperString);
int RandomChar1 = random.nextInt(randomName.length()); // choose a random alphabet to help the player
char CharHelper = sbf.charAt(RandomChar1); //spot that helper char using the previous int as an index
String dots = "-".repeat(sbf.length());
sbf.replace(0, sbf.length(), dots); // make the HelperString as this format: "----------"
sbf.setCharAt(RandomChar1, CharHelper); // change the - with the chosen random alphabets in the right place
HelperString = sbf.toString();
return HelperString;
}
public static String Arranger(String randomName, char UserInput, String HelperString)
//takes user input, find if he can place the character if yes put it in the appropriate place
{
// reminder : HelperString is the variable that outputs the user's progress example : ---m-i
StringBuffer sbf = new StringBuffer(HelperString);
for (int i = 0; i < randomName.length(); i++)
{
if (UserInput == randomName.charAt(i))
//if the player guessed one character right, implement it in the right place
{
if (HelperString.charAt(i) == '-') // to avoid breaking in a letter that is already shown/implemented
{
sbf.setCharAt(i, UserInput);
break;
}
}
}
HelperString = sbf.toString();
return HelperString;
}
public static void GameLoop(int PlayerLevel, int ChosenLength, int PlayerGuesses) throws IOException
// this method will handle the while loops and the interaction with the user
{
Scanner input = new Scanner(System.in);
int TurnsLeft = 20; // how many turns the player has in order to guess one name
while (TurnsLeft != 0) // this loop is for switching names if the player guessed right
{
ArrayList<Character> TriedCharacters = new ArrayList<>(); //a list to store inputted characters
String randomName = RandomNameGenerator(PlayerLevel, ChosenLength).toLowerCase(); //generates a random name
String HelperString = PlayerHelper(randomName);
System.out.println("The name contains "+ randomName.length() + " letters");
System.out.println("The name has this format: " + HelperString);
for (int i = 0; i < randomName.length(); i++) //checks if there is a hyphen in the name
{
if (randomName.charAt(i) == '-')
{
System.out.println("This name has one hyphen");
}
}
for (int i = 0; i < randomName.length(); i++) //checks if there are repetitive alphabets
{
for (int j = i + 1; j < randomName.length(); j++)
{
if (randomName.charAt(i) == randomName.charAt(j))
{
System.out.println("This name has repetitive alphabets");
break;
}
}
}
while (TurnsLeft != 0) // this loop is designed for when the player is in the process of guessing one name
{
char UserInput = input.nextLine().charAt(0); // catches the user character input
HelperString = Arranger(randomName, UserInput, HelperString);
//takes user input, find if he can place the character if yes put it in the appropriate place
TurnsLeft -= 1;
System.out.println("Turns Left: " + TurnsLeft);
TriedCharacters.add(UserInput); // add the Alphabets that the User has inputted during the guessing
Collections.sort(TriedCharacters); //sort the arraylist (ascending order)
System.out.println(TriedCharacters); //gives the player a list of characters that he already tried
System.out.println(HelperString); //shows the progress of the user
if (randomName.equals(HelperString))
{
System.out.println("Good Job!, you guessed right");
TurnsLeft = 20;
PlayerGuesses += 1;
PlayerLevel = PlayerLevel(PlayerGuesses, PlayerLevel);
System.out.println("System will generate another name for you to guess it ;)");
break;
}
if (TurnsLeft == 0) {
System.out.println("you have wasted all you tries, game over.Your score: " + PlayerGuesses);
System.out.println("The name is: " + randomName);
}
}
}
}
public static int PlayerLevel(int PlayerGuesses, int PlayerLevel)
// Updates the player level during the game.
{
// for every 2 right guesses the level increments
if ((PlayerGuesses % 2) == 0 || PlayerGuesses == 15) // if the number is pair increment the level
// the final level is 15 so it's not pair, we need to add that or statement
{
PlayerLevel += 1;
}
return PlayerLevel;
}
}