0% found this document useful (0 votes)
143 views30 pages

Assig 6

This document contains code for a card game called "Timed High-Card" that has a controller, model, and view. The controller initializes the view and model, handles user input and updates the view when data changes. It contains methods for validating user card selections, getting user selections, and handling player turns by prompting the user until a valid selection is made or they exit the game. It also selects cards for the computer and adds them to the play area. The model manages the game data and notifies the controller of changes. The view displays the game components and cards.

Uploaded by

api-335445548
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
143 views30 pages

Assig 6

This document contains code for a card game called "Timed High-Card" that has a controller, model, and view. The controller initializes the view and model, handles user input and updates the view when data changes. It contains methods for validating user card selections, getting user selections, and handling player turns by prompting the user until a valid selection is made or they exit the game. It also selects cards for the computer and adds them to the play area. The model manages the game data and notifies the controller of changes. The view displays the game components and cards.

Uploaded by

api-335445548
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 30

/* Assignment 6 - Timed High-Card Game

* Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner


* CST 338
* October 10, 2017
* Professor Cecil
*/

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.util.Random;;

/**
* Assig6 class which includes main() for creating a "Timed High-Card" game.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
public class Assig6
{
public static void main(String[] args)
{
//Creates a new Controller that begins the game.
CardGameController gameController = new CardGameController("Build",
CardGameModel.NUM_CARDS_PER_HAND, CardGameModel.NUM_PLAYERS);
}
}

/**
* Controller class that initializes a View and a Model.
* Includes methods that control input and updates the view when data changes.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class CardGameController
{
private CardGameModel gameModel;
private CardGameView gameView;
private GameMouseAdapter currentMouseAdapter;

//Initializes the view and model, updating the view to the model's
specifications
public CardGameController(String gameName, int numPlayers, int numCardsPerHand)
{
gameView = new CardGameView(gameName, numCardsPerHand, numPlayers);
gameModel = new CardGameModel();
gameModel.init(this, gameView);
}

//Mutator for the current mouse adapter


public void setCurrentMouseAdapter(GameMouseAdapter mouseAdapter)
{
this.currentMouseAdapter = mouseAdapter;
}
//Creates selection window for the user to select on of two choices
public int getUserSelection()
{
String[] options = {"Left", "Right"};
int response = JOptionPane.showOptionDialog(null,"Which stack do you
choose?",
"Select a stack", 0,JOptionPane.INFORMATION_MESSAGE,null,options,null);
return response;
}

//Validates the value of the card that the user selects


public boolean validSelection(int stackValue, int playerValue)
{
int max = 13;
int min = 1;
if(stackValue > max || stackValue < min)
return false;
if(stackValue == 1)
{
if(playerValue == max || playerValue == stackValue+1)
return true;
return false;
}
else if(stackValue == max)
{
if(playerValue == 1 || playerValue == stackValue-1)
return true;
return false;
}
else
{
if(playerValue == stackValue-1 || playerValue == stackValue+1)
return true;
else
return false;
}
}

//Validates the card the user selects for the left pile
public boolean leftSelection(JLabel cardLabel)
{
int stackValue =
getValueOfCard(gameView.pnlPlayArea.getComponent(0).getName().charAt(0));
int playerValue = getValueOfCard(cardLabel.getName().charAt(0));
if(validSelection(stackValue, playerValue))
{
gameView.pnlHumanHand.remove(cardLabel);
gameView.pnlPlayArea.remove(0);
gameView.pnlPlayArea.add(cardLabel, 0);
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameModel.addCardToPlayer(this);
gameView.pnlHumanHand.validate();
gameView.pnlHumanHand.repaint();
gameView.setVisible(true);
gameModel.noPlay = false;
return true;
}
else
{
final JOptionPane pane = new JOptionPane("Not a valid selection.");
final JDialog d = pane.createDialog((JFrame) null, "Try again");
d.setLocationRelativeTo(gameView.pnlComputerHand);
d.setVisible(true);
return false;
}
}

//Validates the card the user selects for the right pile
public boolean rightSelection(JLabel cardLabel)
{
int stackValue =
getValueOfCard(gameView.pnlPlayArea.getComponent(2).getName().charAt(0));
int playerValue = getValueOfCard(cardLabel.getName().charAt(0));
if(validSelection(stackValue, playerValue))
{
gameView.pnlHumanHand.remove(cardLabel);
gameView.pnlPlayArea.remove(2);
gameView.pnlPlayArea.add(cardLabel, 2);
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameModel.addCardToPlayer(this);
gameView.pnlHumanHand.validate();
gameView.pnlHumanHand.repaint();
gameView.setVisible(true);
gameModel.noPlay = false;
return true;
}
else
{
final JOptionPane pane = new JOptionPane("Not a valid selection.");
final JDialog d = pane.createDialog((JFrame) null, "Try again");
d.setLocationRelativeTo(gameView.pnlComputerHand);
d.setVisible(true);
return false;
}
}

//Handles the player's turns


//Prompts the user until they make a valid selection or exit the game
public void processPlayerTurn(String componentName)
{
boolean computerPlays = true;
// use this card name to find the exact card in players hand
for (int i = 0; i < gameView.pnlHumanHand.getComponents().length; i++)
{
// use this card name to find the exact card in players hand
if
(gameView.pnlHumanHand.getComponent(i).getName().equalsIgnoreCase(componentName))
{
JLabel cardLabel = (JLabel) gameView.pnlHumanHand.getComponent(i);
int response = getUserSelection();
if (response == 1)
{
if(!rightSelection(cardLabel))
computerPlays = false;
}
else if (response == 0)
{
if(!leftSelection(cardLabel))
computerPlays = false;
}
else if (response == JOptionPane.CLOSED_OPTION)
{
computerPlays = false;
}
if(computerPlays)
{
gameView.pnlPlayArea.remove(4);
gameView.pnlPlayArea.add(new JLabel("Your score: "+(+
+gameModel.yourScore),
SwingConstants.CENTER), 4);
gameView.pnlHumanHand.validate();
gameView.pnlHumanHand.repaint();
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameView.setVisible(true);
final JOptionPane pane = new JOptionPane(new JLabel("Click ok to
continue",
JLabel.CENTER));
final JDialog d = pane.createDialog((JFrame) null, "Your card was
played");
d.setLocationRelativeTo(gameView.pnlComputerHand);
d.setVisible(true);
cardLabel.removeMouseListener(currentMouseAdapter);
}
}
}
if(computerPlays)
computerTurn();
gameView.setVisible(true);
}

// Selects a card for the computer side and


// puts it into the play area
public void computerTurn()
{
String cardName = computerSelect();
if(cardName == null)
{
final JOptionPane paneNoPlay = new JOptionPane(
new JLabel("Click ok to continue",JLabel.CENTER));
final JDialog dialog = paneNoPlay.createDialog((JFrame) null,
"Computer had no play");
dialog.setLocationRelativeTo(gameView.pnlComputerHand);
dialog.setVisible(true);
if(gameModel.noPlay)
{
if(gameModel.addCardsToPlayArea(this))
{
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameView.setVisible(true);
final JOptionPane pane = new JOptionPane(
new JLabel("Cards were dealt to play area",JLabel.CENTER));
final JDialog d = pane.createDialog((JFrame) null,
"Neither has a valid card");
d.setLocationRelativeTo(gameView.pnlComputerHand);
d.setSize(250, 250);
d.setVisible(true);
}
else
{
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameView.setVisible(true);
showWinner();
}
}
return;
}
for (int i = 0; i < gameView.pnlComputerHand.getComponents().length; i++)
{
if
(gameView.pnlComputerHand.getComponent(i).getName().equalsIgnoreCase(cardName))
{
JLabel cardLabel = (JLabel) gameView.pnlComputerHand.getComponent(i);
int stackValueLeft = getValueOfCard(
gameView.pnlPlayArea.getComponent(0).getName().charAt(0));
int stackValueRight = getValueOfCard(
gameView.pnlPlayArea.getComponent(2).getName().charAt(0));
int playerValue = getValueOfCard(cardLabel.getName().charAt(0));
if(validSelection(stackValueRight, playerValue))
{
gameView.pnlComputerHand.remove(cardLabel);
gameView.pnlPlayArea.remove(2);
gameView.pnlComputerHand.validate();
gameView.pnlComputerHand.repaint();
Card addedCard;
switch (cardName.charAt(5))
{
case 'c':
addedCard = new Card(cardName.charAt(0), Card.Suit.clubs);
break;
case 'd':
addedCard = new Card(cardName.charAt(0), Card.Suit.diamonds);
break;
case 'h':
addedCard = new Card(cardName.charAt(0), Card.Suit.hearts);
break;
case 's':
addedCard = new Card(cardName.charAt(0), Card.Suit.spades);
break;
default:
addedCard = new Card();
}
cardLabel.setIcon(GUICard.getIcon(addedCard));
gameView.pnlPlayArea.add(cardLabel, 2);
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameView.setVisible(true);
gameModel.addCardToComputer(this);
gameView.pnlHumanHand.validate();
gameView.pnlHumanHand.repaint();
}
else if(validSelection(stackValueLeft, playerValue))
{
gameView.pnlComputerHand.remove(cardLabel);
gameView.pnlPlayArea.remove(0);
gameView.pnlComputerHand.validate();
gameView.pnlComputerHand.repaint();
Card addedCard;
switch (cardName.charAt(5))
{
case 'c':
addedCard = new Card(cardName.charAt(0), Card.Suit.clubs);
break;
case 'd':
addedCard = new Card(cardName.charAt(0), Card.Suit.diamonds);
break;
case 'h':
addedCard = new Card(cardName.charAt(0), Card.Suit.hearts);
break;
case 's':
addedCard = new Card(cardName.charAt(0), Card.Suit.spades);
break;
default:
addedCard = new Card();
}
cardLabel.setIcon(GUICard.getIcon(addedCard));
gameView.pnlPlayArea.add(cardLabel, 0);
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameView.setVisible(true);
gameModel.addCardToComputer(this);
gameView.pnlHumanHand.validate();
gameView.pnlHumanHand.repaint();
}
gameView.pnlPlayArea.remove(1);
gameView.pnlPlayArea.add(new JLabel("Computer score: " +
(++gameModel.computerScore), SwingConstants.CENTER), 1);
gameView.pnlHumanHand.validate();
gameView.pnlHumanHand.repaint();
gameView.pnlPlayArea.validate();
gameView.pnlPlayArea.repaint();
gameView.setVisible(true);
final JOptionPane pane = new JOptionPane(new JLabel("Click ok to
continue",
JLabel.CENTER));
final JDialog d = pane.createDialog((JFrame) null, "Card Played by
Computer");
d.setLocationRelativeTo(gameView.pnlComputerHand);
d.setVisible(true);
cardLabel.removeMouseListener(currentMouseAdapter);
}
}
}

// Displays the winner of the game and ends game


private void showWinner()
{
final JOptionPane pane;
if(gameModel.computerScore == gameModel.yourScore)
{
pane = new JOptionPane(new JLabel("<html>THE GAME IS A DRAW!<br><br>Click
ok"
+ " to close.</html>",JLabel.CENTER));
}
else if(gameModel.computerScore > gameModel.yourScore)
{
pane = new JOptionPane(new JLabel("<html>COMPUTER WINS!<br><br>Click ok to
"
+ "close.</html>",JLabel.CENTER));
}
else
{
pane = new JOptionPane(new JLabel("<html>YOU WIN!<br><br>Click ok to
close."
+ "</html>",JLabel.CENTER));
}
final JDialog d = pane.createDialog((JFrame) null, "Deck ran out of cards");
d.setLocationRelativeTo(gameView.pnlComputerHand);
d.setSize(400, 150);
d.setVisible(true);
System.exit(-1);
}

// Determines the string associated with the


// card the computer selects
public String computerSelect()
{
for (int i = 0; i < gameView.pnlComputerHand.getComponents().length; i++)
{
int stackValueLeft = getValueOfCard(
gameView.pnlPlayArea.getComponent(0).getName().charAt(0));
int stackValueRight = getValueOfCard(
gameView.pnlPlayArea.getComponent(2).getName().charAt(0));
int playerValue = getValueOfCard(
gameView.pnlComputerHand.getComponent(i).getName().charAt(0));
if(validSelection(stackValueRight, playerValue)
|| validSelection(stackValueLeft, playerValue))
return gameView.pnlComputerHand.getComponent(i).getName();
}
return null;
}

// Converts the char value of a card to an integer


public int getValueOfCard(char cardChar)
{
char[] orderChars =
{ '1', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A',
'X' };
for (int i = 0; i < orderChars.length; i++)
{
if (cardChar == orderChars[i])
return i;
}
return 0;
}

// Returns the string associated with the largest value card


// in the computers hand
public String getMaxCard()
{
int max = 0;
String maxCard = gameView.pnlComputerHand.getComponent(0).getName();
for (int i = 0; i < gameView.pnlComputerHand.getComponents().length; i++)
{
if
(getValueOfCard(gameView.pnlComputerHand.getComponent(i).getName().charAt(0))
>= max)
{
maxCard = gameView.pnlComputerHand.getComponent(i).getName();
max = getValueOfCard(maxCard.charAt(0));
}
}
return maxCard;
}

// Returns the string associated with the smallest value card


// in the computers hand
public String getMinCard()
{
int min = getValueOfCard(
gameView.pnlComputerHand.getComponent(0).getName().charAt(0));
String minCard = gameView.pnlComputerHand.getComponent(0).getName();
for (int i = 1; i < gameView.pnlComputerHand.getComponents().length; i++)
{
if
(getValueOfCard(gameView.pnlComputerHand.getComponent(i).getName().charAt(0))
<= min)
{
minCard = gameView.pnlComputerHand.getComponent(i).getName();
min = getValueOfCard(minCard.charAt(0));
}
}
return minCard;
}
}

/**
* Model class that establishes the framework for the
* "Timed High-Card" game. Includes accessors and mutators
* that the Controller can use to access and change data.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class CardGameModel
{
// Initializes the number of cards in each hand and the number
// of players
static final int NUM_CARDS_PER_HAND = 7;
static final int NUM_PLAYERS = 2;
// Initializes the label arrays that will contain the images
// and text that will be displayed on the GUI.
public JLabel[] computerLabels = new JLabel[NUM_CARDS_PER_HAND];
public JLabel[] humanLabels = new JLabel[NUM_CARDS_PER_HAND];
public JLabel[] playedCardLabels = new JLabel[NUM_PLAYERS];
public JLabel[] playLabelText = new JLabel[NUM_PLAYERS + 2];
public boolean noPlay = false;
public int yourScore = 0;
public int computerScore = 0;
private CardGameFramework build;
private CardGameView myCardTable;

// Default constructor
public CardGameModel()
{
setCardFramework();
}

// Mutator for build


private void setCardFramework()
{
int numPacksPerDeck = 1;
int numJokersPerPack = 0;
int numUnusedCardsPerPack = 0;
Card[] unusedCardsPerPack = null;

build = new CardGameFramework(numPacksPerDeck, numJokersPerPack,


numUnusedCardsPerPack, unusedCardsPerPack, NUM_PLAYERS,
NUM_CARDS_PER_HAND);
if (!build.deal())
{
System.exit(-1);
}
}

//Initializes the View


public void init(CardGameController controller, CardGameView gameView)
{
myCardTable = gameView;
int k = 0;

// establish main frame in which program will run


myCardTable.setSize(800, 800);
myCardTable.setLocationRelativeTo(null);
myCardTable.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myCardTable.setLayout(new GridLayout(CardGameView.MAX_PLAYERS + 2,
CardGameView.MAX_CARDS_PER_HAND));

/** Area dedicated to the played card panel **/


