Question
Now, you will create an Artificial Intelligence(AI) poker player. Using your best poker strategy, implement the wager() and discard() methods in Player.java. At the very
Now, you will create an Artificial Intelligence(AI) poker player. Using your best poker strategy, implement the wager() and discard() methods in Player.java. At the very least (for full credit), your implementation MUST return valid values for these two methods. Put into other words, in this one, remove all prompts and IO library calls from the above mentioned methods. Then, using some strategy/algorithm, return a valid wager from wager() and a valid set of cards to discard in discard(). You can use the driver(poker.java) as given.
//
//
//
Player.java:
//
//
//
public class Player{
//declare your fields here double balance; Hand hand; //initialize your fields in the constructor public Player(double balance){ this.balance = balance; this.hand = new Hand(); } public void deal(Card c){ hand.addCard(c); } //Returns an array of Cards that the Player wishes to discard. //The game engine will call deal() on this player for each card //that exists in the return value. Instructions: Print the hand to //the terminal using System.out.println and ask the user which cards //they would like to discard. The user will first the number of cards they //wish to discard, followed by the indices, one at a time, of //the card(s) they would like to discard, //Return an array with the appropriate Card objects //that have been discarded, and remove the Card objects from this //player's hand. Use IO.readInt() for all inputs. In cases of error //re-ask the user for input. // // Example call to discard(): // // This is your hand: // 0: Ace of Hearts // 1: 2 of Diamonds // 2: 5 of Hearts // 3: Jack of Spades // 4: Ace of Clubs // How many cards would you like to discard? // 2 // 1 // 2 // // The resultant array will contain the 2 of Diamonds and the 5 of hearts in that order // This player's hand will now only have 3 cards public Card[] discard(){ int numOfCard = 0; int index = 0; System.out.println("This is your hand:"); hand.printHand(); System.out.println("How many cards would you like to discard?"); numOfCard = IO.readInt(); Card[] discard = new Card[numOfCard]; for(int i = 0;i System.out.println("enter the card index"); index = IO.readInt(); while(hand.getCard(index) == null) { System.out.println("Error, enter again"); index = IO.readInt(); } discard[i] = hand.getCard(index); hand.removeCard(index); } return discard; }
//Returns the amount that this player would like to wager, returns //-1.0 to fold hand. Any non zero wager should immediately be deducted //from this player's balance. This player's balance can never be below // 0 at any time. This player's wager must be >= to the parameter min // MS2 Instructions: Show the user the minimum bet via the terminal //(System.out.println), and ask the user for their wager. Use //IO.readDouble() for input. In cases of error re-ask the user for //input. // // Example call to wager() // // How much do you want to wager? // 200 // // This will result in this player's balance reduced by 200 public double wager(double min){ System.out.println("How much do you want to wager?"); double wager = IO.readDouble(); if(balance < min) { System.out.println("You have to fold hand"); return -1; } while(wager > balance || wager < min) { System.out.println("Error,enter again"); wager = IO.readDouble(); } this.balance = balance - wager; return wager; }
//Returns this player's hand public Hand showHand(){ return this.hand; }
//Returns this player's current balance public double getBalance(){ return this.balance; }
//Increase player's balance by the amount specified in the parameter, //then reset player's hand in preparation for next round. Amount will //be 0 if player has lost hand public void winnings(double amount){ this.balance += amount; this.hand.clear(); }
}
//
//
//
Diver:
//
//
//
/* * Instructions: Place this file into the same directory as IO.java, Hand.java, Card.java, and Player.java * Compile via: javac Poker.java * After compiling, run via: java Poker */
// We import Random for shuffling cards in between hands. import java.util.Random;
public class Poker{
private static Random rand = new Random();
public static void main(String[] args){ // We create two players, which each have a balance of $100.50 Player player1 = new Player(100.50); Player player2 = new Player(100.50);
gameLoop(player1, player2);
}
// Runs through several loops of gameplay until the user tells us to stop. public static void gameLoop(Player p1, Player p2){ Card[] deck = getDeck(); double player1Wager = 0, player2Wager = 0; do{ displayBalances(p1, p2); System.out.println();
// Shuffle the deck and deal 5 cards to each player. shuffle(deck); dealFullHand(deck, p1); dealFullHand(deck, p2);
// Now we get how much player one wants to bet. // IF player one folds, then nothing happens and we try to play another hand. System.out.println("======================================="); System.out.println("Player 1, it is your turn."); player1Wager = getWager(p1, 0);
if(player1Wager == -1){ System.out.println("Play another hand? [y/n]"); p2.winnings(0); p1.winnings(0); continue; } System.out.println("======================================="); System.out.println();
// Now we ask player two to make a bet of equivalent value. // IF they fold, we have to reimburse player 1 with the money we took from them for their bet. System.out.println("======================================="); System.out.println("Player 2, it is your turn."); player2Wager = getWager(p2, player1Wager);
if(player2Wager == -1){ System.out.println("Player 2 folded"); System.out.println("Play another hand? [y/n]"); p2.winnings(0); p1.winnings(player1Wager); continue; } System.out.println("======================================="); System.out.println();
// Now, we ask each player if they would like to discard any cards, and redeal the number of cards that they do discard. askdiscardCardsAndDealNew(p1, p2, deck);
// After redealing, we are now able to display the hands and determine who won. System.out.println(" Here are your final hands:");
System.out.println("======================================="); System.out.println("Player 1:"); p1.showHand().printHand(); System.out.println("======================================="); System.out.println();
System.out.println("======================================="); System.out.println("Player 2:"); p2.showHand().printHand(); System.out.println("======================================="); System.out.println();
int result = p1.showHand().compareTo(p2.showHand()); if(result == 0){ System.out.println("A tie!"); p1.winnings(player1Wager); p2.winnings(player2Wager); }else if(result < 0){ System.out.println("Player 2 wins!"); p1.winnings(0); p2.winnings(player1Wager + player2Wager); }else if(result > 0){ System.out.println("Player 1 wins!"); p1.winnings(player1Wager + player2Wager); p2.winnings(0); } System.out.println(" ");
System.out.println("Play another hand? [y/n]"); }while((IO.readString()).toLowerCase().equals("y")); }
// Prints out the balances of each player at the current time. public static void displayBalances(Player p1, Player p2){ System.out.println("======================================="); System.out.println("Player 1 balance: " + p1.getBalance()); System.out.println("Player 2 balance: " + p2.getBalance()); System.out.println("======================================="); }
// Asks each player what cards they want to discard, then discards them, and then deals new ones. public static void askdiscardCardsAndDealNew(Player p1, Player p2, Card[] cards){ System.out.println("======================================="); System.out.println("Player 1, it is your turn."); discardCardsAndDealNew(cards, p1); System.out.println("======================================="); System.out.println();
System.out.println("======================================="); System.out.println("Player 2, it is your turn."); discardCardsAndDealNew(cards, p2); System.out.println("======================================="); System.out.println();
}
// Gets the cards from the player that they want to get rid of and actually does the getting rid of them. public static void discardCardsAndDealNew(Card[] deck, Player player){ Card[] cards = player.discard(); for(int i = 0; i < cards.length; i ++){ player.deal(getNextCard(deck)); } }
// Shows the user their hand and then asks them for their wager. // Will return the amount that they wagered so that we can keep track of it for winnings. public static double getWager(Player player, double minimum){ player.showHand().printHand(); return player.wager(minimum); }
// Deals enough cards to the player such that they have a full hand. public static void dealFullHand(Card[] deck, Player player){ int numCards = 5 - player.showHand().getCardCount(); for(int i = 0; i < numCards; i ++){ player.deal(getNextCard(deck)); } }
// A placeholder so that we can keep returning the next card that needs to be dealt, without modifying the array for every withdraw. private static int cardPos = 0;
// Returns the next card to deal to the player. public static Card getNextCard(Card[] cards){ return cards[cardPos ++]; }
// Shuffles the cards by going through each one and moving it to some random position in the deck. // Also resets our position, such that we pull from the 0th index on the next getNextCard call. public static void shuffle(Card[] cards){ cardPos = 0; for(int i = 0; i < 52; i ++){ int newPos = rand.nextInt(52); Card temp = cards[i]; cards[i] = cards[newPos]; cards[newPos] = temp; } }
// Returns the standard 52 card deck of AS,2S,...,KS,AH,....,KH,.... public static Card[] getDeck(){ Card[] cards = new Card[52]; int pos = 0;
for(int i = 1; i <= 13; i ++){ for(int j = 0; j <= 3; j ++){ Card c = new Card(i, j); cards[pos ++] = c; } }
return cards; }
}
//
//
//
Hand.java
//
//
//
/** * An object of type Hand represents a hand of cards. The * cards belong to the class Card. A hand is empty when it * is created, and any number of cards can be added to it. */
public class Hand {
private Card[] hand; // The cards in the hand. private int count;
/** * Create a hand that is initially empty. */ public Hand() { hand = new Card[5]; count = 0; }
/** * Remove all cards from the hand, leaving it empty. */ public void clear() { for(int i=0 ; i /** * Add a card to the hand. It is added at the end of the current hand. * @param c the non-null card to be added. * @throws NullPointerException if the parameter c is null. */ public void addCard(Card c) { for(int i=0 ; i } /** * Remove a card from the hand, if present. * @param c the card to be removed. If c is null or if the card is not in * the hand, then nothing is done. */ public void removeCard(Card c) { for(int i=0 ; i } /** * Remove the card in a specified position from the hand. * @param position the position of the card that is to be removed, where * positions are starting from zero. * @throws IllegalArgumentException if the position does not exist in * the hand, that is if the position is less than 0 or greater than * or equal to the number of cards in the hand. */ public void removeCard(int position) { if (position < 0 || position >= hand.length) throw new IllegalArgumentException("Position does not exist in hand: " + position); hand[position] = null; count --; } /** * Returns the number of cards in the hand. */ public int getCardCount() { return count; } /** * Gets the card in a specified position in the hand. (Note that this card * is not removed from the hand!) * @param position the position of the card that is to be returned * @throws IllegalArgumentException if position does not exist in the hand */ public Card getCard(int position) { if (position < 0 || position >= hand.length) throw new IllegalArgumentException("Position does not exist in hand: " + position); return hand[position]; } /** * Sorts the cards in the hand so that cards of the same suit are * grouped together, and within a suit the cards are sorted by value. * Note that aces are considered to have the lowest value, 1. */ public void sortBySuit() { int size = count; int nonnull = 0; int index = 0; Card[] newHand = new Card[5]; while (size > 0) { if (hand[nonnull] == null) { nonnull = nonnull+1; continue;} int pos = nonnull; // Position of minimal card. Card c = hand[nonnull]; // Minimal card. for (int i = nonnull+1; i < hand.length; i++) { Card c1 = hand[i]; if (c1 != null){ if ( c1.getSuit() < c.getSuit() || (c1.getSuit() == c.getSuit() && c1.getValue() < c.getValue()) ) { pos = i; c = c1; } } } hand[pos] = null; size = size - 1; newHand[index++] = c; nonnull = 0; } hand = newHand; } /** * Sorts the cards in the hand so that cards of the same value are * grouped together. Cards with the same value are sorted by suit. * Note that aces are considered to have the lowest value, 1. */ public void sortByValue() { int size = count; int nonnull = 0; int index = 0; Card[] newHand = new Card[5]; while (size > 0) { if (hand[nonnull] == null) { nonnull = nonnull+1; continue;} int pos = nonnull; // Position of minimal card. Card c = hand[nonnull]; // Minimal card. for (int i = nonnull+1; i < hand.length; i++) { Card c1 = hand[i]; if (c1 != null){ if ( c1.getValue() < c.getValue() || (c1.getValue() == c.getValue() && c1.getSuit() < c.getSuit()) ) { pos = i; c = c1; } } } hand[pos] = null; size = size - 1; newHand[index++] = c; nonnull = 0; } hand = newHand; } public void printHand(){ for(int i=0; i< hand.length; i++){ if (hand[i] != null){ System.out.println(hand[i]); } } System.out.println(); } public int numPairs() { sortByValue(); int num = 0; for(int i = 0; i < hand.length -1; i++) { if(hand[i].getValue() == hand[i+1].getValue()) { num++; i++; } } return num; } public boolean hasTriplet() { this.sortByValue(); if(hand[0].getValue() == hand[1].getValue() && hand[1].getValue() == hand[2].getValue() || hand[1].getValue() == hand[2].getValue() && hand[2].getValue() == hand[3].getValue() || hand[2].getValue() == hand[3].getValue() && hand[3].getValue() == hand[4].getValue()) { return true; } else { return false; } } //Returns true if this hand has all cards that are of the same suit public boolean hasFlush() { this.sortBySuit(); if(hand[0].getSuit() == hand[1].getSuit() && hand[1].getSuit() == hand[2].getSuit() && hand[2].getSuit() == hand[3].getSuit() && hand[3].getSuit() == hand[4].getSuit()) { return true; } else { return false; } } //Returns true if this hand has 5 consecutive cards of any suit public boolean hasStraight() { this.sortByValue(); if(hand[0].getValue() != 1) { for(int i = 0; i < hand.length - 1; i++) { if(hand[i].getValue() != (hand[i + 1].getValue() - 1)) { return false; } } return true; } else { if(hand[4].getValue() == 13) { if(hand[1].getValue() == 2) { if(hand[2].getValue() == 3) { if(hand[3].getValue() == 4 || hand[3].getValue() == 12) { return true; } else { return false; } } else if(hand[2].getValue() == 11) { if(hand[3].getValue() == 12) { return true; } else { return false; } } else { return false; } } else if(hand[1].getValue() == 10) { if(hand[2].getValue() == 11 && hand[3].getValue() == 12) { return true; } else { return false; } } else { return false; } } for(int c = 0; c < hand.length-1 ; c++) { if(hand[c].getValue() != (hand[c+1].getValue()-1)) { return false; } } return true; } } //Returns true if this hand has a triplet and a pair of different //values public boolean hasFullHouse() { this.sortByValue(); if(hand[0].getValue() == hand[1].getValue() && hand[2].getValue() == hand[3].getValue() && hand[3].getValue() == hand[4].getValue()) { return true; } else if(hand[0].getValue() == hand[1].getValue() && hand[1].getValue() == hand[2].getValue() && hand[3].getValue() == hand[4].getValue()) { return true; } else { return false; } } //Returns true if this hand has 4 cards that are of the same value public boolean hasFourOfAKind() { this.sortByValue(); if(hand[0].getValue() == hand[1].getValue() && hand[1].getValue() == hand[2].getValue() && hand[2].getValue() == hand[3].getValue() || hand[1].getValue() == hand[2].getValue() && hand[2].getValue() == hand[3].getValue() && hand[3].getValue() == hand[4].getValue()) { return true; } else { return false; } } //Returns the card with the highest value in the hand. When there is more than one highest value card, you may return any one of them public Card highestValue() { sortByValue(); if(hand[0].getValue() == 1) { return hand[0]; } return hand[hand.length-1]; } public Card highestDuplicate() { sortByValue(); if(numPairs() == 0) { return null; } if(hasTriplet() == true && numPairs() == 0 ) { return hand[2]; } if(hasFullHouse() == true) { // return hand[4]; } if(hasFourOfAKind() == true) { return hand[2]; // } if(hand[0].getValue() == 1 && hand[1].getValue() == 1) { return hand[0]; } for(int i = hand.length - 1; i > 0; i--) { if(hand[i].getValue() == hand[i-1].getValue()) { return hand[i]; } }// return null; } public int compareTo(Hand h){ this.sortByValue(); h.sortByValue(); int z = 0; if(this.hasStraight() == true && hasFlush() == true) { z = 1; }// else if(this.hasFourOfAKind() == true) { z = 2; }// else if(this.hasFullHouse() == true) { z = 3; }// else if(this.hasFlush() == true) { z = 4; } else if(this.hasStraight() == true) { z = 5; }// else if(this.hasTriplet() == true) { z = 6; } else if(this.numPairs() == 2) { z = 7; } else if(this.numPairs() == 1) { z = 8; } else { z = 9; }// int level = 0; if(h.hasStraight() == true && h.hasFlush() == true) { level = 1; }// else if(h.hasFourOfAKind() == true) { level = 2; } else if(h.hasFullHouse() == true) { level = 3; }// else if(h.hasFlush() == true) { level = 4; }// else if(h.hasStraight() == true) { level = 5; } // else if(h.hasTriplet() == true) { level = 6; }// else if(h.numPairs() == 2) { level = 7; }// else if(h.numPairs() == 1) { level = 8; } else { level = 9; }// if(z > level) { return -1; }// if(z < level) { return 1; } else { if(level == 1 || level == 5) { if(h.hand[0].getValue() == 1 && h.hand[4].getValue()== 13 && this.hand[0].getValue() == 1 && this.hand[4].getValue() == 13 ) { return 0; }// if(h.hand[0].getValue() == 1 && h.hand[4].getValue()== 13 && this.hand[0].getValue() != 1) { return -1; }// if(this.hand[0].getValue() == 1 && this.hand[4].getValue()== 13 && h.hand[0].getValue() != 1) { return 1; }// if(h.hand[0].getValue() == this.hand[0].getValue()) { return 0; }// else if(h.hand[0].getSuit() > this.hand[0].getSuit()){ return 1; }// else { return -1; }// } if(level == 2 || level == 3 || level == 6) { if(h.hand[2].getValue() < this.hand[2].getValue()){ return 1; } else { return -1; } }// if(level == 4 || level == 9) { boolean notIdentical = true; if(h.hand[0].getValue() == 1 && this.hand[0].getValue() != 1) { return -1; } if(this.hand[0].getValue() == 1 && h.hand[0].getValue() != 1) { return 1; } for(int i = h.hand.length - 1; i >= 0; i--) { if(h.hand[i].getValue() == this.hand[i].getValue()) { notIdentical = false; } if(h.hand[i].getValue() > this.hand[i].getValue()) { return -1; } else { return 1; } // } if(notIdentical == false) { return 0; } } if(level == 7 || level == 8) { if(h.highestDuplicate().getValue() > this.highestDuplicate().getValue()) { return -1; } else if(h.highestDuplicate().getValue() == this.highestDuplicate().getValue()) { return 0; } else { return 1; } } } return -1; } } // // // Card.java // // // /** * An object of type Card represents a playing card from a * standard Poker deck, including Jokers. The card has a suit, which * can be spades, hearts, diamonds, clubs, or joker. A spade, heart, * diamond, or club has one of the 13 values: ace, 2, 3, 4, 5, 6, 7, * 8, 9, 10, jack, queen, or king. Note that "ace" is considered to be * the smallest value. A joker can also have an associated value; * this value can be anything and can be used to keep track of several * different jokers. */ public class Card { public final static int SPADES = 0; // Codes for the 4 suits, plus Joker. public final static int HEARTS = 1; public final static int DIAMONDS = 2; public final static int CLUBS = 3; public final static int JOKER = 4; public final static int ACE = 1; // Codes for the non-numeric cards. public final static int JACK = 11; // Cards 2 through 10 have their public final static int QUEEN = 12; // numerical values for their codes. public final static int KING = 13; /** * This card's suit, one of the constants SPADES, HEARTS, DIAMONDS, * CLUBS, or JOKER. The suit cannot be changed after the card is * constructed. */ private final int suit; /** * The card's value. For a normal card, this is one of the values * 1 through 13, with 1 representing ACE. For a JOKER, the value * can be anything. The value cannot be changed after the card * is constructed. */ private final int value; /** * Creates a Joker, with 1 as the associated value. (Note that * "new Card()" is equivalent to "new Card(1,Card.JOKER)".) */ public Card() { suit = JOKER; value = 1; } /** * Creates a card with a specified suit and value. * @param theValue the value of the new card. For a regular card (non-joker), * the value must be in the range 1 through 13, with 1 representing an Ace. * You can use the constants Card.ACE, Card.JACK, Card.QUEEN, and Card.KING. * For a Joker, the value can be anything. * @param theSuit the suit of the new card. This must be one of the values * Card.SPADES, Card.HEARTS, Card.DIAMONDS, Card.CLUBS, or Card.JOKER. * @throws IllegalArgumentException if the parameter values are not in the * permissible ranges */ public Card(int theValue, int theSuit) { if (theSuit != SPADES && theSuit != HEARTS && theSuit != DIAMONDS && theSuit != CLUBS && theSuit != JOKER) throw new IllegalArgumentException("Illegal playing card suit"); if (theSuit != JOKER && (theValue < 1 || theValue > 13)) throw new IllegalArgumentException("Illegal playing card value"); value = theValue; suit = theSuit; } /** * Returns the suit of this card. * @returns the suit, which is one of the constants Card.SPADES, * Card.HEARTS, Card.DIAMONDS, Card.CLUBS, or Card.JOKER */ public int getSuit() { return suit; } /** * Returns the value of this card. * @return the value, which is one of the numbers 1 through 13, inclusive for * a regular card, and which can be any value for a Joker. */ public int getValue() { return value; } /** * Returns a String representation of the card's suit. * @return one of the strings "Spades", "Hearts", "Diamonds", "Clubs" * or "Joker". */ public String getSuitAsString() { switch ( suit ) { case SPADES: return "Spades"; case HEARTS: return "Hearts"; case DIAMONDS: return "Diamonds"; case CLUBS: return "Clubs"; default: return "Joker"; } } /** * Returns a String representation of the card's value. * @return for a regular card, one of the strings "Ace", "2", * "3", ..., "10", "Jack", "Queen", or "King". For a Joker, the * string is always numerical. */ public String getValueAsString() { if (suit == JOKER) return "" + value; else { switch ( value ) { case 1: return "Ace"; case 2: return "2"; case 3: return "3"; case 4: return "4"; case 5: return "5"; case 6: return "6"; case 7: return "7"; case 8: return "8"; case 9: return "9"; case 10: return "10"; case 11: return "Jack"; case 12: return "Queen"; default: return "King"; } } } /** * Returns a string representation of this card, including both * its suit and its value (except that for a Joker with value 1, * the return value is just "Joker"). Sample return values * are: "Queen of Hearts", "10 of Diamonds", "Ace of Spades", * "Joker", "Joker #2" */ public String toString() { if (suit == JOKER) { if (value == 1) return "Joker"; else return "Joker #" + value; } else return getValueAsString() + " of " + getSuitAsString(); } public boolean equals(Object o){ if ( ! (o instanceof Card)) return false; Card c = (Card)o; if (c.suit == this.suit && c.value == this.value) return true; return false; } } // end class Card
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started