Java Programming Assignment 7

Requirement

Problem:

  • Write a Java program to play a GUI version (your choice of Swing or AWT, application or applet) of your Prog. HW #6 Keno game. Both Prog. HW #6 & Prog. HW #7 versions will use many of the same classes and methods. The only methods you are not allowed to use from Prog. HW #6 are any of the "console" methods (the System.out and System.in methods).
  • You have a choice of GUI design, as long as it includes buttons, different Layouts, at least one textfield for user input, event handling and the program is still object-oriented. Also, don't allow the program to "bomb" or hang or display incorrect info if incorrect input or out of order events occur.

Result Snapshot

Solution

public class HW7_Spot 
{

private int value = 0;

private boolean chosen = false;


public HW7_Spot()

{

value = 0; // not needed but in case

chosen = false;

}


public HW7_Spot(int i_value)

{

value = (i_value > 0)? i_value : value; // not needed but in case

}


public int getValue()

{

return value;

}


public boolean getChosen()

{

return chosen;

}


public void setChosen(boolean b_Chosen)

{

chosen = b_Chosen;

}

}
/* Write an interface called NumberGameInterface which has only abstract public instance methods called 

drawNumbers (no parameters, no return value),

getResults (no parameters, no return value) and displayResults (no parameters, no return value).

*/
public interface HW7_NumberGameInterface 
{

public abstract void drawNumbers();

public abstract void getResults();

public abstract void displayResults();

}
public class HW7_KenoBoard 
{

public static int MAX_KENO_NUMBER = 80;

public static int DRAWN_NUMBERS = 20;


private HW7_Spot [] kenoSpots;

private HW7_Spot [] drawnSpots;


// a constructor (no parameters)-- allocate memory for the kenoSpots (of size MAX_KENO_NUMBER+1) , allocate memory for the drawnSpots array (of size DRAWN_NUMBERS). Initialize each element in the kenoSpots array to an instance of a Spot (pass the array index to the constructor). Note: MAX_KENO_NUMBER and DRAWN_NUMBERS are declared as static in the KenoGame class

public HW7_KenoBoard()

{

kenoSpots = new HW7_Spot[MAX_KENO_NUMBER + 1];

drawnSpots = new HW7_Spot[DRAWN_NUMBERS];


for(int i=1; i < kenoSpots.length; i++)

{

kenoSpots[i] = new HW7_Spot(i);

}

}


// a method that resets the boolean variable in each Spot (OR only the ones that were set, using drawnSpots) of kenoSpots to false, and then resets each element of the drawnSpots array to null.

public void resetKenoBoard()

{

for(int i = 1; i < kenoSpots.length; i++) // Note: Keno Spot index starts from 1, 0th index is null

kenoSpots[i].setChosen(false);


for(int i = 0; i < drawnSpots.length; i++)

drawnSpots[i] = null;

}


// an accessor (with an int parameter, Spot return value) for ONE of the kenoSpots with the index of the int pararmeter-- be sure that the int parameter is in range (check using KenoGame's static MAX_KENO_NUMBER variable) -- if in range, return the corresponding Spot, if not, return null

public HW7_Spot getKenoSpot(int i_Spot)

{

if(i_Spot > 0 && i_Spot <= MAX_KENO_NUMBER)

return kenoSpots[i_Spot];

else

return null;

}


// a method that will randomly choose Spots in kenoSpots by doing the following for each drawnSpots element:

public void createDrawnSpots()

{

int i_RandomKenoIndex;

for (int i = 0; i < drawnSpots.length; i++)

{

// formula to get random number: (int)(Math.random() * (MAX-MIN+1) ) + MIN;

i_RandomKenoIndex = (int)(Math.random() * (MAX_KENO_NUMBER - 1 + 1) ) + 1;

if(kenoSpots[i_RandomKenoIndex].getChosen())

i--; // already chosen than loop one more time, do it silently without any warning

else

{

drawnSpots[i] = new HW7_Spot(kenoSpots[i_RandomKenoIndex].getValue());

kenoSpots[i_RandomKenoIndex].setChosen(true);

}

}

}


// toString (overriding Object's toString) that will return a string with the value of each Spot in the drawnSpots array

public String toString()

{

String s_drawnSpots = "";

for(int i = 0; i < drawnSpots.length; i++)

{

s_drawnSpots = s_drawnSpots + drawnSpots[i].getValue() + "-"; // Don't know why but "|" character is not working

}

return s_drawnSpots;

}

}
// Write a class called KenoPlayer to represent a player's chosen numbers for a Keno Game.
public class HW7_KenoPlayer 
{

private HW7_Spot [] markedSpots;

private int currentIndex = 0;

private int numOfMatches = 0;

private int amountOfBet = 1;

private double amountWin = 0.00;


// To Do: constructor with int for the number of spots to choose, and an int for the bet as parameters-- initialize the appropriate instance variables to the parameters (make sure to assign only if > 0 for numbers, and the number of spots < length of the payoff array in the KenoGame class), and allocate memory for the markedSpots array, using the parameter for the number of spots (or 1 if the parameter is out of range)

public HW7_KenoPlayer(int i_numOfSpots, int i_amountOfBet)

{

if(i_numOfSpots > 0 && i_numOfSpots < HW7_KenoGame.PAYOFF.length)

markedSpots = new HW7_Spot[i_numOfSpots];

else

markedSpots = new HW7_Spot[1];


amountOfBet = (i_amountOfBet > 0)? i_amountOfBet : amountOfBet;

}


// accessors (one for the length of the markedSpots array, one for the bet, one for the number of matches, and one for the winnings)

public int getLengthOfMarkedSports()

{

return markedSpots.length;

}


public int getAmountOfBet()

{

return amountOfBet;

}


public int geNumOfMatches()

{

return numOfMatches;

}


public double getAmountWin()

{

return amountWin;

}


// a method called setSpot (with a Spot parameter and boolean return value) that assigns to the next element in this' markedSpots array, the Spot parameter-- but check if the parameter isn't null and the currentIndex < length of the array AND/OR check each element in this' markedSpots array so far (that the parameter's not already there). If it doesn't, assign, increment the current index and return true, otherwise return false.

public boolean setSpot(HW7_Spot oHW7_Spot)

{

if(currentIndex < markedSpots.length && oHW7_Spot != null)

{

for (int i = 0; i < markedSpots.length; i++)

{

if(markedSpots[i] != null)

{

if(markedSpots[i].getValue() == oHW7_Spot.getValue()) // Spot comparison

return false;

}

}


markedSpots[currentIndex] = oHW7_Spot;

currentIndex ++;

return true;

}

else

{

return false;

}

}


// a method called calcNumMatches that counts how many elements in this KenoPlayer's markedSpots that were chosen (check each element's chosen variable) and assign to your instance variable for number of matches

public void calcNumMatches()

{

numOfMatches = 0; // reset before calculate in case

for(int i = 0; i < markedSpots.length; i++)

{

if(markedSpots[i].getChosen())

numOfMatches++;

}

}


// a method called calcWinnings (no parameters) that will access the PAYOFF static 2-dim. array in the KenoGame to find and assign the appropriate array element (multiplied by your bet), rounded to the nearest int to your instance variable for amount you won.

public void calcWinnings()

{

amountWin = Math.round(HW7_KenoGame.PAYOFF[markedSpots.length][numOfMatches] * amountOfBet);

}


// toString (overriding Object's toString) that will return a string with a label (like "Player's spots:"), each of the Spot's int values in the markedSpots array (make sure it's not null) , number of matches, bet, and winnings

public String toString()

{

// ex: Player's spots: 20 30 40 50, Player matched 2 spot(s), bet $10 and won $10

String s_PlayerSpot = "";

for(int i = 0; i < markedSpots.length; i++)

{

s_PlayerSpot = s_PlayerSpot + markedSpots[i].getValue() + "-";

}

return String.format("Player's spots: %s \nPlayer matched %d spot(s), bet $%d and won $%.2f", s_PlayerSpot, numOfMatches, amountOfBet, amountWin);

}


public String getMatchedSpots()

{

String s_MatchedSpots = "";

for(int i = 0; i < markedSpots.length; i++)

{

if(markedSpots[i].getChosen())

s_MatchedSpots = s_MatchedSpots + markedSpots[i].getValue() + "-";

}

return s_MatchedSpots;

}

}
public class HW7_KenoGame implements HW7_NumberGameInterface
{

public static final int MAX_KENO_NUMBER = 80;

public static final int DRAWN_NUMBERS = 15;


private HW7_KenoBoard oKenoBoard;

private HW7_KenoPlayer oKenoPlayer;

public static double [][] PAYOFF = {{0},

{0, 2.75},

{0, 1., 5.},

{0, 0, 2.50, 25.00},

{0, 0, 1.0, 5.0, 80.0},

{0, 0, 0, 2.0, 10.0, 600.0},

{0, 0, 0, 1.0, 8.0, 50., 1499.0},

{0, 0, 0, 0, 5.0, 10.0, 250., 1500.0},

{0, 0, 0, 0, 4.00, 8.00, 40.00, 400.00, 10000.00},

{0, 0, 0, 0, 2.00, 5.00, 20.00, 80.00, 2500.00, 15000.00},

{0, 0, 0, 0, 0, 2.00, 30.00, 100.00, 500.00, 3000.00, 17500.00},

{0, 0, 0, 0, 0, 2.00, 15.00, 50.00, 80.00, 800.00, 8000.00, 27500.00},

{0, 0, 0, 0, 0, 1.00, 5.00, 30.00, 90.00, 500.00, 2500.00, 15000.00, 30000.00},

{0, 0, 0, 0, 0, 1.00, 2.00, 10.00, 50.00, 500.00, 1000.00, 10000.00, 15000.00, 30000.00},

{0, 0, 0, 0, 0, 0, 2.00, 8.00, 32.00, 300.00, 800.00, 2500.00, 12000.00, 18000.00, 30000.00},

{0, 0, 0, 0, 0, 0, 1.00, 7.00, 21.00, 100.00, 400.00, 2000.00, 8000.00, 12000.00, 25000.00, 30000.}

};


// default constructor that instantiates a KenoBoard (and assigns to the KenoBoard instance variable)

public HW7_KenoGame()

{

oKenoBoard = new HW7_KenoBoard();

}


// a method (2 int parameters) to instantiate a new KenoPlayer passing the int parameters (and assign to the instance variable)

public void createKenoPlayer(int i_numOfSpots, int i_amountOfBet)

{

oKenoPlayer = new HW7_KenoPlayer(i_numOfSpots, i_amountOfBet);

}


// a method with an int parameter to set ONE Spot in the KenoPlayer's (if the KenoPlayer variable is not null) markedSpots array, but check the int parameter first if it's in range (between 1 and KenoBoard's static MAX_KENO_NUMBER) before passing the Spot in the KenoBoard (use the KenoBoard's accessor for one Spot) -- return -2 if the KenoPlayer hasn't been instantiated yet, -1 if the int parameter is out of range, 1 if the KenoPlayer's method returns false, 0 if it was assigned OK

public int setUserDrawnSpot(int i_Spot)

{

if(oKenoPlayer != null)

{

if(i_Spot > 0 && i_Spot <= HW7_KenoBoard.MAX_KENO_NUMBER)

{

//HW7_Spot oHW7_Spot = new HW7_Spot(i_Spot);

//oHW7_Spot.setChosen(true);

if(oKenoPlayer.setSpot(oKenoBoard.getKenoSpot(i_Spot)))

return 0; // -- 0 if it was assigned OK

else

return 1; // -- 1 if the KenoPlayer's method returns false

}

else

return -1; // -- -1 if the int parameter is out of range

}

else

return -2; // -- return -2 if the KenoPlayer hasn't been instantiated yet

}


// a method to return the length of the KenoPlayer's markedSpots array

public int getLenOfMarkedSpots()

{

return oKenoPlayer.getLengthOfMarkedSports();

}


// a method to override the interface method drawNumbers (no parameters) that calling the KenoBoard methods to reset its variables and the method to assign "randomly" to the drawnArray

public void drawNumbers()

{

oKenoBoard.resetKenoBoard();

oKenoBoard.createDrawnSpots();

}


// a method to override the interface method getResults that calls the KenoPlayer's methods to calculate how many matched and calculate its winnings

public void getResults()

{

oKenoPlayer.calcNumMatches();

oKenoPlayer.calcWinnings();

}


// a method to override the interface method displayResults that will display the KenoBoard's toString and the KenoPlayer's toString to System.out.

public void displayResults()

{

System.out.println(oKenoBoard.toString());

System.out.println(oKenoPlayer.toString());

}


// Following methods are added for HW7

public String getDrawnSpots()

{

return oKenoBoard.toString();

}


public String getMatchedSpots()

{

return oKenoPlayer.getMatchedSpots();

}


public int geKenoPlayerNumOfMatches()

{

return oKenoPlayer.geNumOfMatches();

}


public double getKenoPlayerAmountWin()

{

return oKenoPlayer.getAmountWin();

}

}
/*

Name of program: Keno Game with GUI

Programmer's name: ABC

Current Date: dd/mm/yyyy

Computer system and compiler you are using: Win 8, JDK 1.7

Brief description of the program (1-5 sentences): Play Keno game (GUI version)

Variable names (if any) and descriptions of what they represent:

*/
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