// creates played card labels
for (k = 0; k < CardGameModel.NUM_PLAYERS; k++)
{
Card tCard = build.getCardFromDeck();
playedCardLabels[k] = new JLabel(GUICard.getIcon(tCard));
playedCardLabels[k].setName(tCard.toString());
}
// adds labels to play area panel
myCardTable.pnlPlayArea.add(playedCardLabels[0]);
myCardTable.pnlPlayArea.add(new JLabel("Computer score: " + computerScore,
SwingConstants.CENTER));
myCardTable.pnlPlayArea.add(playedCardLabels[1]);
myCardTable.pnlPlayArea.add(new JLabel("Left", SwingConstants.CENTER));
myCardTable.pnlPlayArea.add(new JLabel("Your score: " + yourScore,
SwingConstants.CENTER));
myCardTable.pnlPlayArea.add(new JLabel("Right", SwingConstants.CENTER));
/** Area dedicated to the played card panel **/
/** Area dedicated to the human hand panel **/
// creates human card labels
for (k = 0; k < CardGameModel.NUM_CARDS_PER_HAND; k++)
{
Card tCard = build.getHand(1).inspectCard(k);
humanLabels[k] = new JLabel(GUICard.getIcon(tCard));
humanLabels[k].setName(tCard.toString());
humanLabels[k].addMouseListener(new GameMouseAdapter(controller));
}
// adds labels to human labels panel
for (JLabel label : humanLabels)
{
myCardTable.pnlHumanHand.add(label);
}
/** Area dedicated to the human hand panel **/

