Files
minesweeper-comp2522/src/code/ca/bcit/comp2522/project/WordGame.java
T
2025-11-28 00:11:21 -08:00

264 lines
7.6 KiB
Java

package ca.bcit.comp2522.project;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
/**
* WordGame asks NUMBER_OF_QUESTIONS where you are
* either asked about a country by capital,
* asked about a capital by country,
* or asked about a country by a random fact.
*
* Score is kept and saved
* @author Braeden Sowinski
* @version 1.0.0
*/
public class WordGame
{
private static final String SCORE_PATH = "./data/score.txt";
private static final int NUMBER_OF_QUESTIONS = 10;
private static final int QUESTION_NUM_OFFSET = 1;
private static final int QUEST_ASK_CAPITAL = 0;
private static final int QUEST_ASK_COUNTRY = 1;
private static final int QUEST_ASK_FACT = 2;
private static final int QUESTION_TYPES = 3;
private static final int MAX_ATTEMPTS = 2;
private static final int FIRST_ATTEMPT = 0;
private static final int SPLIT_DATE = 0;
private static final int SPLIT_TIME = 1;
private static final int FIRST_ATTEMPT_SCORE = 0;
private static final int SECOND_ATTEMPT_SCORE = 1;
private static final int INCORRECT_SCORE = 2;
private static final int DEFAULT_SCORE = 0;
private final World world;
/**
* WordGame constructor creates a World class to
* access Countries and their details.
* @throws IOException if World failed to read countries
*/
public WordGame()
throws IOException
{
this.world = new World();
}
/*
* checkAnswer reads user input and compares it to
* a given correct answer and updates scores accordingly.
* @param correctAnswer to check user input to
* @param scanner to read user input from
* @param scores to update accordingly
*/
private static void checkAnswer(
final String correctAnswer,
final Scanner scanner,
final int[] scores
) {
for (int i = 0; i < MAX_ATTEMPTS; i++)
{
final String answer;
System.out.print("> ");
answer = scanner.nextLine();
if (answer.equalsIgnoreCase(correctAnswer))
{
if (i == FIRST_ATTEMPT)
{
scores[FIRST_ATTEMPT_SCORE]++;
}
else
{
scores[SECOND_ATTEMPT_SCORE]++;
}
System.out.println("CORRECT!");
return;
}
System.out.println("INCORRECT!");
}
scores[INCORRECT_SCORE]++;
System.out.printf("The correct answer was %s\n", correctAnswer);
}
/*
* startTrivia starts the game and asks NUMBER_OF_QUESTIONS,
* randomly chooses a Country and randomly chooses which
* kind of question to ask:
* country by capital,
* capital by country, or
* country by fact.
* @param scanner to pass to checkAnswer method
* @param scores to pass to checkAnswer method
*/
private void startTrivia(
final Scanner scanner,
final int[] scores
) {
for (int i = 0; i < NUMBER_OF_QUESTIONS; i++)
{
System.out.printf("Question %d:\n", i + QUESTION_NUM_OFFSET);
final Random rand;
final Country country;
final int questionType;
rand = new Random();
country = this.world.getRandomCountry();
questionType = rand.nextInt(QUESTION_TYPES);
switch (questionType)
{
case QUEST_ASK_CAPITAL:
System.out.println("What is the country of the following capital?");
System.out.println(country.getCapital());
checkAnswer(country.getName(), scanner, scores);
break;
case QUEST_ASK_COUNTRY:
System.out.println("What is the capital of the following country?");
System.out.println(country.getName());
checkAnswer(country.getCapital(), scanner, scores);
break;
case QUEST_ASK_FACT:
System.out.println("What is the country of the following fact?");
System.out.println(country.getRandomFact());
checkAnswer(country.getName(), scanner, scores);
break;
}
}
}
/**
* runTrivia initializes score, scanner, and keeps
* track if the user wants to keep playing after
* a round is completed.
*
* Once a user is done playing, score from all rounds is
* saved and high-scores are calculated.
*/
public void runTrivia()
{
final Scanner scanner;
Score score;
boolean continuePlaying;
continuePlaying = true;
scanner = new Scanner(System.in);
final int[] scores;
int gamesPlayed;
scores = new int[]{DEFAULT_SCORE,DEFAULT_SCORE,DEFAULT_SCORE};
gamesPlayed = DEFAULT_SCORE;
do
{
gamesPlayed++;
this.startTrivia(scanner, scores);
score = new Score(
LocalDateTime.now(),
gamesPlayed,
scores[FIRST_ATTEMPT_SCORE],
scores[SECOND_ATTEMPT_SCORE],
scores[INCORRECT_SCORE]
);
System.out.println(score);
do
{
System.out.println("\nDo you want to play again?");
System.out.print("> ");
final String playAgain;
playAgain = scanner.nextLine();
if (playAgain.equalsIgnoreCase("no"))
{
continuePlaying = false;
break;
}
else if (playAgain.equalsIgnoreCase("yes"))
{
// break inner do-while loop
break;
}
else
{
System.out.printf("Invalid option \"%s\"\n", playAgain);
}
} while (true);
} while (continuePlaying);
scanner.close();
final List<Score> history;
history = Score.readScoresFromFile(SCORE_PATH);
Score.appendScoreToFile(score, SCORE_PATH);
if (Score.isHighScore(score, history))
{
System.out.printf(
"CONGRATULATIONS! You have a new high score with an average of %.2f points per game; ",
score.calculateAverage()
);
final Score prevHighScore;
prevHighScore = Score.getHighScore(history);
if (prevHighScore == null)
{
return;
}
System.out.printf(
"the previous record was %.2f points per game ",
prevHighScore.calculateAverage()
);
System.out.printf(
"on %s at %s.\n",
prevHighScore.getDateTimePlayed().split(" ")[SPLIT_DATE],
prevHighScore.getDateTimePlayed().split(" ")[SPLIT_TIME]
);
}
}
/**
* main method for quickly testing the WordGame
* @param args from command line
*/
public static void main(final String[] args)
{
final WordGame test;
try
{
test = new WordGame();
}
catch (final IOException e)
{
throw new RuntimeException(e);
}
test.runTrivia();
}
}