Algorithm to avoid duplicate Cards in Card Game - java

I made a rookie mistake, and am trying to figure out a fix without recoding the entire program. Here's the scenario:
I am creating 6 cards from a 52 card deck. The cards have 2 fields: int rank and char suit. I am pulling a random rank and suit and creating a new and unnamed instance of each card. This is not accounting for duplicates.
So I am creating the 6 cards successfully, but I do not want the duplicates. This may be a newbish question, but we have all been there :) Thanks for your help!
public void displayCards(List<ImageView> disp) {
int cardNumber = 0;
for (ImageView c : disp) {
cardNumber++;
rank = rand(13) + 2;
int i = rand(4);
if (i == 0) {
suit = 's';
} else if (i == 1) {
suit = 'h';
} else if (i == 2) {
suit = 'd';
} else {
suit = 'c';
}
if (cardNumber == 1) {
dc1 = new Card(rank, suit);
} else if (cardNumber == 2) {
dc2 = new Card(rank, suit);
} else if (cardNumber == 3) {
dc3 = new Card(rank, suit);
} else if (cardNumber == 4) {
pc1 = new Card(rank, suit);
} else if (cardNumber == 5) {
pc2 = new Card(rank, suit);
} else {
pc3 = new Card(rank, suit);
}}

Option 1: Create a full deck (e.g., in a List) of 52 cards using two (nested) loops (all suits and all ranks). Shuffle (using Collections.shuffle()) the deck and take the six cards.
Option 2: Just create the number of cards you want (like you are attempting to do). Here, you will want to put each card into a Set<Card> until the set has the desired number of cards. Essentially, the duplicates will disappear in the set. For this to work, you need to implement equals() and hashcode() for the Card class.

Create a deck of all 52 cards and extract the cards from the deck. Also you should use enumerators to represent ranks and suits.
See my answer in What variables do I have to compare in this java code? for example code of cards and deck.

First, override equals() and hashCode() in your Card class if you haven't done it yet.
Second, add already created cards to a Set (which guarantees that it won't contain duplicates)
Modify your code for something like this:
public void displayCards(List<ImageView> disp) {
int cardNumber = 0;
Set<Card> myCards = new HashMap<Card>();
for (ImageView c : disp) {
cardNumber++;
Card newCard;
do {
rank = rand(13) + 2;
int i = rand(4);
if (i == 0) {
suit = 's';
} else if (i == 1) {
suit = 'h';
} else if (i == 2) {
suit = 'd';
} else {
suit = 'c';
}
newCard = new Card(rank, suit);
} while(myCards.contains(newCard));
myCards.add(newCard);
if (cardNumber == 1) {
dc1 = newCard;
} else if (cardNumber == 2) {
dc2 = newCard;
} else if (cardNumber == 3) {
dc3 = newCard;
} else if (cardNumber == 4) {
pc1 = newCard;
} else if (cardNumber == 5) {
pc2 = newCard;
} else {
pc3 = newCard;
}
}

Related

How can I make an effective mocking suite on objects who constructors take no arguments?

I have a card game I made a few years ago, and now I've learned about mocking with Mockito. So far, my card object looks like:
public Card(){
this.value = new CardValue(determineFace()); //assigns the output of a randomly chosen card to Card's this.value
//by plugging a call to determineFace() into a CardValue
this.suit = determineSuit(); //this.suit is assigned a suit at random
}
where determineFace() is:
public static String determineFace(){ //determines a face at random so that CardValue in this.value's init has a parameter
String f = null;
int rand = (int)(Math.random()*13);
if (rand == 0){
f = "2";
}
if (rand == 1){
f = "3";
}
if (rand == 2){
f = "4";
}
if(rand == 3){
f = "5";
}
if(rand == 4){
f = "6";
}
if(rand == 5){
f = "7";
}
if(rand == 6){
f = "8";
}
if(rand == 7){
f = "9";
}
if(rand == 8){
f = "10";
}
if (rand == 9){
f = "J";
}
if (rand == 10){
f = "Q";
}
if (rand == 11){
f = "K";
}
if(rand == 12){
f = "A";
}
return f;
}
suit is part of
public enum Suit{
CLUBS, DIAMONDS, HEARTS, SPADES
}
where a CardValue is a:
protected String face; //a CardValue's verbal name
protected int numeric; //a CardValue's numeric value
public CardValue(String faceVal){
face = faceVal; // set's a CV's face name passed into the constructor
numeric = findNumericVal(faceVal); //sets the numeric value equal to the output of the call to findNumericVal on the faceVal
}
However, I'm really confused of how to go about mocking CardValue to Mockito so I can test Card's methods. I also want to test CardValue's methods. I'm a little unsure of whether to use #InjectMocks bc it seems like its always used with objects that don't have no args parameters. In trying to make mocks and test them with JUnit and Mockito, I've gotten errors about having thenReturn() being tried with the wrong type in those parens, I've gotten values that have shown up as null in my asserts. How can I make effective mocks of my objects?
Welcome onboard of Stackoverflow!
This is a solution without mocking because I don't see a reasons to use mocking.
All what you need is to substitute the random function by custom one in the tests.
The Card class has a static field randomGenerator which will be overwritten in the tests. BTW, I simplified the determineFace() to one line and removed the explicit constructor just to have more compact code.
class Card {
static Supplier<Integer> randomGenerator = () -> (int) (Math.random() * 13);
static String[] supportedFs =
new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
final CardValue value = new CardValue(determineFace());
final Suite suit = determineSuit();
static String determineFace() {
return supportedFs[randomGenerator.get()];
}
static Suite determineSuit() {
// TODO: to be finished according to your logic.
return Suite.CLUBS;
}
}
This is an example of test class:
public class CardTest {
#Test
public void cardConstructionWhenRandomIsZero() {
// Given custom random generator which returns always 0.
Card.randomGenerator = () -> 0;
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("2", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}
#Test
public void cardConstructionWhenRandomIsOne() {
// Given custom random generator which returns always 1.
Card.randomGenerator = () -> 1;
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("3", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}
}
Sure things, you can use data providers to combine test cases for each possible random values.
One bad point of above solution is the real random generation will be not tested. For this case you can have a test with real random generation but match the actual value as part of supported values:
#Test
public void cardConstructionWithRealRandom() {
// When
Card actualCard = new Card();
// Then
Assert.assertThat(actualCard.value.face, Matchers.isIn(Card.supportedFs));
}
UPDATE: based on the comments.
If you still want to use Mockito you can emulate the behavior of the random generator by this way:
#Test
public void cardConstructionWhenRandomIsZero() {
// Given custom random generator which returns always 0.
Card.randomGenerator = Mockito.mock(Supplier.class);
Mockito.when(Card.randomGenerator.get()).thenReturn(0);
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("2", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}
UPDATE 2: based on the comments.
#Mock
Supplier<Integer> mockedRandomGenerator;
#Test
public void cardConstructionWhenRandomIsZero() {
// Given custom random generator which returns always 0.
Card.randomGenerator = mockedRandomGenerator;
Mockito.when(mockedRandomGenerator.get()).thenReturn(0);
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("2", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}

Cannot get card/deck object program to work

this is my first time posting on the forum and I'm not entirely sure if my question is valid, but I will try to be specific and follow the guideline. In following the guidelines, this is a question based around a class assignment. This assignment is to take code that creates a 'deck' object that represents a deck of cards and add several features. I am currently stuck in the process.
My issue lies within this code:
public class SilasAlmgrenS6L1CardCreate {
public static void main(String args[]) {
Deck d = new Deck();
d.shuffle();
Hand f = new Hand(d); //Returns error 'Hand cannot be resolved to a type'
}
public static class Deck {
Card[] cardArray = new Card[52];
Deck() { //constructor
int suits = 4;
int cardType = 13;
int cardCount = 0;
for (int i = 1; i <= suits; i++)
for (int j = 1; j <= cardType; j++) {
cardArray[cardCount] = new Card(i, j);
cardCount++;
} //End loop
} //End deck() constructor
////////////////////////////////////////////////////////
//My code starts here
public class Hand {
Hand(Deck a) {
Card[] Hand = {a.cardArray[0], a.cardArray[1], a.cardArray[2], a.cardArray[3], a.cardArray[4]};
Card[] playerHand = {Hand[0], Hand[1]};
System.out.println("You have " + playerHand[0] + " and " + playerHand[1] );
} //End hand constructor
} //End hand class
public void shuffle() {
//Runs loop for the length of the deck
for(int i = 0; i < cardArray.length; i++) {
int num = (int) (Math.random() * (51 - 0)) + 0; //Creates a random number between 0 and 51; used to shuffle
Card placeHolder = cardArray[i]; //Picks a place holder card from the deck
cardArray[i] = cardArray[num]; //Picks two random cards and make them equal
cardArray[num] = placeHolder; //Assigns one of the duplicate cards to the placeholder value
} //End for
} //End shuffle
//And ends here
/////////////////////////////////////////////////
public void print() {
for (int i = 0; i < cardArray.length; i++)
System.out.println(cardArray[i]);
} //End print loop
} //End print class
public static class Card {
String suit, name;
int points;
Card(int n1, int n2) {
suit = getSuit(n1);
name = getName(n2);
points = getPoints(name);
} //End card class
public String toString() {
return "The " + name + " of " + suit;
} //End toString
public String getName(int i) {
if (i == 1) return "Ace";
if (i == 2) return "Two";
if (i == 3) return "Three";
if (i == 4) return "Four";
if (i == 5) return "Five";
if (i == 6) return "Six";
if (i == 7) return "Seven";
if (i == 8) return "Eight";
if (i == 9) return "Nine";
if (i == 10) return "Ten";
if (i == 11) return "Jack";
if (i == 12) return "Queen";
if (i == 13) return "King";
return "error";
} //End getName String
public int getPoints(String n) {
if (n == "Jack" || n == "Queen" || n == "King" || n == "Ten")
return 10;
if (n == "Two")
return 2;
if (n == "Three")
return 3;
if (n == "Four")
return 4;
if (n == "Five")
return 5;
if (n == "Six")
return 6;
if (n == "Seven")
return 7;
if (n == "Eight")
return 8;
if (n == "Nine")
return 9;
if (n == "Ace")
return 11;
return -1;
} //End int getPoints
public String getSuit(int i) {
if (i == 1) return "Diamonds";
if (i == 2) return "Clubs";
if (i == 3) return "Spades";
if (i == 4) return "Hearts";
return "error";
} //End getSuit String
} //End Deck class
}
The majority of this program was already provided with the assignment, but we are to add several features. The first of these features was a shuffle method, which I was able to do. In the next feature we are to create a 'Hand' class that deals a hand of cards to the user and calculate how many points they have, as if it were a game of blackjack.
This is the exact wording of this step is:
'Add a Hand Class that contains an array of 5 Card references. Have the program Deal the Hand two cards and display them for the user. Tell the user how many points they have and ask them if they would like another card or not. Continue to allow the player to add cards until they reach 5 cards or the total is greater than 21.'
I have ran through several ways that I felt I could create this class, but none seem to be working. This current iteration is as close as I've gotten. I am currently stumped, however. My issues are; I don't know why I'm getting the type error when I try to use the Hand class and I have no idea how to implement the getPoints() method. There are several steps following the creation of the Hand class, but I am sure I can get through them if I can figure out how to make this class work. I'm on the brink of punching a hole in my wall, so any help with fixing this code would be absolutely appreciated.
The first problem is that your Hand class is a subclass of your static Deck class. This way you can not use it in your main method, because that is not the enclosing class.
EDIT
So, I went a little overboard here. Hope it makes sense to you.
First of all, we have your main class. I renamed it for the sake of not wanting to type that long name. I added your Handand Deck objects as variables, since neither the Hand belongs to the Deck or the other way around, but they both are part of the Main class, let's refer to it as the game.
You start by shuffling the deck. When you have the deck, you can get a random card. This is provided by the deck. (I will come to that method shortly).
As soon as you have a hand, you can show the user the amount of points they have and ask them if they would like an extra card (if numberOfPoints < 22 and numberOfCards < 5). If they do want an extra card, ask the deck for a random card and add it to the hand. Go on until any of the boundaries are met.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CardExample {
private Hand playHand;
private Deck playDeck;
private Scanner reader = new Scanner(System.in); // Reading from System.in
public static void main(String args[]) {
new CardExample().play();
}
public void play(){
playDeck = new Deck();
playDeck.shuffle();
Card firstCard = playDeck.getRandomCard();
Card secondCard = playDeck.getRandomCard();
List<Card> startCards = new ArrayList<>();
startCards.add(firstCard);
startCards.add(secondCard);
playHand = new Hand(startCards);
requestInput();
}
private void requestInput(){
System.out.println("You have " + playHand.getPoints() + " points");
System.out.println("New card? (Y/N)");
String input = reader.next();
if(input.equalsIgnoreCase("y")){
Card newCard = playDeck.getRandomCard();
playHand.addCard(newCard);
if(playHand.getNumberOfCards() < 5 && playHand.getPoints() < 22) {
requestInput();
}else if(playHand.getPoints() >= 22){
System.out.println("You have " + playHand.getPoints() + "points. You're dead, sorry.");
reader.close();
} else{
System.out.println("You have 5 cards, that's the max");
reader.close();
}
}else{
System.out.println("Your score is " + playHand.getPoints() + " points");
reader.close();
}
}
}
Deck class
public class Deck {
private Card[] cardArray = new Card[52];
private int currentIndex = 0;
public Deck() { //constructor
int suits = 4;
int cardType = 13;
int cardCount = 0;
for (int i = 1; i <= suits; i++)
for (int j = 1; j <= cardType; j++) {
cardArray[cardCount] = new Card(i, j);
cardCount++;
} //End loop
}
public void shuffle() {
//Runs loop for the length of the deck
for(int i = 0; i < cardArray.length; i++) {
int num = (int) (Math.random() * (51 - 0)) + 0; //Creates a random number between 0 and 51; used to shuffle
Card placeHolder = cardArray[i]; //Picks a place holder card from the deck
cardArray[i] = cardArray[num]; //Picks two random cards and make them equal
cardArray[num] = placeHolder; //Assigns one of the duplicate cards to the placeholder value
} //End for
} //End shuffle
public Card[] getCardArray() {
return cardArray;
}
public Card getRandomCard(){
Card nextCard = cardArray[currentIndex];
currentIndex += 1;
return nextCard;
}
//And ends here
/////////////////////////////////////////////////
public void print() {
for (int i = 0; i < cardArray.length; i++)
System.out.println(cardArray[i]);
} //End print loop
}
Hand class
addCard updates points so that whenever getting numberOfCards or points, right value is returned
import java.util.ArrayList;
import java.util.List;
public class Hand {
private int points = 0;
private int numberOfCards = 0;
private List<Card> hand = new ArrayList<>();
public Hand(List<Card> cards) {
hand.addAll(cards);
numberOfCards += cards.size();
for(Card card: cards){
points += card.points;
}
} //End hand constructor
public void addCard(Card card){
hand.add(card);
points += card.points;
numberOfCards += 1;
}
public int getNumberOfCards() {
return numberOfCards;
}
public int getPoints() {
return points;
}
}
Card class (unchanged, but seperate file)
public class Card {
String suit, name;
int points;
Card(int n1, int n2) {
suit = getSuit(n1);
name = getName(n2);
points = getPoints(name);
} //End card class
public String toString() {
return "The " + name + " of " + suit;
} //End toString
public String getName(int i) {
if (i == 1) return "Ace";
if (i == 2) return "Two";
if (i == 3) return "Three";
if (i == 4) return "Four";
if (i == 5) return "Five";
if (i == 6) return "Six";
if (i == 7) return "Seven";
if (i == 8) return "Eight";
if (i == 9) return "Nine";
if (i == 10) return "Ten";
if (i == 11) return "Jack";
if (i == 12) return "Queen";
if (i == 13) return "King";
return "error";
} //End getName String
public int getPoints(String n) {
if (n == "Jack" || n == "Queen" || n == "King" || n == "Ten")
return 10;
if (n == "Two")
return 2;
if (n == "Three")
return 3;
if (n == "Four")
return 4;
if (n == "Five")
return 5;
if (n == "Six")
return 6;
if (n == "Seven")
return 7;
if (n == "Eight")
return 8;
if (n == "Nine")
return 9;
if (n == "Ace")
return 11;
return -1;
} //End int getPoints
public String getSuit(int i) {
if (i == 1) return "Diamonds";
if (i == 2) return "Clubs";
if (i == 3) return "Spades";
if (i == 4) return "Hearts";
return "error";
} //End getSuit String
} //End Deck class

I don't understand how to pass variables to function in my code(Java)

I'm relatively new to programming so be patient with me. I can't figure out how to pass the variables p12c, p13c etc. to the method findWinner. I ran into this problem quite often, so if you could provide some help I will appreciate it. Also, any tips on how to simplify any code is welcome too. Thank you.
import java.util.*;
public class StarterPoker {
public static void main(String[] args)
{
do
{
System.out.print("Welcome to Starter Poker!\n\n" +
"To play, two players will be dealt\n"+
"five cards per hand and the hand with\n"+
"the highest cards will win. Then you\n"+
"will be prompted to continue or quit.\n");
dealHand();
findWinner();
}
while(playAgain()=='Y');
}
public static void dealHand()
{
int p12c=0, p13c=0, p14c=0, p15c=0, p16c=0, p17c=0, p18c=0, p19c=0, p1tc=0, p1jc=0, p1qc=0, p1kc=0, p1ac=0;
int p22c=0, p23c=0, p24c=0, p25c=0, p26c=0, p27c=0, p28c=0, p29c=0, p2tc=0, p2jc=0, p2qc=0, p2kc=0, p2ac=0;
int [][] deck = new int[13][4];
int [][] player1hand = new int[5][2];
int [][] player2hand = new int[5][2];
//the p1 = player1, then it has each card value, followed by c for count, for example: p12c = player1 2s count.
String[] suits = {"Spades","Diamonds","Hearts","Clubs"};
String[] cards = {"2","3","4","5","6","7","8","9","10","Jack","Queen","King","Ace"};
Random randGen = new Random();
do
{
String hand1 = "";
//dealing hand 1
for(int dex = 0; dex < player1hand.length; dex++)
{
boolean goodCard = false;
while(!goodCard)
{
int suit = randGen.nextInt(4);
int card = randGen.nextInt(13);
if( deck[card][suit] == 0)
{
goodCard = true;
deck[card][suit] = 1;
player1hand[dex][0] = suit;
player1hand[dex][1] = card;
hand1 += "\n "+cards[card]+" of "+suits[suit]+"";
if(card == 0) p12c=p12c+1;
if(card == 1) p13c=p13c+1;
if(card == 2) p14c=p14c+1;
if(card == 3) p15c=p15c+1;
if(card == 4) p16c=p16c+1;
if(card == 5) p17c=p17c+1;
if(card == 6) p18c=p18c+1;
if(card == 7) p19c=p19c+1;
if(card == 8) p1tc=p1tc+1;
if(card == 9) p1jc=p1jc+1;
if(card == 10) p1qc=p1qc+1;
if(card == 11) p1kc=p1kc+1;
if(card == 12) p1ac=p1ac+1;
}
}
}
String hand2 = "";
//dealing hand 1
for(int dex = 0; dex < player2hand.length; dex++)
{
boolean goodCard = false;
while(!goodCard)
{
int suit = randGen.nextInt(4);
int card = randGen.nextInt(13);
if( deck[card][suit] == 0)
{
goodCard = true;
deck[card][suit] = 1;
player2hand[dex][0] = suit;
player2hand[dex][1] = card;
hand2 += "\n "+cards[card]+" of "+suits[suit]+"";
if(card == 0) p22c=p22c+1;
if(card == 1) p23c=p23c+1;
if(card == 2) p24c=p24c+1;
if(card == 3) p25c=p25c+1;
if(card == 4) p26c=p26c+1;
if(card == 5) p27c=p27c+1;
if(card == 6) p28c=p28c+1;
if(card == 7) p29c=p29c+1;
if(card == 8) p2tc=p2tc+1;
if(card == 9) p2jc=p2jc+1;
if(card == 10) p2qc=p2qc+1;
if(card == 11) p2kc=p2kc+1;
if(card == 12) p2ac=p2ac+1;
}
}
}
System.out.print("\nDo you want to deal two hands?\nenter 'Y' to continue or anything else to quit: ");
Scanner input = new Scanner(System.in);
char cont = input.next().charAt(0);
if(cont != 'Y')
{
System.out.println("Program terminated!");
System.exit(0);
}
System.out.printf("Player 1's hand is %s\n", hand1);
System.out.printf("Player 2's hand is %s\n", hand2);
} while(true);
}
public static void findWinner()
{
int p1s = 0, p2s = 0;
int p1p = 0, p2p = 0;
int p1t = 0, p2t = 0;
int p1f = 0, p2f = 0;
if (p12c > 0)
{
if(p12c >1)
{
if(p12c > 2)
{
if(p12c > 3)
{
p1f = 1;
}
else
{
p1t = 1;
}
}
else
{
p1p = p1p+1;
}
}
else
{
p1s = p1s+1;
}
}
if (p13c > 0)
{
if(p13c >1)
{
if(p13c > 2)
{
if(p13c > 3)
{
p1f = 1;
}
else
{
p1t = 1;
}
}
else
{
p1p = p1p+1;
}
}
else
{
p1s = p1s+1;
}
}
System.out.printf("p1s = %d",p1s);
//System.out.printf("Player %d wins ", winner);
//System.out.print("because %d beats %d\n",winCard, loseCard);
}
public static char playAgain(){
System.out.println("Would you like to play again?");
Scanner input = new Scanner(System.in);
char cont = input.next().charAt(0);
return cont;
}
}
To pass variables, you first have to have the variables being passed into the parameter:
public static void findWinner(int a, int b) //Or how many ever variable you need
{
...
}
Then when you call that method, you need to pass in those variables:
int p12c = 1;
int p13c = 2;
findWinner(p12c, p13c);
On a side note, when you just want to increment the variable by one, you can do either of the following:
var x = 1;
x++; // x = 2
x += 1; // x = 3
Just put that variables that you need in to the brackets and remember that it is an local variables. In your method "findWinner" all that you need is hust wrote public static void findWinner(int p12c, int p13c) and all be Ok ;)

Uno Project: Making sure that a illegal plays return correctly?

I am writing a chunk of program to play Uno with other classes. My Uno project is almost finished, but I need to be sure that the part which checks to make sure that on moves after a Wild Card is played, I play either a legal card or return a -1. Here is my code:
import java.util.*;
public class AlexaL_UnoPlayer implements UnoPlayer
{
public int play(List<Card> hand, Card upCard, Color calledColor, GameState state)
{
int play = -1;
boolean haveWild = false;
boolean matchesWildCall = false;
int indexOfWild = 0;
//turn number of cards all players are holding into ints for later use
int[] array = state.getNumCardsInHandsOfUpcomingPlayers();
int playerNext = array[0];
int playerTwoNext = array[1];
int playerBefore = array[2];
Color upCardColor = upCard.getColor();
for(int i = 0; i < hand.size(); i++)
{
//see if I have any wilds
if(hand.get(i).getRank().equals(Rank.WILD) || hand.get(i).getRank().equals (Rank.WILD_D4))
{
haveWild = true;
indexOfWild = i;
}
//set upCard color to calledColor if wild or wild_d4 are played
if (upCard.getRank().equals(Rank.WILD) || upCard.getRank().equals(Rank.WILD_D4))
{
upCardColor = calledColor;
}
//always play a card matching rank of upCard, if possible, or play the first in hand which matches color
if(hand.get(i).getColor().equals(upCardColor))
{
if(hand.get(i).getNumber() == upCard.getNumber())
{
play = i;
}
}
//if cornered(no matching number or color), play a wild
else if(haveWild == true)
{
play = indexOfWild;
}
//hold reverse cards until person next after me has less cards than person before me
if(hand.get(i).getRank().equals(Rank.REVERSE) && playerNext < playerBefore)
{
play = i;
}
//play skips when person next to me has less cards than me
if((hand.get(i).getRank().equals(Rank.SKIP) || hand.get(i).getRank().equals(Rank.DRAW_TWO)) && playerNext < hand.size())
{
play = i;
}
}
return play;
}
public Color callColor(List<Card> hand)
{
//strategy: change the color to the one i'm holding the most of
Color changeTo = Color.GREEN;
int numBlues = 0;
int numGreens = 0;
int numReds = 0;
int numYellows = 0;
//find out how many of each color i'm holding
for(int i = 0; i < hand.size(); i++)
{
if(hand.get(i).getColor().equals(Color.BLUE))
{
numBlues++;
}
else if(hand.get(i).getColor().equals(Color.RED))
{
numReds++;
}
else if(hand.get(i).getColor().equals(Color.GREEN))
{
numGreens++;
}
else if(hand.get(i).getColor().equals(Color.YELLOW))
{
numYellows++;
}
}
//find out which i'm holding the most of and call that color
//if no majority, return my favorite color(green)
if(numBlues > numReds && numBlues > numGreens && numBlues > numYellows)
{
changeTo = Color.BLUE;
}
else if(numReds > numBlues && numReds > numGreens && numReds > numYellows)
{
changeTo = Color.RED;
}
else if(numGreens > numBlues && numGreens > numYellows && numGreens > numReds)
{
changeTo = Color.GREEN;
}
else if(numYellows > numBlues && numYellows > numGreens && numYellows > numReds)
{
changeTo = Color.YELLOW;
}
else
{
changeTo = Color.GREEN;
}
return changeTo;
}
}
For some reason, my output is telling me this:
You were given this hand:
0. G7
1. G5
2. G+2
and the up card was: W
and the called color was: YELLOW
and you (wrongly) returned 2.
Valid plays would have included: -1
Can anyone provide some insight on why I am getting this error and how to fix it? Much appreciated!
Based on just this code, it is hard to say what is wrong with your implementation.
Did you try step-by-step debugging of your play function?
Alternately, it would be beneficial to instrument your code with more trace statements to better figure out where the issue might be occurring.
For example:
Every where your play variable gets assigned a value, print its value to console with some context of where you are in code.
if(hand.get(i).getNumber() == upCard.getNumber())
{
play = i;
System.out.println("number match step: play = " + play ); // You can add such a line
}
This should give you an idea as to when play's value is getting mutated to 2 unexpectedly.
Just clutching at straws here, but what are the expected values of getColor and getNumber for wild cards.
In case you have them set to Green or 2 respectively, it might explain the output you are seeing because of the following fragment of code.
//always play a card matching rank of upCard, if possible, or play the first in hand which matches color
if(hand.get(i).getNumber() == upCard.getNumber())
{
play = i;
}
else if(hand.get(i).getColor() == upCardColor)
{
play = i;
}

How to create a hand class for BlackJack java [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Can someone please please help. I have created a card class and Deck class but I just dont know how to create the Hand class.
This is my Card class below.
package blackjack;
public class Card {
private int rank;
private int suit;
#Override
public String tostring() {
String result = "";
if (rank == 1) result = "Ace";
if (rank == 2) result = "Two";
if (rank == 3) result = "Three";
if (rank == 4) result = "Four";
if (rank == 5) result = "Five";
if (rank == 6) result = "Six";
if (rank == 7) result = "Seven";
if (rank == 8) result = "Eight";
if (rank == 9) result = "Nine";
if (rank == 10) result = "Ten";
if (rank == 11) result = "Jack";
if (rank == 12) result = "Queen";
if (rank == 13) result = "King";
if (suit == 1) result = result + " of Clubs ";
if (suit == 2) result = result + " of Diamonds ";
if (suit == 3) result = result + " of Hearts ";
if (suit == 4) result = result + " of Spades ";
return result;
}
public Card(int rank, int suit) {
this.rank = rank;
this.suit = suit;
}
}
This is my Deck Class
package blackjack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Deck {
private Random shuffles = new Random();
public ArrayList<Card> Deck = new ArrayList<Card>();
Random rand = new Random();
// private int numberOfCards = 52;
public Deck() {
for (int ranks = 1; ranks <= 13; ranks++) {
for (int suits =1 ; suits <= 4; suits++) {
Deck.add(new Card(ranks, suits));
//System.out.println(Deck.get(ranks) + "" +Deck.get(suits));
}
}
shuffle();
for (int i = 1; i < Deck.size(); i++) {
//int cardPosition2 = shuffles.nextInt(52);
//shuffle.nextInt(Deck.get(i);
System.out.println(Deck.get(i));
//System.out.println(cardPosition2);
//i++;
}
}
public void shuffle() {
Collections.shuffle(Deck);
}
public Card DrawCard() {
int cardPosition = shuffles.nextInt(Deck.size());
return Deck.remove(cardPosition);
}
public int TotalCardsLeft() {
return Deck.size();
}
public Card dealCard() {
// Deals one card from the deck and returns it.
if (Deck.size() == 52) {
shuffle();
}
Card temp;
temp = Deck.get(0);
Deck.remove(0);
return temp;
}
public Card getCard(int i) {
return Deck.get(i);
}
public Card remove(int i) {
Card remo = Deck.get(i);
Deck.remove(i);
return remo;
}
}
If you can help me with my Hand call I would really appreciate it.
Create Class, which will contain for example ArrayList hand.
public class Hand {
private ArrayList<Card> hand
.
.
Then make methods to add(draw) Card :
public void addCard(Card c){
this.hand.add(c);
}
You will also need method to check whether card of specific type is present:
public boolean checkPresence(int rank){
for(int i=0;i<hand.size();i++){
//note you will need to implement getters to the Card class first
if (hand.get(i).getRank==rank)
return true;
}
return false;
}
Similarly for suit.
Of course you will most probably need other methods, but I am sure you can figure them out yourself.

Categories