/** Area dedicated to the computer hand panel **/


// creates computer card labels
for (k = 0; k < CardGameModel.NUM_CARDS_PER_HAND; k++)
{
Card tCard = build.getHand(0).inspectCard(k);
computerLabels[k] = new JLabel(GUICard.getCardBackIcon());
computerLabels[k].setName(tCard.toString());
}
// adds labels to computer labels panel
for (JLabel label : computerLabels)
{
myCardTable.pnlComputerHand.add(label);
}
/** Area dedicated to the computer hand panel **/

// add JPanels to myCardTable


myCardTable.add(myCardTable.pnlComputerHand);
myCardTable.add(myCardTable.pnlPlayArea);
myCardTable.add(myCardTable.pnlHumanHand);
myCardTable.add(myCardTable.timerPanel);

// sets layout of each JPanel


myCardTable.pnlComputerHand.setLayout(new GridLayout(1,
CardGameView.MAX_CARDS_PER_HAND));
myCardTable.pnlPlayArea.setLayout(new GridLayout(2, 3, 0, -35));
myCardTable.pnlHumanHand.setLayout(new GridLayout(1,
CardGameView.MAX_CARDS_PER_HAND));

/** Area dedicated to the timer **/


TitledBorder timerTitle = BorderFactory.createTitledBorder("Buttons Area");
myCardTable.timerPanel.setBorder(timerTitle);
myCardTable.timerPanel.setLayout(new FlowLayout());