import java.util.Scanner; // To Do: Remove

public class HW7_KenoGameDriver extends JFrame implements ActionListener
{

static Scanner oScanner = new Scanner(System.in); // TO Do: Remove

private static int i_Counter = 0;

private static int i_NumOfSpotToChose = 0;


// GUI Components

private JComboBox cbx_NumOfSpotToChose;

private JTextField tb_amountOfBet;

private JButton btn_playKeno;

private JButton [] btn_KenoSpots;

private JLabel lb_result;

private JButton btn_playKenoAgain;


private HW7_KenoGame oKenoGame;


public HW7_KenoGameDriver()

{

super("Keno Game");

setLayout(new BorderLayout());


JPanel p1 = new JPanel(new FlowLayout());

String [] strArray_NumOfSpotToChose = new String[HW7_KenoGame.DRAWN_NUMBERS];

for (int i = 0; i < HW7_KenoGame.DRAWN_NUMBERS; i++)

strArray_NumOfSpotToChose[i] = Integer.toString(i+1);

cbx_NumOfSpotToChose = new JComboBox(strArray_NumOfSpotToChose);

tb_amountOfBet = new JTextField(5); // assumed max bet is 99999

btn_playKeno = new JButton("Play Keno");

btn_playKeno.addActionListener(this);

p1.add(new JLabel("How many spots do you want to choose?"));

p1.add(cbx_NumOfSpotToChose);

p1.add(new JLabel("What is your bet (min $1): "));

p1.add(tb_amountOfBet);

p1.add(btn_playKeno);



JPanel p2 = new JPanel(new GridLayout(8, 10, 1, 1));

btn_KenoSpots = new JButton[HW7_KenoGame.MAX_KENO_NUMBER];

for (int i = 0; i < btn_KenoSpots.length; i++)

{

btn_KenoSpots[i] = new JButton(Integer.toString(i+1));

btn_KenoSpots[i].setEnabled(false);

btn_KenoSpots[i].setBackground(Color.GRAY);

btn_KenoSpots[i].addActionListener(this);

p2.add(btn_KenoSpots[i]); // avoid another for loop

}


JPanel p3 = new JPanel(new FlowLayout());

lb_result = new JLabel();

btn_playKenoAgain = new JButton("Play Another Game");

btn_playKenoAgain.setEnabled(false);

btn_playKenoAgain.addActionListener(this);

p3.add(lb_result);

p3.add(btn_playKenoAgain);


JPanel p4 = new JPanel(new GridLayout(8, 4, 2, 2));

JButton oJButton_Yellow = new JButton("Selected Spots"); oJButton_Yellow.setBackground(Color.YELLOW); oJButton_Yellow.setEnabled(false); oJButton_Yellow.setToolTipText("Selected Spot");

JButton oJButton_MAGENTA = new JButton("Drawn Spots"); oJButton_MAGENTA.setBackground(Color.MAGENTA); oJButton_MAGENTA.setEnabled(false); oJButton_Yellow.setToolTipText("Drawn Spot");

JButton oJButton_Red = new JButton("Matched Spots"); oJButton_Red.setBackground(Color.RED); oJButton_Red.setEnabled(false); oJButton_Yellow.setToolTipText("Matched Spot");

JButton oJButton_Gray = new JButton("Disabled Spots"); oJButton_Gray.setBackground(Color.GRAY); oJButton_Gray.setEnabled(false); oJButton_Gray.setToolTipText("Buttons are disabled. Please select options and click on Play Keno Game to start the game");

JButton oJButton_Cyan = new JButton("Enabled Spots"); oJButton_Cyan.setBackground(Color.CYAN); oJButton_Cyan.setEnabled(false); oJButton_Cyan.setToolTipText("Buttons are enabled for selection. Please select keno spots to see how much you win");

p4.add(oJButton_Yellow);

p4.add(oJButton_MAGENTA);

p4.add(oJButton_Red);

p4.add(oJButton_Gray);

p4.add(oJButton_Cyan);


// Arrange all panels

add(p1, BorderLayout.NORTH);

add(p2, BorderLayout.CENTER);

add(p3, BorderLayout.SOUTH);

add(p4, BorderLayout.WEST);


oKenoGame = new HW7_KenoGame();

}


