diff --git a/Console.java b/Console.java index 4d87306..5ab0a16 100644 --- a/Console.java +++ b/Console.java @@ -1,58 +1,134 @@ -/** COSC-1337-001--Jennifer Ayala--07/29/2019--Final Project: -* Create an application that reads and converts English sentences to a secret -* code according the specs given; this class process user interaction methods -* Console.java -*/ -package wordconverter; -import java.util.Scanner; +/**INEW-2338-001/COSC 2336-001--Jennifer Ayala--11/10/2019--Programming Project Quiz 2 + * Create an app to allow users to enter a guess and wage after selecting a player + * for a random number selection game, update balance thru a GUI and write + * results to a file + * This file validates user input -- Console.java +*/ +package ui; +import java.util.Scanner; //import statement to access the Scanner class for user input /** - * The Console class provides methods to obtain user input + * The Console class provides methods to obtain and validate user input * @author Jennifer Ayala * @version 1.0.0 */ public class Console { - private static Scanner sc = new Scanner(System.in); + + private static Scanner sc = new Scanner(System.in); - public static void displayLine() { - System.out.println(); + /** Displays the prompt to the console, uses Scanner object + * to obtain String from the user, validates is a string entry + * @param prompt String string message displayed to user + * @return String string entered by user + */ + public static String getString(String prompt) { + String s = ""; + boolean isValid = false; + while (!isValid) { + System.out.print(prompt); + if (sc.hasNext()) { + s = sc.nextLine(); // read entire line + isValid = true; + } else { + System.out.println("Error! Invalid string value. Try again."); + } + } + return s; } - public static void displayLine(String s) { - System.out.println(s); + /** Displays the prompt to the console, uses Scanner object + * to obtain Double value from the user, validates input is a double + * @param prompt String string message displayed to user + * @return Double value entered by user + */ + public static double getDouble(String prompt) { + double d = 0; + boolean isValid = false; + while (!isValid) { + System.out.print(prompt); + if (sc.hasNextDouble()) { + d = sc.nextDouble(); + isValid = true; + } else { + sc.next(); // discard the incorrectly entered double + System.out.println("Error! Invalid decimal value. Try again."); + } + sc.nextLine(); // discard any other data entered on the line + } + return d; } - public static String getString(String prompt) { - System.out.print(prompt); - String s = sc.nextLine(); - return s; + /** Displays the prompt to the console, uses Scanner object + * to obtain Double from the user, validates entry is within the specified range + * @param prompt String string message displayed to user + * @param min Double double value specifying minimum value in range + * @param max Double double value specifying maximum value in range + * @return Double double value entered by user + */ + public static double getDouble(String prompt, double min, double max) { + double d = 0; + boolean isValid = false; + while (!isValid) { + d = Console.getDouble(prompt); + if (d <= min) { + System.out.println( + "Error! Number must be greater than " + min + "."); + } else if (d >= max) { + System.out.println( + "Error! Number must be less than " + max + "."); + } else { + isValid = true; + } + } + return d; } + /** Displays the prompt to the console, uses Scanner object + * to obtain int value from the user & validate input is an integer + * @param prompt String string message displayed to user + * @return int integer value entered by user + */ public static int getInt(String prompt) { + boolean isValid = false; int i = 0; - while (true) { + while (!isValid) { System.out.print(prompt); - try { - i = Integer.parseInt(sc.nextLine()); - break; - } catch (NumberFormatException e) { - System.out.println("Error! Invalid integer. Try again."); + if (sc.hasNextInt()) { + i = sc.nextInt(); + isValid = true; + } else { + sc.next(); // discard invalid data + System.out.println("Error! Invalid integer value. Try again."); } + sc.nextLine(); // discard any other data entered on the line } return i; } - public static double getDouble(String prompt) { - double d = 0; - while (true) { - System.out.print(prompt); - try { - d = Double.parseDouble(sc.nextLine()); - break; - } catch (NumberFormatException e) { - System.out.println("Error! Invalid decimal. Try again."); + /** Displays the prompt to the console, uses Scanner object + * to obtain int from the user, validates entry is within the specified range + * @param prompt String string message displayed to user + * @param min int integer value specifying minimum value in range + * @param max int integer value specifying maximum value in range + * @return int integer value entered by user + */ + public static int getInt(String prompt, int min, int max) { + int i = 0; + min = 1; + max = 5; + boolean isValid = false; + while (!isValid) { + i = Console.getInt(prompt); + if (i <= min) { + System.out.println( + "Error! Number must be greater than " + min + "."); + } else if (i >= max) { + System.out.println( + "Error! Number must be less than " + max + "."); + } else { + isValid = true; } } - return d; - } -} + return i; + } +} \ No newline at end of file diff --git a/GamePlay.java b/GamePlay.java new file mode 100644 index 0000000..511556d --- /dev/null +++ b/GamePlay.java @@ -0,0 +1,241 @@ +//project quiz - possible application start +/**INEW-2338-001/COSC 2336-001--Jennifer Ayala--11/10/2019--Programming Project Quiz 2 + * Create an app to allow users to enter a guess and wage after selecting a player + * for a random number selection game, update balance thru a GUI and write + * results to a file + * This file defines the GUI interface and interaction with the user --GamePlay.java +*/ + +package ui; + +/** + * The GamePlay class implements the application GUI & updates the + * player object, contains instance variables, constructor, + * @author Jennifer Ayala + * @version 1.0.0 +*/ +import java.util.*; +import java.util.Random; //access the random class for number generator +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.*; +import javax.swing.*; +import java.text.NumberFormat; +import business.Player; //access to the Player object class +import db.PlayerDAO; // access to the PlayerDAO interface +import db.PlayerTextFile; //ability to read & write to the player text file +import java.nio.file.Paths; +import java.util.List; + + +public class GamePlay extends JFrame { + //create the player file + //private PlayerDAO playerTextFile = new PlayerTextFile(); + + private JComboBox playerCombo; //declare variable to select user from combobox from Player object + private JTextField playerNameTF; //field to move player name from player object + private JTextField playerBalanceTF; //text field to add player balance from player object + private JTextField wagerTF; //declare variable text field for user to input wager + private JTextField guessTF; // declare variable text field to enter a guess + private JTextField randomNumTF; //declare variable text field to display random number + private JTextField resultTF; //declare variable text field to display result of guess + + /** + * @param args the command line arguments + */ + public GamePlay (){ + try { + UIManager.setLookAndFeel( + UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | InstantiationException | + IllegalAccessException | UnsupportedLookAndFeelException e) { + System.out.println(e); + } + initComponents(); + } + + + //@SuppressWarnings("empty-statement") + private void initComponents() { + setTitle("Game Play"); //create the GUI frame title + setLocationByPlatform(true); //allow OS to set frame location + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //exit application on close + + //retrieve Player object data from the PlayerTextFile: + //List players = PlayerTextFile.getAll(); + + //temp code to test comboBox + String [] players = {" ", "John Doe", "Mary Smith"}; + + //create the textField and JComboBox objects from variables: + playerCombo = new JComboBox(players); + + //Add object to playerCombo box: + //playerCombo.getItem(players); + + + playerNameTF = new JTextField(); + playerNameTF.setEditable(false); //read only once name retrieved from player object + + playerBalanceTF = new JTextField(); + + // pending: add balance from player text file + //playerBalanceTF.setText(); + playerBalanceTF.setEditable(false); //read only once balance retrieved from player object + + wagerTF = new JTextField(); //user input field for wager + guessTF = new JTextField(); //user input field for guess + + randomNumTF = new JTextField(); + randomNumTF.setEditable(false); //set display field to read only for random number + + resultTF = new JTextField(); + resultTF.setText(""); + resultTF.setEditable(false); //displays the result of the guess - win or lose + + //Set the height & weight dimensions + Dimension dim = new Dimension(150, 20); + playerNameTF.setPreferredSize(dim); + playerBalanceTF.setPreferredSize(dim); + wagerTF.setPreferredSize(dim); + guessTF.setPreferredSize(dim); + randomNumTF.setPreferredSize(dim); + resultTF.setPreferredSize(dim); + + playerNameTF.setMinimumSize(dim); + playerBalanceTF.setMinimumSize(dim); + wagerTF.setMinimumSize(dim); + guessTF.setMinimumSize(dim); + randomNumTF.setMinimumSize(dim); + resultTF.setMinimumSize(dim); + + //Create the exit button: + JButton exit = new JButton("Exit"); //create button object + exit.addActionListener(e -> { + exitButtonClicked(); //Exit button method + }); + + //create spin the wheel button: + JButton spin = new JButton("Spin the Wheel"); //create button object + spin.addActionListener(e -> { + spinWheel(); //Spin the wheel method + }); + + //create Play Again button: + JButton playAgainB = new JButton("Play Again"); //create button object + playAgainB.addActionListener(e -> { + playAgain(); //calls the play again method + }); + + //set up button panel + JPanel buttonPanel = new JPanel(); //create new panel for the buttons + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); //align right + buttonPanel.add(spin); //add spin wheel button to the panel + buttonPanel.add(playAgainB); // add play agaon button to panel + buttonPanel.add(exit); // add exit button to the panel + + //Create main panel: + JPanel main = new JPanel(); //main panel to add each panel + main.setLayout(new GridBagLayout()); //align left + main.add(new JLabel("Select a player:"), getConstraints(0, 0)); //label for player + main.add(playerCombo, getConstraints(1, 0)); //add the player object to the panel + main.add(new JLabel(" Player Name: "), getConstraints(0, 1)); + main.add(playerNameTF, getConstraints(1, 1)); + main.add(new JLabel("Enter a wager amount"), getConstraints(0, 2)); //label for wager + main.add(wagerTF, getConstraints(1, 2)); //add wager text field to panel + main.add(new JLabel("Enter one guess between 1 - 5"), getConstraints(0, 3)); + main.add(guessTF, getConstraints(1, 3)); //text field for the guess + main.add(new JLabel("The Winning Number Is: "), getConstraints (0, 5)); + main.add(randomNumTF, getConstraints(1, 5)); //add the randomly generated number + // main.add(resultTF, getConstraints(1, 6)); // add the result response + + + //add panels to the BorderLayout of the frame: + add(main, BorderLayout.CENTER); //add to the center of the frame + add(buttonPanel, BorderLayout.SOUTH); //position at the bottom of the frame + setSize(320, 200); + pack(); //set the size of the frame to accommodate all components + + } + + // helper method for getting a GridBagConstraints object + private GridBagConstraints getConstraints(int x, int y) { + GridBagConstraints c = new GridBagConstraints(); + c.anchor = GridBagConstraints.LINE_START; + c.insets = new Insets(5, 5, 0, 5); + c.gridx = x; + c.gridy = y; + return c; + } + + //Create the exit button method: + private void exitButtonClicked(){ + System.exit(0); //exit application with status code of 0 + } + + /**create the spin the wheel method for the button event + * generates random number between 1-5 */ + private void spinWheel(){ + String message = ""; //declare variable for alert message + int winningNumber = (int) (Math.random()*(6-1)+1); + String wNumber = Integer.toString(winningNumber); + String guess = guessTF.getText(); + int gNumber = Integer.parseInt(guess); + + if(gNumber < 1 || gNumber > 5){ + message = "Please enter a number between 1 and 5"; + playAgain(); + } else { + randomNumTF.setText(wNumber); + if (guess == wNumber){ + message = "Winner"; + } else if (guess != wNumber) { + message = "Loser"; + } + } + //display the message: + JOptionPane.showMessageDialog(this, message); + + } + + /** create the play again method for the button event, reset the fields - by + * setting text fields to empty strings & update the record*/ + private void playAgain(){ + playerCombo.setSelectedIndex(0); + playerNameTF.setText(""); + wagerTF.setText(""); + guessTF.setText(""); + randomNumTF.setText(""); + resultTF.setText(""); + + //Pending: update the balance & player record + //player = playerCombo.getSelectedItem(players); + //updateBalance(); + } + + /** + * Method to update player record the file - convert double data type + * to post string data retrieved from text fields + */ + private void updateBalance(){ + //set variable to capture balance from player object + double balance = Double.parseDouble(playerBalanceTF.getText()); + + //set variable to capture wager from entry + double wage = Double.parseDouble(wagerTF.getText()); + balance += wage; //new balance equal original balance plus wage + + //set number format to currency for price with NumberFormat object: + NumberFormat currency = NumberFormat.getCurrencyInstance(); + playerBalanceTF.setText(currency.format(balance)); + } + + //main method to run the program + public static void main(String[] args) { + java.awt.EventQueue.invokeLater(() -> { + new GamePlay().setVisible(true); + }); + } + +} diff --git a/Player.java b/Player.java new file mode 100644 index 0000000..aff1cc4 --- /dev/null +++ b/Player.java @@ -0,0 +1,79 @@ +/**INEW-2338-001/COSC 2336-001--Jennifer Ayala--11/10/2019--Programming Project Quiz 2 + * Create an app to allow users to enter a guess and wage after selecting a player + * for a random number selection game, update balance thru a GUI and write + * results to a file + * This file defines the player object -- Player.java +*/ + +package business; + +import db.PlayerDAO; // access the PlayerDAO interface +import java.lang.Object; //access to the object class +import java.text.NumberFormat; // access to Number format class for currency format + +/** + * The Player class implements the DAO interface & define the player + * object, contains instance variables, constructor, set & get methods + * @author Jennifer Ayala + * @version 1.0.0 +*/ +public class Player { + /** Create 2 instance variables: player's name, amount of money + player has on table*/ + private String playerName; + private double balance; + + + /** 1st Constructor - Creates a Player with no parameters */ + public Player(){ + } + + /**2nd Constructor - Name & amount of balance: */ + public Player(String playerName, double balance){ + this.playerName = playerName; + this.balance = balance; + } + + /** + * Create getter & setter methods for all instance variables + * Sets the playerName + * @param playerName String string variable + */ + public void setPlayerName(String playerName){ + this.playerName = playerName; + } + + /** + * Gets the playerName + * @return playerName String for the player object + */ + public String getPlayerName(){ + return playerName; + } + + /** + * Sets the money variable + * @param balance double double variable + */ + public void setBalance(double balance){ + this.balance = balance; + } + + /** + * Gets the balance variable + * @return balance double for the player object + */ + public double getBalance(){ + return balance; + } + + /** + * Formats balance variable into currency + * @return balance money in currency format + */ + public String getMoneyFormatted(){ + NumberFormat currency = NumberFormat.getCurrencyInstance(); + return currency.format(balance); + } + +} \ No newline at end of file diff --git a/PlayerDAO.java b/PlayerDAO.java new file mode 100644 index 0000000..d60a248 --- /dev/null +++ b/PlayerDAO.java @@ -0,0 +1,26 @@ +/**INEW-2338-001/COSC 2336-001--Jennifer Ayala--11/10/2019--Programming Project Quiz 2 + *Create an app to allow users to enter a guess and wage after selecting a player + * for a random number selection game, update balance thru a GUI and write + * results to a file + * This file defines I/O methods -- PlayerDAO.java +*/ +package db; + +import java.util.List; // access the List interface +import business.Player; //import statement to access Player object class + +/** + * The PlayerDAO interface defines the I/O methods & constants for a + * data access object + * get() method returns a single player object by player name + * getAll() method returns a List object that contains all Player objects + * update() method to write the player data to file, using a + * boolean indicating success of operation + * @author Jennifer Ayala + * @version 1.0.0 +*/ +public interface PlayerDAO { + Player get(String playerName); + List getAll(); + boolean update(Player p); +} \ No newline at end of file diff --git a/PlayerTextFile.java b/PlayerTextFile.java new file mode 100644 index 0000000..7cd0df7 --- /dev/null +++ b/PlayerTextFile.java @@ -0,0 +1,136 @@ +/**INEW-2338-001/COSC 2336-001--Jennifer Ayala--11/10/2019--Programming Project Quiz 2 + * Create an app to allow users to enter a guess and wage after selecting a player + * for a random number selection game, update balance thru a GUI and write + * results to a file + * This file defines how to write the results to a file --PlayerTextFile.java +*/ +package db; + +/** + * The PlayerTextFile class provides methods to read and write players + * to a text file + * @author Jennifer Ayala + * @version 1.0.0 +*/ + +import java.io.*; //access to the IO exception class +import java.nio.file.*; //package to work with directories & files +import java.util.*; + +import business.Player; //access the Player object class + +public class PlayerTextFile implements PlayerDAO { + /** + * Define & initialize instance variables + */ + private List players = null; // + private Path playersPath = null; + private File playersFile = null; + private final String FIELD_SEP = "\t"; // delimiter + + /** + * Constructor + */ + public PlayerTextFile(){ + playersPath = Paths.get("players.txt"); //create path object for players file + playersFile = playersPath.toFile(); //convert path object to file oject + players = this.getAll(); //get list of all players + } + /** + * getAll method + * @return a list of Player objects for all players stored in the file + * try-with-resources statement automatically closes the input stream + * IOException is thrown if operation fails + */ + @Override + public List getAll(){ //if already read, don't read file again + if (players != null){ //check if player list exists + return players; + } + players = new ArrayList<>(); // create empty ArrayList of Player objects + //check if player file exists + if(Files.exists(playersPath)){ + try (BufferedReader in = new BufferedReader( + new FileReader(playersFile))){ + String line = in.readLine(); //read player line into String variable + while(line != null) { //process until end of file reached + + //split string into fields + String[] fields = line.split(FIELD_SEP); + String playerName = fields[0]; + String balance = fields[1]; + + //create new player object from field values: + Player p = new Player( + playerName, Double.parseDouble(balance)); + players.add(p); //add player object to array list + line = in.readLine(); //reads next line in file + } + } catch (IOException e){ + System.out.println(e); //test if successful + } + } else { + System.out.println( + playersPath.toAbsolutePath() + " does not exist"); + return null; + } + return players; + } + /** + * Method to return Player object matching specific Player name + * @param playerName + * @return player if matches/ otherwise returns null + */ + @Override + public Player get(String playerName){ + for (Player p : players) { + if (p.getPlayerName() .equals(playerName)){ + return p; + } + } + return null; + } + + /** + * Method to write data to the Players file using a loop to write each + * individual player in the list, separated by the delimiter constant + * println method to insert a new line character after each player record + * IOException returns false if the save operation fails + * @return + */ + private boolean saveAll(){ + //Connect to Player's file: + try (PrintWriter out = new PrintWriter( + new BufferedWriter( + new FileWriter(playersFile)))){ + /** write all players in list to file using a loop to write each + * player in the list to the file, separated by the delimiter*/ + for (Player p : players){ + out.print(p.getPlayerName() + FIELD_SEP); + out.println(p.getBalance() + FIELD_SEP); + } + return true; + } catch (IOException e){ + System.out.println(e); + return false; + } + } + + /** + * Method to update individual player, by finding index through player name, + * removing player record from file and replacing with updated info + * @param newPlayer new player name to update + * @return true only if saveAll also returns true, record updated + */ + @Override + public boolean update(Player newPlayer){ + Player oldPlayer = this.get(newPlayer.getPlayerName()); + int i = players.indexOf(oldPlayer); + players.remove(i); + players.add(i, newPlayer); + return this.saveAll(); + } + + + +} \ No newline at end of file