JLabel lblTimer = new JLabel("0.00");


JButton btnTimer = new JButton("Start");
btnTimer.addActionListener(new TimerButtonListener(lblTimer, btnTimer));

myCardTable.timerPanel.add(btnTimer);
myCardTable.timerPanel.add(lblTimer);
/** Area dedicated to the timer **/

/** Area dedicated to the no play button **/


JButton noPlayBtn = new JButton("I cannot play.");
noPlayBtn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
noPlay = true;
controller.computerTurn();
}
});
myCardTable.timerPanel.add(noPlayBtn);
myCardTable.timerPanel.add(btnTimer);
myCardTable.timerPanel.add(lblTimer);
/** Area dedicated to the no play button **/

TitledBorder compTitle = BorderFactory.createTitledBorder("Computer Hand");


myCardTable.pnlComputerHand.setBorder(compTitle);
TitledBorder areaTitle = BorderFactory.createTitledBorder("Playing Area");
myCardTable.pnlPlayArea.setBorder(areaTitle);
TitledBorder playerTitle = BorderFactory.createTitledBorder("Your Hand");
myCardTable.timerPanel.setBackground(Color.white);
// show everything to the user
myCardTable.setVisible(true);
}

// Adds new cards to the play area from the deck


public boolean addCardsToPlayArea(CardGameController controller)
{
Card tCardLeft = build.getCardFromDeck();
if(!tCardLeft.isErrorFlag())
{
myCardTable.pnlPlayArea.remove(0);
JLabel playedLabel = new JLabel(GUICard.getIcon(tCardLeft));
playedLabel.setName(tCardLeft.toString());
myCardTable.pnlPlayArea.add(playedLabel, 0);
}
else
{
return false;
}
Card tCardRight = build.getCardFromDeck();
if(!tCardRight.isErrorFlag())
{
myCardTable.pnlPlayArea.remove(2);
JLabel playedLabel = new JLabel(GUICard.getIcon(tCardRight));
playedLabel.setName(tCardRight.toString());
myCardTable.pnlPlayArea.add(playedLabel, 2);
}
return true;
}

//Adds a new card to the player's hand from the deck


public boolean addCardToPlayer(CardGameController controller)
{
Card tCard = build.getCardFromDeck();
if(!tCard.isErrorFlag())
{
JLabel humanLabel = new JLabel(GUICard.getIcon(tCard));
humanLabel.setName(tCard.toString());
humanLabel.addMouseListener(new GameMouseAdapter(controller));
myCardTable.pnlHumanHand.add(humanLabel);
return true;
}
else
{
return false;
}
}

//Adds a new card to the computer's hand from the deck


public boolean addCardToComputer(CardGameController controller)
{
Card tCard = build.getCardFromDeck();
if(!tCard.isErrorFlag())
{
JLabel computerLabel = new JLabel(GUICard.getCardBackIcon());
computerLabel.setName(tCard.toString());
computerLabel.addMouseListener(new GameMouseAdapter(controller));
myCardTable.pnlComputerHand.add(computerLabel);
return true;
}
else
{
return false;
}
}

