complete lab09
This commit is contained in:
8 files changed
+628
No files matched your search
@@ -4,3 +4,4 @@
|
|||||||
|
|
||||||
/.idea/*
|
/.idea/*
|
||||||
/src/code/ca/bcit/comp2522/testing/*
|
/src/code/ca/bcit/comp2522/testing/*
|
||||||
|
/data/logs/*
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
Afghanistan
|
||||||
|
Albania
|
||||||
|
Algeria
|
||||||
|
Andorra
|
||||||
|
Angola
|
||||||
|
Antigua and Barbuda
|
||||||
|
Argentina
|
||||||
|
Armenia
|
||||||
|
Australia
|
||||||
|
Austria
|
||||||
|
Azerbaijan
|
||||||
|
Bahamas
|
||||||
|
Bahrain
|
||||||
|
Bangladesh
|
||||||
|
Barbados
|
||||||
|
Belarus
|
||||||
|
Belgium
|
||||||
|
Belize
|
||||||
|
Benin
|
||||||
|
Bhutan
|
||||||
|
Bolivia
|
||||||
|
Bosnia and Herzegovina
|
||||||
|
Botswana
|
||||||
|
Brazil
|
||||||
|
Brunei
|
||||||
|
Bulgaria
|
||||||
|
Burkina Faso
|
||||||
|
Burundi
|
||||||
|
Cabo Verde
|
||||||
|
Cambodia
|
||||||
|
Cameroon
|
||||||
|
Canada
|
||||||
|
Central African Republic
|
||||||
|
Chad
|
||||||
|
Chile
|
||||||
|
China
|
||||||
|
Colombia
|
||||||
|
Comoros
|
||||||
|
Congo (Congo-Brazzaville)
|
||||||
|
Costa Rica
|
||||||
|
Croatia
|
||||||
|
Cuba
|
||||||
|
Cyprus
|
||||||
|
Czechia
|
||||||
|
Democratic Republic of the Congo
|
||||||
|
Denmark
|
||||||
|
Djibouti
|
||||||
|
Dominica
|
||||||
|
Dominican Republic
|
||||||
|
Ecuador
|
||||||
|
Egypt
|
||||||
|
El Salvador
|
||||||
|
Equatorial Guinea
|
||||||
|
Eritrea
|
||||||
|
Estonia
|
||||||
|
Eswatini
|
||||||
|
Ethiopia
|
||||||
|
Fiji
|
||||||
|
Finland
|
||||||
|
France
|
||||||
|
Gabon
|
||||||
|
Gambia
|
||||||
|
Georgia
|
||||||
|
Germany
|
||||||
|
Ghana
|
||||||
|
Greece
|
||||||
|
Grenada
|
||||||
|
Guatemala
|
||||||
|
Guinea
|
||||||
|
Guinea-Bissau
|
||||||
|
Guyana
|
||||||
|
Haiti
|
||||||
|
Honduras
|
||||||
|
Hungary
|
||||||
|
Iceland
|
||||||
|
India
|
||||||
|
Indonesia
|
||||||
|
Iran
|
||||||
|
Iraq
|
||||||
|
Ireland
|
||||||
|
Israel
|
||||||
|
Italy
|
||||||
|
Jamaica
|
||||||
|
Japan
|
||||||
|
Jordan
|
||||||
|
Kazakhstan
|
||||||
|
Kenya
|
||||||
|
Kiribati
|
||||||
|
Kuwait
|
||||||
|
Kyrgyzstan
|
||||||
|
Laos
|
||||||
|
Latvia
|
||||||
|
Lebanon
|
||||||
|
Lesotho
|
||||||
|
Liberia
|
||||||
|
Libya
|
||||||
|
Liechtenstein
|
||||||
|
Lithuania
|
||||||
|
Luxembourg
|
||||||
|
Madagascar
|
||||||
|
Malawi
|
||||||
|
Malaysia
|
||||||
|
Maldives
|
||||||
|
Mali
|
||||||
|
Malta
|
||||||
|
Marshall Islands
|
||||||
|
Mauritania
|
||||||
|
Mauritius
|
||||||
|
Mexico
|
||||||
|
Micronesia
|
||||||
|
Moldova
|
||||||
|
Monaco
|
||||||
|
Mongolia
|
||||||
|
Montenegro
|
||||||
|
Morocco
|
||||||
|
Mozambique
|
||||||
|
Myanmar
|
||||||
|
Namibia
|
||||||
|
Nauru
|
||||||
|
Nepal
|
||||||
|
Netherlands
|
||||||
|
New Zealand
|
||||||
|
Nicaragua
|
||||||
|
Niger
|
||||||
|
Nigeria
|
||||||
|
North Korea
|
||||||
|
North Macedonia
|
||||||
|
Norway
|
||||||
|
Oman
|
||||||
|
Pakistan
|
||||||
|
Palau
|
||||||
|
Palestine
|
||||||
|
Panama
|
||||||
|
Papua New Guinea
|
||||||
|
Paraguay
|
||||||
|
Peru
|
||||||
|
Philippines
|
||||||
|
Poland
|
||||||
|
Portugal
|
||||||
|
Qatar
|
||||||
|
Romania
|
||||||
|
Russia
|
||||||
|
Rwanda
|
||||||
|
Saint Kitts and Nevis
|
||||||
|
Saint Lucia
|
||||||
|
Saint Vincent and the Grenadines
|
||||||
|
Samoa
|
||||||
|
San Marino
|
||||||
|
Sao Tome and Principe
|
||||||
|
Saudi Arabia
|
||||||
|
Senegal
|
||||||
|
Serbia
|
||||||
|
Seychelles
|
||||||
|
Sierra Leone
|
||||||
|
Singapore
|
||||||
|
Slovakia
|
||||||
|
Slovenia
|
||||||
|
Solomon Islands
|
||||||
|
Somalia
|
||||||
|
South Africa
|
||||||
|
South Korea
|
||||||
|
South Sudan
|
||||||
|
Spain
|
||||||
|
Sri Lanka
|
||||||
|
Sudan
|
||||||
|
Suriname
|
||||||
|
Sweden
|
||||||
|
Switzerland
|
||||||
|
Syria
|
||||||
|
Tajikistan
|
||||||
|
Tanzania
|
||||||
|
Thailand
|
||||||
|
Timor-Leste
|
||||||
|
Togo
|
||||||
|
Tonga
|
||||||
|
Trinidad and Tobago
|
||||||
|
Tunisia
|
||||||
|
Turkey
|
||||||
|
Turkmenistan
|
||||||
|
Tuvalu
|
||||||
|
Uganda
|
||||||
|
Ukraine
|
||||||
|
United Arab Emirates
|
||||||
|
United Kingdom
|
||||||
|
United States
|
||||||
|
Uruguay
|
||||||
|
Uzbekistan
|
||||||
|
Vanuatu
|
||||||
|
Vatican City
|
||||||
|
Venezuela
|
||||||
|
Vietnam
|
||||||
|
Yemen
|
||||||
|
Zambia
|
||||||
|
Zimbabwe
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
COUNTRY=14
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package ca.bcit.comp2522.lab09;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles loading, tracking, and saving the player's best score.
|
||||||
|
*
|
||||||
|
* @author Nico Agostini
|
||||||
|
* @author Braeden Sowinski
|
||||||
|
* @author Trishaan Shetty
|
||||||
|
* @author Calvin Arifianto
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
public class HighScoreService
|
||||||
|
{
|
||||||
|
private static final String FILE_PATH = "./data/highscore.txt";
|
||||||
|
private static final String PREFIX = "COUNTRY=";
|
||||||
|
|
||||||
|
private final BufferedWriter writer;
|
||||||
|
private final int highScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a HighScoreService and loads the stored high score.
|
||||||
|
*
|
||||||
|
* @throws IOException if the high score file cannot be read or created.
|
||||||
|
*/
|
||||||
|
public HighScoreService()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
final File scoreFile;
|
||||||
|
final BufferedReader reader;
|
||||||
|
final String line;
|
||||||
|
|
||||||
|
scoreFile = new File(FILE_PATH);
|
||||||
|
scoreFile.createNewFile();
|
||||||
|
|
||||||
|
reader = new BufferedReader(new FileReader(FILE_PATH));
|
||||||
|
line = reader.readLine();
|
||||||
|
|
||||||
|
if (line == null)
|
||||||
|
{
|
||||||
|
this.highScore = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.highScore = Integer.parseInt(line.replaceAll(PREFIX, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
this.writer = new BufferedWriter(new FileWriter(FILE_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current high score.
|
||||||
|
*
|
||||||
|
* @return the saved high score.
|
||||||
|
*/
|
||||||
|
public int getHighScore()
|
||||||
|
{
|
||||||
|
return this.highScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the high score if the new score is better.
|
||||||
|
*
|
||||||
|
* @param newScore the new score to compare.
|
||||||
|
*/
|
||||||
|
public void updateCurrentScore(final int newScore)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (newScore < this.highScore)
|
||||||
|
{
|
||||||
|
this.writer.write(PREFIX + newScore);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.writer.write(PREFIX + this.highScore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.err.printf("Failed to update high score: %s\n", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the high score file.
|
||||||
|
*/
|
||||||
|
public void saveHighScore()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
System.err.println("Error closing the writer: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package ca.bcit.comp2522.lab09;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and writes game logs for each play session.
|
||||||
|
* Each guess and outcome is recorded with a timestamp.
|
||||||
|
*
|
||||||
|
* @author Nico Agostini
|
||||||
|
* @author Braeden Sowinski
|
||||||
|
* @author Trishaan Shetty
|
||||||
|
* @author Calvin Arifianto
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
public class LoggerService
|
||||||
|
{
|
||||||
|
private static final Path BASE_PATH = Paths.get("data", "logs");
|
||||||
|
private static final String DATE_PATTERN = "YYYY-MM-dd_HH-mm-ss";
|
||||||
|
|
||||||
|
private final BufferedWriter writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getDateTime returns a string of the
|
||||||
|
* date and time for the logs
|
||||||
|
* @return date time string formatted as the pattern
|
||||||
|
*/
|
||||||
|
private static String getDateTime()
|
||||||
|
{
|
||||||
|
final LocalDateTime now;
|
||||||
|
final DateTimeFormatter formatter;
|
||||||
|
|
||||||
|
now = LocalDateTime.now();
|
||||||
|
formatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
|
||||||
|
|
||||||
|
return now.format(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new log file for a game session.
|
||||||
|
*
|
||||||
|
* @param country the correct word used in the round.
|
||||||
|
* @throws IOException if the log directory or file cannot be created.
|
||||||
|
*/
|
||||||
|
public LoggerService(final String country)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
Files.createDirectories(BASE_PATH);
|
||||||
|
|
||||||
|
final String logFilename = BASE_PATH + "/" + getDateTime() + "_" + country + ".txt";
|
||||||
|
|
||||||
|
this.writer = new BufferedWriter(new FileWriter(logFilename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a log entry.
|
||||||
|
*
|
||||||
|
* @param guess the player's guess.
|
||||||
|
* @param outcome the result of the guess.
|
||||||
|
*/
|
||||||
|
public void log(final String guess, final String outcome)
|
||||||
|
{
|
||||||
|
final StringBuilder log = new StringBuilder();
|
||||||
|
|
||||||
|
log.append(getDateTime());
|
||||||
|
log.append(" Guess: ");
|
||||||
|
log.append(guess);
|
||||||
|
log.append(" Outcome: ");
|
||||||
|
log.append(outcome);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.writer.write(log.toString());
|
||||||
|
this.writer.newLine();
|
||||||
|
}
|
||||||
|
catch (final IOException e)
|
||||||
|
{
|
||||||
|
System.err.printf("Failed to write to log: %s\n", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves and closes the log file.
|
||||||
|
*/
|
||||||
|
public void saveLog()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
System.err.println("Error closing the writer: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
package ca.bcit.comp2522.lab09;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game controller for Lucky Vault. Generates a random word and manages gameplay.
|
||||||
|
* Tracks user guesses, logging, and high score updates.
|
||||||
|
*
|
||||||
|
* @author Nico Agostini
|
||||||
|
* @author Braeden Sowinski
|
||||||
|
* @author Trishaan Shetty
|
||||||
|
* @author Calvin Arifianto
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
public class LuckyVault
|
||||||
|
{
|
||||||
|
private static final int STARTING_VALUE = 0;
|
||||||
|
private static final int INVALID_MATCH = -1;
|
||||||
|
|
||||||
|
private final String country;
|
||||||
|
private final LoggerService logger;
|
||||||
|
private final HighScoreService highScore;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* matchingChars checks how many characters match two
|
||||||
|
* given strings
|
||||||
|
* @param s1 string one to match
|
||||||
|
* @param s2 string two to match
|
||||||
|
* @return number of characters matching (same position)
|
||||||
|
*/
|
||||||
|
private static int matchingChars(
|
||||||
|
final String s1,
|
||||||
|
final String s2
|
||||||
|
) {
|
||||||
|
if (s1.length() != s2.length())
|
||||||
|
{
|
||||||
|
return INVALID_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
int matched = STARTING_VALUE;
|
||||||
|
|
||||||
|
for (int i = 0; i < s1.length(); i++)
|
||||||
|
{
|
||||||
|
if (s1.charAt(i) == s2.charAt(i))
|
||||||
|
{
|
||||||
|
matched++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a LuckyVault game with a random word.
|
||||||
|
*
|
||||||
|
* @throws IOException if files are missing or unreadable.
|
||||||
|
*/
|
||||||
|
public LuckyVault()
|
||||||
|
throws IOException, FileNotFoundException
|
||||||
|
{
|
||||||
|
final WordList countries = new WordList("./data/countries.txt");
|
||||||
|
|
||||||
|
this.country = countries.getRandomWord();
|
||||||
|
this.logger = new LoggerService(this.country);
|
||||||
|
this.highScore = new HighScoreService();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the game session.
|
||||||
|
*/
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
final Scanner inputScanner = new Scanner(System.in);
|
||||||
|
String input;
|
||||||
|
int attempts = STARTING_VALUE;
|
||||||
|
|
||||||
|
System.out.println("Lucky Vault — COUNTRY MODE. Type QUIT to exit.");
|
||||||
|
System.out.printf("Secret Word Length: %d\n", country.length());
|
||||||
|
System.out.println("Current Best: " + (this.highScore.getHighScore() == Integer.MAX_VALUE ?
|
||||||
|
"-" : this.highScore.getHighScore()));
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
System.out.print("Your guess: ");
|
||||||
|
input = inputScanner.nextLine();
|
||||||
|
|
||||||
|
if (input.isEmpty())
|
||||||
|
{
|
||||||
|
System.out.println("Empty guess. Try again.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(input.equalsIgnoreCase("QUIT"))
|
||||||
|
{
|
||||||
|
System.out.println("Bye!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
if (input.length() != this.country.length())
|
||||||
|
{
|
||||||
|
System.out.printf("Wrong length (%d). Need %d\n", input.length(), this.country.length());
|
||||||
|
this.logger.log(input, "wrong_length");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.equalsIgnoreCase(this.country))
|
||||||
|
{
|
||||||
|
final int matching = matchingChars(input, this.country);
|
||||||
|
|
||||||
|
System.out.printf("Not it. %d letter(s) correct (correct position).\n", matching);
|
||||||
|
this.logger.log(input, "matches=" + matching);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("Correct in %d attempts! Word was: %s\n", attempts, this.country);
|
||||||
|
|
||||||
|
this.logger.log(input, "CORRECT_in=" + attempts);
|
||||||
|
this.highScore.updateCurrentScore(attempts);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputScanner.close();
|
||||||
|
this.logger.saveLog();
|
||||||
|
this.highScore.saveHighScore();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package ca.bcit.comp2522.lab09;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the Lucky Vault game.
|
||||||
|
*
|
||||||
|
* @author Nico Agostini
|
||||||
|
* @author Braeden Sowinski
|
||||||
|
* @author Trishaan Shetty
|
||||||
|
* @author Calvin Arifianto
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
public class Main
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Starts the Lucky Vault application.
|
||||||
|
*
|
||||||
|
* @param args command line arguments (unused).
|
||||||
|
*/
|
||||||
|
public static void main(final String[] args)
|
||||||
|
{
|
||||||
|
final LuckyVault vault;
|
||||||
|
|
||||||
|
try {
|
||||||
|
vault = new LuckyVault();
|
||||||
|
}
|
||||||
|
catch (final IOException e)
|
||||||
|
{
|
||||||
|
System.err.printf("An error occurred during an IO operation: %s\n", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vault.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package ca.bcit.comp2522.lab09;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a list of words from a text file and provides random selection.
|
||||||
|
* @author Nico Agostini
|
||||||
|
* @author Braeden Sowinski
|
||||||
|
* @author Trishaan Shetty
|
||||||
|
* @author Calvin Arifianto
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
public class WordList
|
||||||
|
{
|
||||||
|
private final List<String> wordList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a word list by reading each line of the given file.
|
||||||
|
*
|
||||||
|
* @param filePath the file containing words.
|
||||||
|
* @throws FileNotFoundException if the file cannot be opened.
|
||||||
|
*/
|
||||||
|
public WordList(final String filePath)
|
||||||
|
throws FileNotFoundException
|
||||||
|
{
|
||||||
|
this.wordList = new ArrayList<>();
|
||||||
|
|
||||||
|
final Scanner fileScanner;
|
||||||
|
final File file = new File(filePath);
|
||||||
|
|
||||||
|
fileScanner = new Scanner(file);
|
||||||
|
|
||||||
|
while (fileScanner.hasNextLine())
|
||||||
|
{
|
||||||
|
this.wordList.add(fileScanner.nextLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
fileScanner.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random word from the list.
|
||||||
|
*
|
||||||
|
* @return a randomly selected word.
|
||||||
|
*/
|
||||||
|
public String getRandomWord()
|
||||||
|
{
|
||||||
|
final Random rand = new Random();
|
||||||
|
|
||||||
|
return this.wordList.get(rand.nextInt(this.wordList.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user