librejack

Blackjack clone written in java
git clone https://github.com/michaelneuper/librejack.git
README | Files | Log | Refs | LICENSE

librejack/src/model/Statistics.java (6392B)


package model;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvValidationException;

/**
 * The Statistics class represents a set of statistics for a blackjack game.
 * Statistics are stored in a CSV file with the following format:
 * <ul>
 * <li><b>Column 1:</b> number of wins</li>
 * <li><b>Column 2:</b> number of losses</li>
 * <li><b>Column 3:</b> number of pushes(ties)</li>
 * </ul>
 *
 * <p>
 * The file is named <code>statistics.csv</code> and is stored in the
 * <code>db/</code> directory.</p>
 *
 * @author Michael Neuper
 * <a href="mailto:michael@michaelneuper.com">michael@michaelneuper.com</a>
 */
public class Statistics {

    private static final String CSV_FILE = "db/statistics.csv"; // csv file that stores the stats
    private static final String[] CSV_HEADERS = {"wins", "losses", "pushes"}; // headers for the csv file

    private int wins;
    private int losses;
    private int pushes;

    /**
     * Constructs a new {@link Statistics} object with all statistics
     * initialized to 0.
     */
    public Statistics() {
        this.wins = 0;
        this.losses = 0;
        this.pushes = 0;
    }

    /**
     * Constructs a new {@link Player} object with the given statistics.
     *
     * @param wins the number of wins
     * @param losses the number of losses
     * @param pushes the number of pushes (ties)
     */
    public Statistics(int wins, int losses, int pushes) {
        this.wins = wins;
        this.losses = losses;
        this.pushes = pushes;
    }

    /**
     * Gets the number of wins.
     *
     * @return the number of wins
     */
    public int getWins() {
        return wins;
    }

    /**
     * Gets the number of losses.
     *
     * @return the number of losses
     */
    public int getLosses() {
        return losses;
    }

    /**
     * Gets the number of pushes (ties).
     *
     * @return the number of pushes
     */
    public int getPushes() {
        return pushes;
    }

    /**
     * Sets the number of wins.
     *
     * @param wins the new number of wins
     */
    public void setWins(int wins) {
        this.wins = wins;
    }

    /**
     * Sets the number of losses.
     *
     * @param losses the new number of losses
     */
    public void setLosses(int losses) {
        this.losses = losses;
    }

    /**
     *
     * Sets the number of pushes (ties).
     *
     * @param pushes the new number of pushes
     */
    public void setPushes(int pushes) {
        this.pushes = pushes;
    }

    /**
     * Increments the number of wins by 1 and saves the new statistics to the
     * CSV file.
     */
    public void incrementWins() {
        this.wins++;
        save();
    }

    /**
     * Increments the number of losses by 1 and saves the new statistics to the
     * CSV file.
     */
    public void incrementLosses() {
        this.losses++;
        save();
    }

    /**
     * Increments the number of pushes (ties) by 1 and saves the new statistics
     * to the CSV file.
     */
    public void incrementPushes() {
        this.pushes++;
        save();
    }

    /**
     * <p>
     * This method saves the current statistics (number of wins, losses, and
     * pushes) to the {@code CSV_FILE} file. The file path is defined by the
     * {@code CSV_FILE} constant in the {@link Statistics} class.</p>
     * <p>
     * The method uses a {@link CSVWriter} object to write the data to the file.
     * If an {@link IOException} occurs during the file writing process, it is
     * caught and printed to the standard error stream.</p>
     */
    private void save() {
        try (CSVWriter writer = new CSVWriter(new FileWriter(CSV_FILE))) {
            writer.writeNext(CSV_HEADERS);
            String[] data = {String.valueOf(wins), String.valueOf(losses), String.valueOf(pushes)};
            writer.writeNext(data);
        } catch (IOException e) {
            System.err.println("Error writing to " + CSV_FILE);
        }
    }

    /**
     * <p>
     * This static method loads the statistics from the {@code CSV_FILE} file
     * located at the path defined by the {@code CSV_FILE} constant in the
     * {@link Statistics} class. The method uses a {@link CSVReader} object to
     * read the data from the file.</p>
     * <p>
     * If the {@code CSV_FILE} file does not have the expected headers, an
     * {@link IOException} is thrown. The method returns a {@link Statistics}
     * object with the values read from the {@code CSV_FILE} file.</p>
     * <p>
     * If an {@link IOException} occurs during the file reading process, it is
     * caught and printed to the standard error stream. If a
     * {@link CsvValidationException} is thrown during the file reading process,
     * it is handled internally and an empty {@link Statistics} object is
     * returned.</p>
     *
     * @return a {@link Statistics} object with the values read from the
     * {@code CSV_FILE} file, or an empty {@link Statistics} object if there was
     * a problem with the CSV file format
     * @throws IOException if there is a problem with the file reading process
     * or the CSV file headers are invalid
     */
    public static Statistics load() throws IOException {
        Statistics stats = new Statistics();
        try (CSVReader reader = new CSVReader(new FileReader(CSV_FILE))) {
            String[] headers = reader.readNext();
            if (!headers[0].equals(CSV_HEADERS[0])
                    || !headers[1].equals(CSV_HEADERS[1])
                    || !headers[2].equals(CSV_HEADERS[2])) {
                throw new IOException("Invalid CSV headers");
            }
            String[] data = reader.readNext();
            if (data != null) {
                stats.setWins(Integer.parseInt(data[0]));
                stats.setLosses(Integer.parseInt(data[1]));
                stats.setPushes(Integer.parseInt(data[2]));
            }
        } catch (CsvValidationException e) {
            // handle the exception internally
            System.err.println("Error: invalid CSV file format");
        } catch (IOException e) {
            // rethrow the IOException to the calling function
            throw new IOException("Error reading " + CSV_FILE, e);
        }

        return stats;
    }

}