// Generates a random Card by getting two random numbers,


// with one representing the value and one representing the suit
static Card generateRandomCard()
{
Random random = new Random();
int RandomValueInt = random.nextInt(14);
int RandomSuitInt = random.nextInt(4);
String value = GUICard.turnIntIntoCardValue(RandomValueInt);
String suit = GUICard.turnIntIntoCardSuit(RandomSuitInt);
switch (suit)
{
case "C":
return new Card(value.charAt(0), Card.Suit.clubs);
case "D":
return new Card(value.charAt(0), Card.Suit.diamonds);
case "H":
return new Card(value.charAt(0), Card.Suit.hearts);
case "S":
return new Card(value.charAt(0), Card.Suit.spades);
default:
return new Card();
}
}
}

/**
* JFrame class that controls the positioning of the panels and cards within a
* GUI.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*/
class CardGameView extends JFrame
{
static int MAX_CARDS_PER_HAND = 56;
static int MAX_PLAYERS = 2; // for now, we only allow 2 person games

private int numCardsPerHand;


private int numPlayers;

public JPanel pnlComputerHand, pnlHumanHand, pnlPlayArea, timerPanel;

/**
* Constructor which creates a JFrame, using the parameters to determine the
* title and number of panels used
*
* @param String title, int numCardsPerHand, int numPlayers
*/
public CardGameView(String title, int numCardsPerHand, int numPlayers)
{
super(title);
pnlComputerHand = new JPanel();
pnlPlayArea = new JPanel();
pnlHumanHand = new JPanel();
timerPanel = new JPanel();

if (numCardsPerHand > 0 && numCardsPerHand <= MAX_CARDS_PER_HAND)


{
this.numCardsPerHand = numCardsPerHand;
} else
{
this.numCardsPerHand = MAX_CARDS_PER_HAND;
}

if (numPlayers > 0 && numPlayers <= MAX_PLAYERS)


{
this.numPlayers = numPlayers;
} else
{
this.numPlayers = MAX_PLAYERS;
}
}

// Accessor for the number of cards per hand


public int getNumCardsPerHand()
{
return numCardsPerHand;
}

// Accessor for the number of players


public int getNumPlayers()
{
return numPlayers;
}

/**
* MouseAdapter class that handles how the game processes a user
* clicking on a card
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class GameMouseAdapter extends MouseAdapter
{
private CardGameController controller;

/**
* Constructor that sets myCardTable and build
*
* @param CardTable myCardTable, CardGameFramework build
*/
public GameMouseAdapter(CardGameController controller)
{
this.controller = controller;
}

/*
* (non-Javadoc)
*
* @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
*/
// Selects the card the user clicks on and
// places it into the play area
@Override
public void mousePressed(MouseEvent e)
{
final String componentName = e.getComponent().getName();
controller.processPlayerTurn(componentName);
}

/*
* (non-Javadoc)
*
* @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
*/
@Override
public void mouseReleased(MouseEvent e)
{
super.mouseReleased(e);
}
}

/**
* Class that stores images of cards into a two-dimensional array
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*/
class GUICard
{
private static Icon[][] iconCards = new ImageIcon[14][4];
// 14 = A thru K + joker
private static Icon iconBack;
static boolean iconsLoaded = false;

// Loads 56 card images into a two-dimensional array


static void loadCardIcons()
{
if (!iconsLoaded)
{
for (int i = 0; i < iconCards.length; i++)
{
for (int j = 0; j < iconCards[i].length; j++)
{
iconCards[i][j] = new ImageIcon(
"src/images/" + turnIntIntoCardValue(i)
+ turnIntIntoCardSuit(j) + ".gif");
}
}
iconBack = new ImageIcon("src/images/BK.gif");
iconsLoaded = true;
}
}

// turns 0 - 13 into "A", "2", "3", ... "Q", "K", "X"


static String turnIntIntoCardValue(int k)
{
if (k > -1 && k < 14)
{
switch (k)
{
case 0:
return "A";
case 9:
return "T";
case 10:
return "J";
case 11:
return "Q";
case 12:
return "K";
case 13:
return "X";
default:
int startVal = '1';
return "" + (char) (startVal + k);
}
}
return null;
}

// turns 0 - 3 into "C", "D", "H", "S"


static String turnIntIntoCardSuit(int j)
{
switch (j)
{
case 0:
return "C";
case 1:
return "D";
case 2:
return "H";
case 3:
return "S";
default:
return null;
}
}
// turns the char value of a Card into an int
static int valueAsInt(Card card)
{
switch (card.getValue())
{
case 'A':
return 0;
case 'T':
return 9;
case 'J':
return 10;
case 'Q':
return 11;
case 'K':
return 12;
case 'X':
return 13;
default:
return card.getValue() - '1';
}
}

// turns a suit value into an int


static int suitAsInt(Card card)
{
switch (card.getSuit())
{
case clubs:
return 0;
case diamonds:
return 1;
case hearts:
return 2;
case spades:
return 3;
default:
return -1;
}
}

// returns an Icon from the array of all card icons


static public Icon getIcon(Card card)
{
GUICard.loadCardIcons();
return iconCards[valueAsInt(card)][suitAsInt(card)];
}

// returns the card back Icon


static public Icon getCardBackIcon()
{
GUICard.loadCardIcons();
return iconBack;
}
}

