complete lab09
This commit is contained in:
8 files changed
+628
No files matched your search
@@ -4,3 +4,4 @@
|
||||
|
||||
/.idea/*
|
||||
/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