- Upload a zip file, including PlayingCard.java and VideoPoker.java, - Implement
ID: 3839666 • Letter: #
Question
- Upload a zip file, including PlayingCard.java and VideoPoker.java,
- Implement poker game program in package PJ4:
Part I (40%) Implement Decks class
Part II (60%) Implement VideoPoker class
Bonus (30%) Add GUI, only after you have completed I & II
Must complete by same due date.
Submit both non-GUI and GUI versions
See PJ4/PlayingCard.java and PJ4/VideoPoker.java for more info.
- Use TestVideoPoker.java to test correctness of your program
- Compile programs (you are in directory containing Readme file):
javac PJ4/*.java
javac TestVideoPoker.java
- Run programs (you are in directory containing Readme file):
// Run tests in PJ4 classes
java PJ4.Decks
java PJ4.VideoPoker
// Run main test program
java TestVideoPoker
//////////////////////////////////////////////////////////////////////////////////////
package PJ4;
import java.util.*;
/*
* Ref: http://en.wikipedia.org/wiki/Video_poker
* http://www.freeslots.com/poker.htm
*
*
* Short Description and Poker rules:
*
* Video poker is also known as draw poker.
* The dealer uses a 52-card deck, which is played fresh after each playerHand.
* The player is dealt one five-card poker playerHand.
* After the first draw, which is automatic, you may hold any of the cards and draw
* again to replace the cards that you haven't chosen to hold.
* Your cards are compared to a table of winning combinations.
* The object is to get the best possible combination so that you earn the highest
* payout on the bet you placed.
*
* Winning Combinations
*
* 1. One Pair: one pair of the same card
* 2. Two Pair: two sets of pairs of the same card denomination.
* 3. Three of a Kind: three cards of the same denomination.
* 4. Straight: five consecutive denomination cards of different suit.
* 5. Flush: five non-consecutive denomination cards of the same suit.
* 6. Full House: a set of three cards of the same denomination plus
* a set of two cards of the same denomination.
* 7. Four of a kind: four cards of the same denomination.
* 8. Straight Flush: five consecutive denomination cards of the same suit.
* 9. Royal Flush: five consecutive denomination cards of the same suit,
* starting from 10 and ending with an ace
*
*/
/* This is the video poker game class.
* It uses Decks and Card objects to implement video poker game.
* Please do not modify any data fields or defined methods
* You may add new data fields and methods
* Note: You must implement defined methods
*/
public class VideoPoker {
// default constant values
private static final int startingBalance=100;
private static final int numberOfCards=5;
// default constant payout value and playerHand types
private static final int[] multipliers={1,2,3,5,6,10,25,50,1000};
private static final String[] goodHandTypes={
"One Pair" , "Two Pairs" , "Three of a Kind", "Straight", "Flush ",
"Full House", "Four of a Kind", "Straight Flush", "Royal Flush" };
// must use only one deck
private final Decks oneDeck;
// holding current poker 5-card hand, balance, bet
private List<Card> playerHand;
private int playerBalance;
private int playerBet;
/** default constructor, set balance = startingBalance */
public VideoPoker()
{
this(startingBalance);
}
/** constructor, set given balance */
public VideoPoker(int balance)
{
this.playerBalance= balance;
Decks(1, false);
}
/** This display the payout table based on multipliers and goodHandTypes arrays */
private void showPayoutTable()
{
System.out.println(" ");
System.out.println("Payout Table Multiplier ");
System.out.println("=======================================");
int size = multipliers.length;
for (int i=size-1; i >= 0; i--) {
System.out.println(goodHandTypes[i]+" | "+multipliers[i]);
}
System.out.println(" ");
}
/** Check current playerHand using multipliers and goodHandTypes arrays
* Must print yourHandType (default is "Sorry, you lost") at the end of function.
* This can be checked by testCheckHands() and main() method.
*/
private void checkHands()
{
// implement this method!
}
/*************************************************
* add new private methods here ....
*
*************************************************/
public void play()
{
/** The main algorithm for single player poker game
*
* Steps:
* showPayoutTable()
*
* ++
* show balance, get bet
* verify bet value, update balance
* reset deck, shuffle deck,
* deal cards and display cards
* ask for positions of cards to replace
* get positions in one input line
* update cards
* check hands, display proper messages
* update balance if there is a payout
* if balance = O:
* end of program
* else
* ask if the player wants to play a new game
* if the answer is "no" : end of program
* else : showPayoutTable() if user wants to see it
* goto ++
*/
// implement this method!
}
/*************************************************
* Do not modify methods below
/*************************************************
/** testCheckHands() is used to test checkHands() method
* checkHands() should print your current hand type
*/
public void testCheckHands()
{
try {
playerHand = new ArrayList<Card>();
// set Royal Flush
playerHand.add(new Card(3,1));
playerHand.add(new Card(3,10));
playerHand.add(new Card(3,12));
playerHand.add(new Card(3,11));
playerHand.add(new Card(3,13));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set Straight Flush
playerHand.set(0,new Card(3,9));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set Straight
playerHand.set(4, new Card(1,8));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set Flush
playerHand.set(4, new Card(3,5));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// "Royal Pair" , "Two Pairs" , "Three of a Kind", "Straight", "Flush ",
// "Full House", "Four of a Kind", "Straight Flush", "Royal Flush" };
// set Four of a Kind
playerHand.clear();
playerHand.add(new Card(4,8));
playerHand.add(new Card(1,8));
playerHand.add(new Card(4,12));
playerHand.add(new Card(2,8));
playerHand.add(new Card(3,8));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set Three of a Kind
playerHand.set(4, new Card(4,11));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set Full House
playerHand.set(2, new Card(2,11));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set Two Pairs
playerHand.set(1, new Card(2,9));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set One Pair
playerHand.set(0, new Card(2,3));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set One Pair
playerHand.set(2, new Card(4,3));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
// set no Pair
playerHand.set(2, new Card(4,6));
System.out.println(playerHand);
checkHands();
System.out.println("-----------------------------------");
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
/* Quick testCheckHands() */
public static void main(String args[])
{
VideoPoker pokergame = new VideoPoker();
pokergame.testCheckHands();
}
}
//////////////////////////////////////////////////////////////////////////////////////
package PJ4;
import java.util.*;
//=================================================================================
/** class PlayingCardException: It is used for errors related to Card and Deck objects
* Do not modify this class!
*/
class PlayingCardException extends Exception {
/* Constructor to create a PlayingCardException object */
PlayingCardException (){
super ();
}
PlayingCardException ( String reason ){
super ( reason );
}
}
//=================================================================================
/** class Card : for creating playing card objects
* it is an immutable class.
* Rank - valid values are 1 to 13
* Suit - valid values are 0 to 4
* Do not modify this class!
*/
class Card {
/* constant suits and ranks */
static final String[] Suit = {"Joker","Clubs", "Diamonds", "Hearts", "Spades" };
static final String[] Rank = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
/* Data field of a card: rank and suit */
private int cardRank; /* values: 1-13 (see Rank[] above) */
private int cardSuit; /* values: 0-4 (see Suit[] above) */
/* Constructor to create a card */
/* throw PlayingCardException if rank or suit is invalid */
public Card(int suit, int rank) throws PlayingCardException {
// suit =0 is joker, rank must be 1 or 2
if (suit==0) {
if ((rank <1) || (rank >2))
throw new PlayingCardException("Invalid rank for Joker:"+rank);
cardRank=rank;
cardSuit=0;
} else {
if ((rank < 1) || (rank > 13))
throw new PlayingCardException("Invalid rank:"+rank);
else
cardRank = rank;
if ((suit < 1) || (suit > 4))
throw new PlayingCardException("Invalid suit:"+suit);
else
cardSuit = suit;
}
}
/* Accessor and toString */
/* You may impelemnt equals(), but it will not be used */
public int getRank() { return cardRank; }
public int getSuit() { return cardSuit; }
public String toString() {
if (cardSuit == 0) return Suit[cardSuit]+" #"+cardRank;
else return Rank[cardRank] + " " + Suit[cardSuit];
}
/* Few quick tests here */
public static void main(String args[])
{
try {
Card c1 = new Card(4,1); // A Spades
System.out.println(c1);
c1 = new Card(1,10); // 10 Clubs
System.out.println(c1);
c1 = new Card(0,2); // Joker #2
System.out.println(c1);
c1 = new Card(5,10); // generate exception here
}
catch (PlayingCardException e)
{
System.out.println("PlayingCardException: "+e.getMessage());
}
}
}
//=================================================================================
/** class Decks represents : n decks of 52 (or 54) playing cards
* Use class Card to construct n * 52 (or 54) playing cards!
*
* Do not add new data fields!
* Do not modify any methods
* You may add private methods
*/
class Decks {
/* this is used to keep track of original n*52 or n*54 cards */
private List<Card> originalDecks;
/* this starts with copying cards from originalDecks */
/* it is used to play the card game */
/* see reset(): resets gameDecks to originalDecks */
private List<Card> gameDecks;
/* number of decks in this object */
private int numberDecks;
private boolean withJokers;
/**
* Constructor: Creates one deck of 52 or 54 (withJokers = false or true)
* playing cards in originalDecks and copy them to gameDecks.
* initialize numberDecks=1
* Note: You need to catch PlayingCardException from Card constructor
* Use ArrayList for both originalDecks & gameDecks
*/
public Decks(boolean withJokers)
{
// implement this method!
}
/**
* Constructor: Creates n decks (54 or 52 cards each deck - with or without Jokers)
* of playing cards in originalDecks and copy them to gameDecks.
* initialize numberDecks=n
* Note: You need to catch PlayingCardException from Card constructor
* Use ArrayList for both originalDecks & gameDecks
*/
public Decks(int n, boolean withJokers)
{
// implement this method!
}
/**
* Task: Shuffles cards in gameDecks.
* Hint: Look at java.util.Collections
*/
public void shuffle()
{
// implement this method!
}
/**
* Task: Deals cards from the gameDecks.
*
* @param numberCards number of cards to deal
* @return a list containing cards that were dealt
* @throw PlayingCardException if numberCard > number of remaining cards
*
* Note: You need to create ArrayList to stored dealt cards
* and should removed dealt cards from gameDecks
*
*/
public List<Card> deal(int numberCards) throws PlayingCardException
{
// implement this method!
return null;
}
/**
* Task: Resets gameDecks by getting all cards from the originalDecks.
*/
public void reset()
{
// implement this method!
}
/**
* Task: Return number of decks.
*/
public int getNumberDecks()
{
return numberDecks;
}
/**
* Task: Return withJokers.
*/
public boolean getWithJokers()
{
return withJokers;
}
/**
* Task: Return number of remaining cards in gameDecks.
*/
public int remainSize()
{
return gameDecks.size();
}
/**
* Task: Returns a string representing cards in the gameDecks
*/
public String toString()
{
return ""+gameDecks;
}
/* Quick test */
/* */
/* Do not modify these tests */
/* Generate 2 decks of 54 cards */
/* Loop 2 times: */
/* Deal 27 cards for 5 times */
/* Expect exception at 5th time*/
/* reset() */
public static void main(String args[]) {
System.out.println("******* Create 2 decks of cards ******** ");
Decks decks = new Decks(2, true);
System.out.println("getNumberDecks:" + decks.getNumberDecks());
System.out.println("getWithJokers:" + decks.getWithJokers());
for (int j=0; j < 2; j++)
{
System.out.println(" ************************************************ ");
System.out.println("Loop # " + j + " ");
System.out.println("Before shuffle:"+decks.remainSize()+" cards");
System.out.println(" "+decks);
System.out.println(" ============================================== ");
int numHands = 5;
int cardsPerHand = 27;
for (int i=0; i < numHands; i++)
{
decks.shuffle();
System.out.println("After shuffle:"+decks.remainSize()+" cards");
System.out.println(" "+decks);
try {
System.out.println(" Hand "+i+":"+cardsPerHand+" cards");
System.out.println(" "+decks.deal(cardsPerHand));
System.out.println(" Remain:"+decks.remainSize()+" cards");
System.out.println(" "+decks);
System.out.println(" ============================================== ");
}
catch (PlayingCardException e)
{
System.out.println("*** In catch block:PlayingCardException:Error Msg: "+e.getMessage());
}
}
decks.reset();
}
}
}
/*************************************************************************************
*
* This program is used to test PJ4.VideoPoker class
* More info are given in Readme file
*
* PJ4 class allows user to run program as follows:
*
* java PJ4 // default credit is $100
* or java PJ4 NNN // set initial credit to NNN
*
* Do not modify this file!
*
**************************************************************************************/
import PJ4.VideoPoker;
class TestVideoPoker {
public static void main(String args[])
{
VideoPoker pokergame;
if (args.length > 0)
pokergame = new VideoPoker(Integer.parseInt(args[0]));
else
pokergame = new VideoPoker();
pokergame.play();
}
}
Explanation / Answer
This seems a lot of work, what I could understand was we have implement a Poker Game. I just went through your code and it can be made efficient through some changes. I am not going to give away the complete code but snippets of the changes required and implementation asked for. So, let's begin:
Your default constructor of VideoPoker is not setting the balance to starting balance, it needs to be modified. It just refers to the balances:
public VideoPoker(){
this(startingBalance);
}
change it to..
public VideoPoker(){
this(startingBalance);
playerBalance = startingBalance;
scanner = new Scanner(System.in);
playerCardsToKeepMap = new HashMap<>();
}
Change your parameterized constructor to this
public VideoPoker(int balance){
this.playerBalance = balance;
scanner = new Scanner(System.in);
playerCardsToKeepMap = new HashMap<>();
}
Now, we have to implement checkHands(). This function only checks if your bet has won something or not, so just check for the bet and increment accordingly, like this:
if(isRoyalFlush()){ --> if it is RoyalFlush
System.out.println("Royal Flush!");
playerBalance += multipliers[8] * playerBet; --> balance is incremented accordingly
}
Same goes for other kind, isFlush(), isFullHouse() and all that. In the else section just put "You Lost !"
Now, we will make the function we have used above i.e. isFullHouse(), isRoyalFlush() and all. So, I will be giving you a hint about it. Royal Flush is when consective cards are of same suit of rank: A, 10, J, Q, K ! So, just implement the logic in this function.
private boolean isRoyalFlush(){ --> returns boolean
int firstCardSuit = playerHand.get(0).getSuit(); --> gets the first card suit
List<Integer> royalFlushRankList = Arrays.asList(1,10,11,12,13);
for(Card card : playerHand){
if(card.getSuit() != firstCardSuit || !royalFlushRankList.contains(card.getRank())) --> check for the rank
return false;
}
return true; --> if loop is executed successfully then it is a Royal Flush !
}
Similarly, go on to make all the method. If you encounter any problem comment below, I would be happy to help.
I will give away the method to Royal Pair also, here it is:
When do we have a Royal Pair? When a hand consists of one pair of identical rank, and 3 cards of different ranks. So, we have to check this only in our method !
private boolean isRoyalPair(){
HashMap<Integer,Integer> rankMap = new HashMap<>();
int pairCounter = 0;
for(Card card : playerHand){
if(!rankMap.containsKey(card.getRank())){
rankMap.put(card.getRank(), 1);
pairCounter = 1;
}
else{
int value = rankMap.get(card.getRank());
rankMap.put(card.getRank(), value+1);
pairCounter++;
}
}
return pairCounter == 2 && rankMap.containsValue(1);
}
Now, we go on to implement some basic functions like
getPlayerBet() --> Check if bet is larger than balance and check to input integers only ! We can use try and catch to build it.
updateBalance() --> playerBalance -= playerBet (updates the current balance)
dealHand() --> to catch exception
try{
playerHand = oneDeck.deal(numberOfCards);
}
catch(PlayingCardException e){
System.out.println("PlayingCardException: " + e.getMessage());
}
getPlayerCardRetainingPositions() --> Check what player want to keep in hand.
if(input.isEmpty()){
return;
}
Else iterate through the positions to keep and remove the others.
setAndDisplayNewPlayerHand() --> this will move through our hashmap and just keep on adding the cards the player has choosen to keep
checkToPlayNewGame() --> After a game check whether to continue the game or quit
checkAndDisplayIfPlayerWantsCheckoutTable() --> showPayoutTable() if the answer is yes
exitGame() --> System.exit(0);
Now, we come to the main part of this program. We start with showing the payoutTable and our above methods have made it easy to go with this section. Show Balance at the beginning, now we have to call our methods !
getPlayerBet(); --> get the bet
updateBalance(); --> reflect the bet in the balance
oneDeck.reset(); --> reset the deck
oneDeck.shuffle(); --> shuffle the deck
dealHand(); -->deal cards
System.out.println(playerHand.toString()); --> display the cards
getPlayerCardRetainingPositions(); --> get the positions the player want to keep
setAndDisplayNewPlayerHand(); --> New player hands
checkHands(); --> check for balance
showBalance --> show the balance
if(playerBalance == 0){ --> if balance is zero,
exitGame(); --> exir
}
else{
checkToPlayNewGame(); --> otherwise check if the player wants to play a new game
}
Now we move onto Decks Class ! Before moving on, I would recommend to add a few data members to this class, firstsuit =1, lastSuit=4, firstRank=1 and lastRank=13.
For the default constructor,
numberDecks = 1;
saveDecks = new ArrayList<>(); --> using array list for both the decks
playDecks = new ArrayList<>();
for(int suit = firstSuit; suit <= lastSuit; suit++){ --> adding a card
for(int rank = firstRank; rank <= lastRank; rank++){
Card newCard = new Card(suit, rank);
saveDecks.add(newCard); --> creating one deck of 52 cards
playDecks.add(newCard);} } --> copying them to playDecks
For parameterized constructor, add an extra loop to create n number of decks.
Shuffle method will just shuffle the playing decks --> Collections.shuffle(playDecks)
public List<Card> deal(int numberCards) throws PlayingCardException --> check if the cards are enough on the deck and then iterate through the playing cards, remove the used one and move on !
List<Card> dealtCards = new ArrayList<>(); --> data type
for(int i = numberCards-1; i >= 0; i--){ --> iterate through the number of cards
Card randomCard = playDecks.remove(i);
dealtCards.add(randomCard);
reset method will just reset by copying all the cards from the saved deck.
playDecks = saveDecks;
I guess that is all, for any further question feel free to comment below !
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.