/**
* Card class which holds suit and value of a card
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class Card
{
public enum Suit
{
clubs, diamonds, hearts, spades
};

private Suit suit;


private char value;
private boolean errorFlag;

public static char[] valuRanks =


{ 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'X' };

/**
* Constructor - constructor for the Card Class
*
* @param value The value of the card
* @param suit The suit of the card
*/
public Card(char value, Suit suit)
{
set(value, suit);
}

/**
* Mutator that accepts the legal values established in the earlier section
*
* @param value The value of the card
* @param suit The suit of the card
* @return Returns a boolean indicating whether or not the values were set
*/
public boolean set(char value, Suit suit)
{
value = Character.toUpperCase(value);
if (isValid(value, suit))
{
this.suit = suit;
this.value = value;
this.errorFlag = false;
return true;
}
this.errorFlag = true;
return false;
}

/**
* Accessor for suit
*
* @return Returns the current card's suit
*/
public Suit getSuit()
{
return suit;
}

/**
* Accessor for value
*
* @return the value
*/
public char getValue()
{
return value;
}

/**
* Accessor for errorFlag
*
* @return the errorFlag
*/
public boolean isErrorFlag()
{
return errorFlag;
}

/**
* Stringizer method that the client can use prior to displaying the card.
*
* @return Returns a string representation of a card
*/
@Override
public String toString()
{
if (errorFlag)
return "** illegal **";
return value + " of " + suit;
}

/**
* Constructor called when client does not pass parameter
*/
public Card()
{
this('A', Card.Suit.spades);
}

/**
* Tests equality between two Card
*
* @param card A card that will be compared with current card
* @return Returns a boolean indicating whether or not they are equal
*/
public boolean equals(Card card)
{
if (card.getSuit() == this.getSuit() && card.getValue() == this.getValue()
&& card.isErrorFlag() == this.isErrorFlag())
return true;
return false;
}

/**
* Helper method that returns true or false, depending on the legality of the
* parameters
*
* @param value Character variable for value of card
* @param suit Suit variable for suit of card
* @return Returns a boolean indicating whether or not the card is valid
*/
private boolean isValid(char value, Suit suit)
{
char[] values =
{ 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'X' };
for (char acceptedValue : values)
{
if (acceptedValue == value)
{
return true;
}
}
return false;
}

//Sorts a card array from least to greatest using a bubble sort


public static void arraySort(Card[] cards, int arraySize)
{
Card temp = new Card();
for (int i = 0; i < arraySize; i++)
{
for (int j = 1; j < (arraySize - i); j++)
{
if (cards[j - 1].getValue() > cards[j].getValue())
{
temp = cards[j - 1];
cards[j - 1] = cards[j];
cards[j] = temp;
}
}
}
}
}

/**
* Class that represents the cards held by a single player.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class Hand
{
public static final int MAX_CARDS = 100;

private Card[] myCards;


private int numCards;

/**
* Default constructor
*/
public Hand()
{
myCards = new Card[MAX_CARDS];
resetHand();
}

/**
* Removes all cards from the hand (in the simplest way).
*/
public void resetHand()
{
for (int i = 0; i < numCards; i++)
{
if (myCards[i] == null)
return;
myCards[i] = null;
}
numCards = 0;
}

/**
* adds a card to the next available position in the myCards array. This is an
* object copy, not a reference copy, since the source of the Card might destroy
* or change its data after our Hand gets it -- we want our local data to be
* exactly as it was when we received it.
*
* @param card A card that will be added to the hand
* @return Returns a boolean indicating whether or not a card is added
*/
public boolean takeCard(Card card)
{
if (numCards < MAX_CARDS)
{
myCards[numCards++] = new Card(card.getValue(), card.getSuit());

return true;
}
return false;
}

/**
* Returns and removes the card in the top occupied position of the array.
*
* @return Returns a card from the top occupied position of the array
*/
public Card playCard(int index)
{
if (numCards > 0 && index < numCards)
{
/*
* Card topCard = myCards[--numCards]; //deebee modified myCards[numCards]
=
* null; return topCard;
*/
Card retCard = myCards[index];
myCards[index] = null;
return retCard;
}
return inspectCard(-1);
}

/**
* Accessor for an individual card.
*
* @return Returns a card with errorFlag = true if k is bad.
*/
public Card inspectCard(int k)
{
if (k < 0 || k >= numCards)
{
return new Card('F', Card.Suit.spades);
}
return myCards[k];
}

/**
* Accessor for numCards
*
* @return Returns the integer value for numCards
*/
public int getNumCards()
{
return numCards;
}

/**
* Stringizer method that the client can use prior to displaying the entire
* hand.
*
* @return Returns a string representation of a hand
*/
@Override
public String toString()
{
if (numCards > 0)
{
String retString = "Hand = ";
retString += "(";
for (int i = 0; i < numCards; i++)
{
retString += " " + myCards[i] + ",";
}
retString = retString.substring(0, retString.length() - 1);
retString += " )";
return retString;
}
return "Empty hand";
}

//Sorts the hand's array of cards from least to greatest


public void sort()
{
Card.arraySort(myCards, myCards.length);
}
}

/**
* Class that represents the source of the cards for dealing and, as the game
* progresses, the place from which players can receive new cards
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class Deck
{
public static final int MAX_CARDS = 6 * 56;

private static Card[] masterPack;

private Card[] cards;


private int topCard;
private int numPacks;

/**
* Constructor that populates the arrays and assigns initial values to members.
*
* @param numPacks int
*/
public Deck(int numPacks)
{
allocateMasterPack();
init(numPacks);
}