    public void actionPerformed(ActionEvent e)
    {
    Object obj = e.getSource();
    

int i_amountOfBet = 0;

        if(obj == btn_playKeno)
        {
        i_NumOfSpotToChose = Integer.parseInt((String)cbx_NumOfSpotToChose.getSelectedItem());
        
        if(tb_amountOfBet.getText().isEmpty())
        {
        JOptionPane.showMessageDialog(null, "Please enter value in Amount of bet box before click Play again", "Input Error", JOptionPane.ERROR_MESSAGE);
        return;
        }
        try 
        {
        i_amountOfBet = Integer.parseInt(tb_amountOfBet.getText());
        if (i_amountOfBet == 0)
        {
        JOptionPane.showMessageDialog(null, "Must enter amount greater than 0.", "Input Error", JOptionPane.ERROR_MESSAGE);
        return;
        }
        }
        catch( NumberFormatException nfe )
        {
        JOptionPane.showMessageDialog(null, "Must enter digits only in amount of bet box!", "Input Error", JOptionPane.ERROR_MESSAGE);
        return;
        } 
        
        oKenoGame.drawNumbers();
        oKenoGame.createKenoPlayer(i_NumOfSpotToChose, i_amountOfBet);
    for (int i = 0; i < btn_KenoSpots.length; i++)
    {
    btn_KenoSpots[i].setEnabled(true);
    btn_KenoSpots[i].setBackground(Color.CYAN);
    }
    
    cbx_NumOfSpotToChose.setEnabled(false);
    tb_amountOfBet.setEnabled(false);
    btn_playKeno.setEnabled(false);
    lb_result.setText("Select " + i_NumOfSpotToChose + " keno numbers");
    lb_result.setForeground(Color.RED);
        }
        else if(obj == btn_playKenoAgain)
        {
        // To Do:
        btn_playKenoAgain.setEnabled(false);
    for (int i = 0; i < btn_KenoSpots.length; i++)
    {
    btn_KenoSpots[i].setEnabled(false);
    btn_KenoSpots[i].setBackground(Color.GRAY);
    }
    cbx_NumOfSpotToChose.setEnabled(true);
    tb_amountOfBet.setEnabled(true);
    btn_playKeno.setEnabled(true);
    lb_result.setText("");
    // No reset for amount of bet and number of spots to chose, since it might helpful for user if want to keep the same numbers and try one more time OR modification is easier
    i_Counter = 0;
    i_NumOfSpotToChose = 0;

oKenoGame = new HW7_KenoGame(); // To Do:

        }

else if(obj instanceof JButton && Character.isDigit(((JButton)obj).getText().charAt(0))) // To Do: bad logic, how to determine keno spot buttons, probably need new action listener, check range 1 to 80

        {

JButton btn_kenoSpot = (JButton)obj;

btn_kenoSpot.setEnabled(false);

btn_kenoSpot.setBackground(Color.YELLOW);

oKenoGame.setUserDrawnSpot(Integer.parseInt(btn_kenoSpot.getText()));

i_Counter ++;

       

if(i_Counter == i_NumOfSpotToChose)

        {

oKenoGame.getResults(); // Calculated number of matches and amount of Win

       

//System.out.println(oKenoGame.getDrawnSpots()); // For Test Only

String [] a_drawnSpots = oKenoGame.getDrawnSpots().split("-");

for(int i = 0; i < a_drawnSpots.length; i++)

{

// System.out.println(a_drawnSpots[i]); // For Test Only

btn_KenoSpots[Integer.parseInt(a_drawnSpots[i])-1].setBackground(Color.MAGENTA);

}

       

String s_MatchedSpots = oKenoGame.getMatchedSpots();

//System.out.println(s_MatchedSpots); // For Test Only

if(!s_MatchedSpots.isEmpty())

{

String [] a_matchedSpots = s_MatchedSpots.split("-");

for(int i = 0; i < a_matchedSpots.length; i++)

{

btn_KenoSpots[Integer.parseInt(a_matchedSpots[i])-1].setBackground(Color.RED);

}

}

       
        for (int i = 0; i < btn_KenoSpots.length; i++)
        {
        btn_KenoSpots[i].setEnabled(false);
        }
        
        lb_result.setText("You matched "+ oKenoGame.geKenoPlayerNumOfMatches() + " Spot(s), You won $" + oKenoGame.getKenoPlayerAmountWin() +"   ");
        btn_playKenoAgain.setEnabled(true);
        }
        }
    }


public static void main(String[] args)

{

//HW7_KenoGame oKenoGame = new HW7_KenoGame();

HW7_KenoGameDriver oKenoGameDriver = new HW7_KenoGameDriver();

oKenoGameDriver.setSize(650,650);

oKenoGameDriver.setVisible(true);

oKenoGameDriver.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


// Note: In GUI version following line is not needed (keep it here for future reference)

//boolean b_IsGameContinue = true; // determine if user want to repeat

//while(b_IsGameContinue)

//{

// oKenoGame.drawNumbers();

// getKenoGameUserChoices(oKenoGame);

// oKenoGame.getResults();

// oKenoGame.displayResults();

// b_IsGameContinue = isGameContinue(); // Ask if user wants to repeat

//}

}


// Not needed (Keep it here for future reference)

public static void getKenoGameUserChoices(HW7_KenoGame oKenoGame)

{

int i_NumOfSpotToChose = 0;

int i_amountOfBet = 0;

while (i_NumOfSpotToChose < 1 || i_NumOfSpotToChose >= HW7_KenoGame.PAYOFF.length)

{

System.out.print("How many spots do you want to choose? (max. " + HW7_KenoGame.DRAWN_NUMBERS + "): ");

i_NumOfSpotToChose = oScanner.nextInt();

// if (i_NumOfSpotToChose < 1 || i_NumOfSpotToChose >= HW7_KenoGame.PAYOFF.length) // display error message

}

while(i_amountOfBet <= 0)

{

System.out.print("What is your bet (at least $1): ");

i_amountOfBet = oScanner.nextInt();

}


oKenoGame.createKenoPlayer(i_NumOfSpotToChose, i_amountOfBet);

int i_Counter = 0;

while (i_Counter < i_NumOfSpotToChose)

{

System.out.print(String.format("Enter number (1-%d) #%d: ", HW7_KenoGame.MAX_KENO_NUMBER, (i_Counter+1)));

switch(oKenoGame.setUserDrawnSpot(oScanner.nextInt()))

{

case -1:

System.out.println(String.format("Number is out of range (1-%d)", HW7_KenoGame.MAX_KENO_NUMBER));

break;

case 1:

System.out.println("You already chose that number!");

break;

case 0:

i_Counter++;

break;

default:

break;

}

}

}


// Ask if user wants to repeat --> Copied this method from HW2 --> Not needed (Keep it here for reference)

public static boolean isGameContinue()

{

boolean isGameContinue;

System.out.print("Play another game? (y for yes): ");

String s_UserInput = oScanner.next();

if(s_UserInput != null && ! s_UserInput.isEmpty())

{

System.out.println(s_UserInput.substring(0, 0).toUpperCase());

isGameContinue = (s_UserInput.toUpperCase().charAt(0) == 'Y')? true : false;

}

else

isGameContinue = false;


return isGameContinue;

}

}
/*
Output: 
- GUI output of different steps in word document
*/