/**
* Default Constructor
*/
public Deck()
{
this(1);
}

/**
* Shuffles the deck of cards using the Fisher-Yates shuffle algorithm
*/
public void shuffle()
{
Random random = new Random();
for (int i = topCard; i > 0; i--)
{
int index = random.nextInt(i);
Card tempCard = cards[index];
cards[index] = cards[i];
cards[i] = tempCard;
}
}

/**
* Removes card from top of deck and returns it
*
* @return Returns a Card from the top of the deck
*/
public Card dealCard()
{
if (topCard >= 0)
{
Card dealtCard = new Card();
while (topCard-- > 0)
{
dealtCard = cards[topCard];
if (dealtCard != null)
{
break;
}
}
cards[topCard + 1] = null;
if(dealtCard != null)
return dealtCard;
}
return inspectCard(-1);
}

/**
* Accessor for card, checks if the card asked for is valid
*
* @param k An integer representing the kth card in the deck
* @return Returns the kth Card in the array cards
*/
public Card inspectCard(int k)
{
if (k < 0 || k > topCard)
{
return new Card('F', Card.Suit.spades);
}
return cards[k];
}

/**
* Re-populates the deck based on the numPacks using masterPack
*
* @param numPacks The amount of packs a deck will have
*/
public void init(int numPacks)
{
if (!setNumPacks(numPacks))
return;
cards = new Card[numPacks * 56];
int count = 0;
for (int i = 0; i < numPacks; i++)
{
for (Card card : masterPack)
{
cards[count] = card;
count++;
if (count == numPacks * 56)
break;
}
}
this.topCard = numPacks * 56 - 1;
}

/**
* Mutator method sets value of numPacks after checked for validity
*
* @param numPacks The amount of packs a deck will have
* @return Returns true if numPacks was valid and set
*/
public boolean setNumPacks(int numPacks)
{
if (numPacks * 56 > MAX_CARDS || numPacks <= 0)
return false;
this.numPacks = numPacks;
return true;
}

/**
* Builds a masterPack with all 52 cards
*/
private static void allocateMasterPack()
{
if (masterPack == null)
{
masterPack = new Card[56];
Card.Suit[] suits =
{ Card.Suit.clubs, Card.Suit.diamonds, Card.Suit.hearts,
Card.Suit.spades };

int count = 0;
for (Card.Suit suit : suits)
{
for (char value : Card.valuRanks)
{
masterPack[count] = new Card(value, suit);
count++;
}
}
}
}

/**
* Accessor for cards
*
* @return Returns an array of Card objects
*/
public Card[] getCards()
{
return this.cards;
}

/**
* Accessor for topCard
*
* @return Returns the integer topCard
*/
public int getTopCard()
{
return this.topCard;
}

//Add a card to the top of the deck


public boolean addCard(Card card)
{
for (int i = 0; i < masterPack.length; i++)
{
if (masterPack[i] == null)
{
masterPack[i] = card;
return true;
}
if (masterPack[i].equals(card))
{
return false;
}
}
masterPack[topCard + 1] = card;
return true;
}

//Remove a specific card from the deck


public boolean removeCard(Card card)
{
for (int i = 0; i < this.cards.length; i++)
{
if (cards[i] == null)
{
continue;
}
if (cards[i].equals(card))
{
cards[i] = null;
return true;
}
}
return false;
}

//Sorts the deck from least to greatest values


public void sort()
{
Card.arraySort(masterPack, masterPack.length);
}

//Accessor for the number of cards remaining


//in the deck
public int getNumCards()
{
int numCards = 0;
for (int i = 0; i < masterPack.length; i++)
{
if (masterPack[i] != null)
{
numCards++;
}
}
return numCards;
}
}

// class CardGameFramework ----------------------------------------------------


// provided by CSU MB
class CardGameFramework
{
private static final int MAX_PLAYERS = 50;
private int numPlayers;
private int numPacks; // # standard 52-card packs per deck
// ignoring jokers or unused cards
private int numJokersPerPack; // if 2 per pack & 3 packs per deck, get 6
private int numUnusedCardsPerPack; // # cards removed from each pack
private int numCardsPerHand; // # cards to deal each player
private Deck deck; // holds the initial full deck and gets
// smaller (usually) during play
private Hand[] hand; // one Hand for each player
private Card[] unusedCardsPerPack; // an array holding the cards not used
// in the game. e.g. pinochle does not
// use cards 2-8 of any suit

public CardGameFramework(int numPacks, int numJokersPerPack,


int numUnusedCardsPerPack, Card[] unusedCardsPerPack,
int numPlayers, int numCardsPerHand)
{
int k;

// filter bad values


if (numPacks < 1 || numPacks > 6)
numPacks = 1;
if (numJokersPerPack < 0 || numJokersPerPack > 4)
numJokersPerPack = 0;
if (numUnusedCardsPerPack < 0 || numUnusedCardsPerPack > 50) // > 1 card
numUnusedCardsPerPack = 0;
if (numPlayers < 1 || numPlayers > MAX_PLAYERS)
numPlayers = 4;

// one of many ways to assure at least one full deal to all players
if (numCardsPerHand < 1 || numCardsPerHand > numPacks
* (52 - numUnusedCardsPerPack) / numPlayers)
numCardsPerHand = numPacks * (52 - numUnusedCardsPerPack) / numPlayers;

// allocate
this.unusedCardsPerPack = new Card[numUnusedCardsPerPack];
this.hand = new Hand[numPlayers];
for (k = 0; k < numPlayers; k++)
this.hand[k] = new Hand();
deck = new Deck(numPacks);

// assign to members
this.numPacks = numPacks;
this.numJokersPerPack = numJokersPerPack;
this.numUnusedCardsPerPack = numUnusedCardsPerPack;
this.numPlayers = numPlayers;
this.numCardsPerHand = numCardsPerHand;
for (k = 0; k < numUnusedCardsPerPack; k++)
this.unusedCardsPerPack[k] = unusedCardsPerPack[k];

// prepare deck and shuffle


newGame();
}

// constructor overload/default for game like bridge


public CardGameFramework()
{
this(1, 0, 0, null, 4, 13);
}

// Returns a player's hand'


public Hand getHand(int k)
{
// hands start from 0 like arrays

// on error return automatic empty hand


if (k < 0 || k >= numPlayers)
return new Hand();

return hand[k];
}

// Deals a card from deck


public Card getCardFromDeck()
{
return deck.dealCard();
}

// Returns the count of remaining cards in deck


public int getNumCardsRemainingInDeck()
{
return deck.getNumCards();
}

// creates a new game


public void newGame()
{
int k, j;

// clear the hands


for (k = 0; k < numPlayers; k++)
hand[k].resetHand();

// restock the deck


deck.init(numPacks);

// remove unused cards


for (k = 0; k < numUnusedCardsPerPack; k++)
deck.removeCard(unusedCardsPerPack[k]);

// add jokers
for (k = 0; k < numPacks; k++)
for (j = 0; j < 4 - numJokersPerPack; j++)
deck.removeCard(new Card('X', Card.Suit.values()[j]));

// shuffle the cards


deck.shuffle();
}

// Deals cards for game


public boolean deal()
{
// returns false if not enough cards, but deals what it can
int k, j;
boolean enoughCards;

// clear all hands


for (j = 0; j < numPlayers; j++)
hand[j].resetHand();

enoughCards = true;
for (k = 0; k < numCardsPerHand && enoughCards; k++)
{
for (j = 0; j < numPlayers; j++)
if (deck.getNumCards() > 0)
hand[j].takeCard(deck.dealCard());
else
{
enoughCards = false;
break;
}
}
return enoughCards;
}
// Sorts hands using the sort method
void sortHands()
{
int k;

for (k = 0; k < numPlayers; k++)


hand[k].sort();
}

// Plays card from a player's hand


Card playCard(int playerIndex, int cardIndex)
{
// returns bad card if either argument is bad
if (playerIndex < 0 || playerIndex > numPlayers - 1 || cardIndex < 0
|| cardIndex > numCardsPerHand - 1)
{
// Creates a card that does not work
return new Card('M', Card.Suit.spades);
}

// return the card played


return hand[playerIndex].playCard(cardIndex);
}

// Takes a card from deck for a player hand


boolean takeCard(int playerIndex)
{
// returns false if either argument is bad
if (playerIndex < 0 || playerIndex > numPlayers - 1)
return false;

// Are there enough Cards?


if (deck.getNumCards() <= 0)
return false;

return hand[playerIndex].takeCard(deck.dealCard());
}
}

/**
* Timer class that utilizes multithreading to initialize a counter
* that increases while Thread.sleep is active.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class Timer extends Thread
{
private static long seconds = 0;
private JLabel lblTimer;
private JButton btnTimer;
private boolean isSleeping;

/**
* @return the isSleeping
*/
public boolean isSleeping() {
return isSleeping;
}
/**
* @param isSleeping the isSleeping to set
*/
public void setSleeping(boolean isSleeping) {
this.isSleeping = isSleeping;
}
/**
* @return the seconds
*/
public static long getSeconds() {
return seconds;
}
/**
* @param seconds the seconds to set
*/
public static void setSeconds(long seconds) {
Timer.seconds = seconds;
}
public Timer(JLabel lblTimer, JButton btnTimer) {
this.lblTimer = lblTimer;
this.btnTimer = btnTimer;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
doNothing();
}

//Puts a thread in suspension and increases and updates


//a counter while it remains in suspension.
public void doNothing()
{
while(true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(!isSleeping)
{
seconds++;
lblTimer.setText(secondsToString(seconds));
}
}
}
/**
* Formats the total seconds
*
* @param pTime
* @return
*/
private String secondsToString(long pTime) {
return String.format("%02d:%02d", pTime / 60, pTime % 60);
}
}

/**
* ActionListener class that starts and stops a timer when
* the timer button is clicked.
*
* @author Moises Bernal, Debajyoti Banerjee, and Nicholas Tippner
*
*/
class TimerButtonListener implements ActionListener
{
private Timer timer;
private JLabel lblTimer;
private JButton btnTimer;

/**
* Constructor class
*
* @param lblTimer
* @param btnTimer
*/
public TimerButtonListener(JLabel lblTimer, JButton btnTimer) {
timer = new Timer(lblTimer, btnTimer);
this.lblTimer = lblTimer;
this.btnTimer = btnTimer;
}

//Starts timer if timer is off, stops timer if timer is on


@Override
public void actionPerformed(ActionEvent e) {
if(btnTimer.getText().equalsIgnoreCase("Start"))
{
if(!timer.isAlive())
timer.start();
timer.setSleeping(false);
btnTimer.setText("Stop");
}
else
{
btnTimer.setText("Start");
timer.setSeconds(0);
timer.setSleeping(true);
}
}
}

You might also like