How do I set variable to int and String? - java

I am making a card class, and need to set the face (The number on the card) to the numbers 1-13. However, on a card, a 1 is an ace, a 13 is a king, a 12 is a Queen, and an 11 is a jack. How do I also set the number 1, and 11-13 to a string such as ace, king, queen, or jack? Any help is appreciated!
public void setFace(int f)
{
if(f >= 1 && f <= 13)
face = f;
else
face = 1;
}
public int getFace()
{
return face;
}

I'm assuming you have field like
public int face;
I guess it will work if it's what you meant
public String getFace() {
switch (this.face) {
case 1:
face = "Ace";
break;
case 11:
face = "Jack";
break;
case 12:
face = "Queen";
break;
case 13:
face = "King";
break;
default:
return Integer.toString(face);
break;
}
}

What do you think about this code..?
public void setFace(int f) {
switch (f) {
case 1:
face = 1;
break;
case 11:
face = 1;
break;
case 12:
face = 1;
break;
case 13:
face = 1;
break;
default:
face = f;
break;
}
}

How about using enums?
public enum CardValue {
ACE(1), TWO(2), THREE(3), ..... KING(13);
private int value;
private CardValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public CardValue getValueFor(int x) {
// iterate through CardValue enum and return correct instance of the enum
}
}

Related

Java - Guava Table Not Returning Value

I am using Google's Guava library for the Table class.
I have the table define like this:
private Table<ThreePartKey, DateTime, UnitDay> table = TreeBasedTable.create();
ThreePartKey is an object that contains 3 string values as fields. It is being used as the Row index in the table. DateTime is a Joda Time object being used as the Column index of the table. UnitDay is a plain old java object that is the Value of the table.
I have populated the table, and later in my code I want to access a specific cell of the table. I use the following code:
UnitDay tempUnitDay = table.get(threePartKey, dateTime);
But tempUnitDay is null. I've run this in Eclipse debug mode, and neither threePartKey nor dateTime is null. There should not be a null value in the table.
Does anyone have any idea what I am doing wrong?
EDIT:
#TR1 I thought of that, but it should have a value for that column/row. I created a list of ThreePartKeys and a list of DateTimes, then created a table from those lists with an empty UnitDay as the value. Then I go back an iterate through the same values again to populate the UnitDay values.
Here is the code for my ThreePartKey class:
public class ThreePartKey implements Comparable<ThreePartKey> {
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((facilityCode == null) ? 0 : facilityCode.hashCode());
result = prime
* result
+ ((facilityGroupCode == null) ? 0 : facilityGroupCode
.hashCode());
result = prime * result
+ ((unitCode == null) ? 0 : unitCode.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ThreePartKey other = (ThreePartKey) obj;
if (facilityCode == null) {
if (other.facilityCode != null)
return false;
} else if (!facilityCode.equals(other.facilityCode))
return false;
if (facilityGroupCode == null) {
if (other.facilityGroupCode != null)
return false;
} else if (!facilityGroupCode.equals(other.facilityGroupCode))
return false;
if (unitCode == null) {
if (other.unitCode != null)
return false;
} else if (!unitCode.equals(other.unitCode))
return false;
return true;
}
private String facilityGroupCode;
private String facilityCode;
private String unitCode;
public void setFacilityGroupCode (String facilityGroupCode) {
this.facilityGroupCode = facilityGroupCode;
}
public void setFacilityCode (String facilityCode) {
this.facilityCode = facilityCode;
}
public void setUnitCode (String unitCode) {
this.unitCode = unitCode;
}
public String getFacilityGroupCode () {
return facilityGroupCode;
}
public String getFacilityCode () {
return facilityCode;
}
public String getUnitCode () {
return unitCode;
}
#Override
public int compareTo(ThreePartKey o) {
return (100*(unitCode.compareTo(o.unitCode))) +
(10*(facilityCode.compareTo(o.unitCode))) +
(facilityGroupCode.compareTo(o.facilityGroupCode));
}
}
And here is my code that creates the table:
public void setUpTable () {
for (DateTime day : uniqueDays) {
for (ThreePartKey unit : trueUniqueUnits) {
UnitDay unitDay = new UnitDay();
String unitCode = unit.getUnitCode();
unitDay.setDay(day);
unitDay.setUnitCode(unit.getUnitCode());
unitDay.setFacilityCode(unit.getFacilityCode());
unitDay.setFacilityGroupCode(unit.getFacilityGroupCode());
table.put(unit, day, unitDay);
}
}
}
public void populateTable () { //FIX THIS TO INCLUDE ThreePartKey
for (CensusHour hour : allHours) {
DateTime minHour = hour.getDateTaken().withTimeAtStartOfDay();
DateTime day = hour.getDateTaken().withTimeAtStartOfDay();
String unit = hour.getUnitCode();
ThreePartKey key = new ThreePartKey();
key.setFacilityCode(hour.getFacilityCode());
key.setFacilityGroupCode(hour.getFacilityGroupCode());
key.setUnitCode(hour.getUnitCode());
UnitDay tempUnitDay = table.get(key, day);
tempUnitDay.setFacilityId(hour.getFacilityId());
tempUnitDay.setFacilityName(hour.getFacilityName());
tempUnitDay.setUnitId(hour.getUnitId());
tempUnitDay.setUnitName(hour.getUnitName());
tempUnitDay.setPortalCensusFileId(hour.getPortalCensusFileId());
tempUnitDay.setDay(minHour);
tempUnitDay.setFacilityCode(hour.getFacilityCode());
tempUnitDay.setFacilityGroupCode(hour.getFacilityGroupCode());
tempUnitDay.setFacilityGroupName(hour.getFacilityGroupName());
int objectHour = hour.getHourOfDay();
double occupancy = hour.getOccupancy();
switch (objectHour) {
case 0: tempUnitDay.setCensusHour0(occupancy);
break;
case 1: tempUnitDay.setCensusHour1(occupancy);
break;
case 2: tempUnitDay.setCensusHour2(occupancy);
break;
case 3: tempUnitDay.setCensusHour3(occupancy);
break;
case 4: tempUnitDay.setCensusHour4(occupancy);
break;
case 5: tempUnitDay.setCensusHour5(occupancy);
break;
case 6: tempUnitDay.setCensusHour6(occupancy);
break;
case 7: tempUnitDay.setCensusHour7(occupancy);
break;
case 8: tempUnitDay.setCensusHour8(occupancy);
break;
case 9: tempUnitDay.setCensusHour9(occupancy);
break;
case 10: tempUnitDay.setCensusHour10(occupancy);
break;
case 11: tempUnitDay.setCensusHour11(occupancy);
break;
case 12: tempUnitDay.setCensusHour12(occupancy);
break;
case 13: tempUnitDay.setCensusHour13(occupancy);
break;
case 14: tempUnitDay.setCensusHour14(occupancy);
break;
case 15: tempUnitDay.setCensusHour15(occupancy);
break;
case 16: tempUnitDay.setCensusHour16(occupancy);
break;
case 17: tempUnitDay.setCensusHour17(occupancy);
break;
case 18: tempUnitDay.setCensusHour18(occupancy);
break;
case 19: tempUnitDay.setCensusHour19(occupancy);
break;
case 20: tempUnitDay.setCensusHour20(occupancy);
break;
case 21: tempUnitDay.setCensusHour21(occupancy);
break;
case 22: tempUnitDay.setCensusHour22(occupancy);
break;
case 23: tempUnitDay.setCensusHour23(occupancy);
break;
}
table.put(key, day, tempUnitDay);
}
}

DeckOfCards and HighLow Class incompatible types

I get an incompatible types error when running my code. It is when "playerGuess = d1.deal();"
Thank you in advanced. This main has two other classes that go along with it. The DeckOfCards and Cards Classes.
Card Class
public class Card
{
public final static int ACE = 1;
public final static int TWO = 2;
public final static int THREE = 3;
public final static int FOUR = 4;
public final static int FIVE = 5;
public final static int SIX = 6;
public final static int SEVEN = 7;
public final static int EIGHT = 8;
public final static int NINE = 9;
public final static int TEN = 10;
public final static int JACK = 11;
public final static int QUEEN = 12;
public final static int KING = 13;
public final static int CLUBS = 1;
public final static int DIAMONDS = 2;
public final static int HEARTS = 3;
public final static int SPADES = 4;
private final static int NUM_FACES = 13;
private final static int NUM_SUITS = 4;
private int face, suit;
private String faceName, suitName;
//-----------------------------------------------------------------
// Creates a random card.
//-----------------------------------------------------------------
public Card()
{
face = (int) (Math.random() * NUM_FACES) + 1;
setFaceName();
suit = (int) (Math.random() * NUM_SUITS) + 1;
setSuitName();
}
//-----------------------------------------------------------------
// Creates a card of the specified suit and face value.
//-----------------------------------------------------------------
public Card(int faceValue, int suitValue)
{
face = faceValue;
setFaceName();
suit = suitValue;
setSuitName();
}
//-----------------------------------------------------------------
// Sets the string representation of the face using its stored
// numeric value.
//-----------------------------------------------------------------
private void setFaceName()
{
switch (face)
{
case ACE:
faceName = "Ace";
break;
case TWO:
faceName = "Two";
break;
case THREE:
faceName = "Three";
break;
case FOUR:
faceName = "Four";
break;
case FIVE:
faceName = "Five";
break;
case SIX:
faceName = "Six";
break;
case SEVEN:
faceName = "Seven";
break;
case EIGHT:
faceName = "Eight";
break;
case NINE:
faceName = "Nine";
break;
case TEN:
faceName = "Ten";
break;
case JACK:
faceName = "Jack";
break;
case QUEEN:
faceName = "Queen";
break;
case KING:
faceName = "King";
break;
}
}
//-----------------------------------------------------------------
// Sets the string representation of the suit using its stored
// numeric value.
//-----------------------------------------------------------------
private void setSuitName()
{
switch (suit)
{
case CLUBS:
suitName = "Clubs";
break;
case DIAMONDS:
suitName = "Diamonds";
break;
case HEARTS:
suitName = "Hearts";
break;
case SPADES:
suitName = "Spades";
break;
}
}
//-----------------------------------------------------------------
// Determines if this card is higher than the passed card. The
// second parameter determines if aces should be considered high
// (beats a King) or low (lowest of all cards). Uses the suit
// if both cards have the same face.
//-----------------------------------------------------------------
public boolean isHigherThan(Card card2, boolean aceHigh)
{
boolean result = false;
if (face == card2.getFace())
{
if (suit > card2.getSuit())
result = true;
}
else
{
if (aceHigh && face == ACE)
result = true;
else
if (face > card2.getFace())
result = true;
}
return result;
}
//-----------------------------------------------------------------
// Determines if this card is higher than the passed card,
// assuming that aces should be considered high.
//-----------------------------------------------------------------
public boolean isHigherThan(Card card2)
{
return isHigherThan(card2, true);
}
//-----------------------------------------------------------------
// Returns the face (numeric value) of this card.
//-----------------------------------------------------------------
public int getFace()
{
return face;
}
//-----------------------------------------------------------------
// Returns the suit (numeric value) of this card.
//-----------------------------------------------------------------
public int getSuit()
{
return suit;
}
//-----------------------------------------------------------------
// Returns the face (string value) of this card.
//-----------------------------------------------------------------
public String getFaceName()
{
return faceName;
}
//-----------------------------------------------------------------
// Returns the suit (string value) of this card.
//-----------------------------------------------------------------
public String getSuitName()
{
return suitName;
}
//-----------------------------------------------------------------
// Returns the string representation of this card, including
// both face and suit.
//-----------------------------------------------------------------
public String toString()
{
return faceName + " of " + suitName;
}
}
Deck of Cards Class
public class DeckOfCards
{
private Card[] myCardDeck;
private int nowCard;
public DeckOfCards( ) {
myCardDeck = new Card[ 52 ];
int i = 0;
for ( int suit = Card.SPADES; suit <= Card.DIAMONDS; suit++ )
for ( int pos = 1; pos <= 13; pos++ )
myCardDeck[i++] = new Card(suit, pos);
nowCard = 0;
}
public void shuffle(int n)
{
int i, j, k;
for ( k = 0; k < n; k++ )
{
i = (int) ( 52 * Math.random() );
j = (int) ( 52 * Math.random() );
Card tmp = myCardDeck[i];
myCardDeck[i] = myCardDeck[j];
myCardDeck[j] = tmp;;
}
nowCard = 0;
}
public Card deal()
{
if ( nowCard < 52 )
{
return ( myCardDeck[ nowCard++ ] );
}
else
{
System.out.println("No Cards BRUH");
return ( null );
}
}
public String toString()
{
String s = "";
int Q = 0;
for ( int i = 0; i < 4; i++ )
{
for ( int j = 1; j <= 13; j++ )
s += (myCardDeck[Q++] + " ");
s += "\n";
}
return ( s );
}
public int deckSize()
{
for(int z =0; z < myCardDeck.length && z < 52; z++);
return myCardDeck.length;
}
}
The main driver class (HighLow)
import java.util.*;
public class HighLow
{
public static void main (String [] args)
{
DeckOfCards d1 = new DeckOfCards();
Scanner scan = new Scanner(System.in);
String playerGuess;
Card firstDeal, secondDeal;
int count =0;
d1.shuffle(1);
firstDeal = d1.deal();
while(true)
{
if(d1.deckSize() == 0);
{
System.out.print("Game over! Score: " + count);
break;
}
System.out.print(firstDeal);
System.out.print("Guess if next card will be a high card, or a low card!");
System.out.print("Use H or L");
playerGuess = d1.deal();
if(secondDeal.isHigherThan(firstDeal)&&playerGuess.equals("H"))
{
System.out.print("Nice!!!!");
count++;
firstDeal=secondDeal;
}
else if(firstDeal.isHigherThan(secondDeal) && playerGuess.equals("L"))
{
System.out.println("NICE!!!!");
count++;
firstDeal = secondDeal;
}
else if (firstDeal.isHigherThan(secondDeal) && playerGuess.equals("L"))
{
System.out.print("Good Job!!!!");
count++;
firstDeal = secondDeal;
}
else
{
System.out.println("Sorry, the game is over. But your score is! " + count);
break;
}
}
}}
Thank you!
The method deal() returns a Card:
public Card deal() { ... }
The variable playerGuess is a String:
String playerGuess;
You can't assign a Card to a String:
playerGuess = d1.deal(); // incompatible types
It looks like you want playerGuess to store the user input, so it should be:
playerGuess = scan.next();

What is the reasoning behind the assert statements in the constructor vs. class's main method?

I'm taking this online Java course and don't understand the reasoning behind the different assert sections in the code.
Why are the rankToString assert methods in the class's main method vs. isValidRank methods in the class's constructor?
public class Card {
private final int rank;
private final int suit;
// Kinds of suits
public final static int DIAMONDS = 1;
public final static int CLUBS = 2;
public final static int HEARTS = 3;
public final static int SPADES = 4;
// Kinds of ranks
public final static int ACE = 1;
public final static int DEUCE = 2;
public final static int THREE = 3;
public final static int FOUR = 4;
public final static int FIVE = 5;
public final static int SIX = 6;
public final static int SEVEN = 7;
public final static int EIGHT = 8;
public final static int NINE = 9;
public final static int TEN = 10;
public final static int JACK = 11;
public final static int QUEEN = 12;
public final static int KING = 13;
public Card(int rank, int suit) {
assert isValidRank(rank);
assert isValidSuit(suit);
this.rank = rank;
this.suit = suit;
}
public int getSuit() {
return suit;
}
public int getRank() {
return rank;
}
public static boolean isValidRank(int rank) {
return ACE <= rank && rank <= KING;
}
public static boolean isValidSuit(int suit) {
return DIAMONDS <= suit && suit <= SPADES;
}
public static String rankToString(int rank) {
switch (rank) {
case ACE:
return "Ace";
case DEUCE:
return "Deuce";
case THREE:
return "Three";
case FOUR:
return "Four";
case FIVE:
return "Five";
case SIX:
return "Six";
case SEVEN:
return "Seven";
case EIGHT:
return "Eight";
case NINE:
return "Nine";
case TEN:
return "Ten";
case JACK:
return "Jack";
case QUEEN:
return "Queen";
case KING:
return "King";
default:
//Handle an illegal argument. There are generally two
//ways to handle invalid arguments, throwing an exception
//(see the section on Handling Exceptions) or return null
return null;
}
}
public static String suitToString(int suit) {
switch (suit) {
case DIAMONDS:
return "Diamonds";
case CLUBS:
return "Clubs";
case HEARTS:
return "Hearts";
case SPADES:
return "Spades";
default:
return null;
}
}
public static void main(String[] args) {
// must run program with -ea flag (java -ea ..) to
// use assert statements
assert rankToString(ACE) == "Ace";
assert rankToString(DEUCE) == "Deuce";
assert rankToString(THREE) == "Three";
assert rankToString(FOUR) == "Four";
assert rankToString(FIVE) == "Five";
assert rankToString(SIX) == "Six";
assert rankToString(SEVEN) == "Seven";
assert rankToString(EIGHT) == "Eight";
assert rankToString(NINE) == "Nine";
assert rankToString(TEN) == "Ten";
assert rankToString(JACK) == "Jack";
assert rankToString(QUEEN) == "Queen";
assert rankToString(KING) == "King";
assert suitToString(DIAMONDS) == "Diamonds";
assert suitToString(CLUBS) == "Clubs";
assert suitToString(HEARTS) == "Hearts";
assert suitToString(SPADES) == "Spades";
}
}
The asserts in the main method test assertions about static final fields, the asserts in the constructor test assertions about non-static final fields. Since assertions about static fields shouldn't be tested every time an object is created and non-static fields need a instance, it makes sense to place the assertions there.
However I would recommend writing jUnit tests instead of using asserts.
You'll find a tutorial for jUnit at vogella.com.
Some benefits of jUnit:
You don't have to mix the tests with the code, which makes the code more readable.
You can test sequences of function calls, ect. without changing the behaviour of the code (e.g. it's hard to test if an exception is thrown in asserts without adding a try-catch block to the code)
Most IDEs provide a nice user interface for jUnit
You have better control when you check your assertions. E.g. you can create 2 Cards without checking the assertions in the constructor twice.
assert is a java keyword that lets you test some condition (and enforce that it is valid). The format used here is assert <boolean>
You will see that that the expression after the assert evaluates to a boolean in both cases.
You can read more about it in this Oracle documentation.

Why isn't this public String function working?

It is saying that it must return a string but I don't see anything wrong with it? I think numericDayOfWeek should be working fine?
public String getDayOfWeek(){
if(numericDayOfWeek==0){
return "Saturday";
}
if(numericDayOfWeek==1){
return "Sunday";
}
if(numericDayOfWeek==2){
return "Monday";
}
if(numericDayOfWeek==3){
return "Tuesday";
}
if(numericDayOfWeek==4){
return "Wednesday";
}
if(numericDayOfWeek==5){
return "Thursday";
}
if(numericDayOfWeek==6){
return "Friday";
}
}
Here is the full code
public class DayOfWeek {
int myMonth, myDayOfMonth, myYear, myAdjustment, numericDayOfWeek;
public DayOfWeek(int month, int dayOfMonth, int year){
myMonth = month;
myDayOfMonth = dayOfMonth;
myYear = year;
}
public int getNumericDayOfWeek(){
if(myMonth==1){
myAdjustment = 1;
if(myYear%4==0){
myAdjustment-=1;
}
}
if(myMonth==2){
myAdjustment = 4;
if(myYear%4==0){
myAdjustment-=1;
}
}
if(myMonth==3){
myAdjustment = 4;
}
if(myMonth==4){
myAdjustment = 0;
}
if(myMonth==5){
myAdjustment = 2;
}
if(myMonth==6){
myAdjustment = 5;
}
if(myMonth==7){
myAdjustment = 0;
}
if(myMonth==8){
myAdjustment = 3;
}
if(myMonth==9){
myAdjustment = 6;
}
if(myMonth==10){
myAdjustment = 1;
}
if(myMonth==11){
myAdjustment = 4;
}
if(myMonth==12){
myAdjustment = 6;
}
int fourDivides = myYear / 4;
numericDayOfWeek = myAdjustment + myDayOfMonth + (myYear-1900) + fourDivides;
return numericDayOfWeek;
}
public String getDayOfWeek(){
if(numericDayOfWeek==0){
return "Saturday";
}
if(numericDayOfWeek==1){
return "Sunday";
}
if(numericDayOfWeek==2){
return "Monday";
}
if(numericDayOfWeek==3){
return "Tuesday";
}
if(numericDayOfWeek==4){
return "Wednesday";
}
if(numericDayOfWeek==5){
return "Thursday";
}
if(numericDayOfWeek==6){
return "Friday";
}
}
public int getMonth(){
}
public String getMonthString(){
}
public int getDayOfMonth(){
}
public int getYear(){
}
}
Sotirios is correct, but a better solution here would be to use a case statement:
switch(numericDayOfWeek)
{
case 0:
return "Saturday";
case 1:
return "Sunday";
case 2:
return "Monday";
case 3:
return "Tuesday";
case 4:
return "Wednesday";
case 5:
return "Thursday";
case 6:
return "Friday";
default:
return "Error";
}
If none of the conditions passes, ie. they all evaluate to false, the method wouldn't return anything. Add a default return at the end
public String getDayOfWeek(){
if(numericDayOfWeek==0){
return "Saturday";
}
if(numericDayOfWeek==1){
return "Sunday";
}
if(numericDayOfWeek==2){
return "Monday";
}
if(numericDayOfWeek==3){
return "Tuesday";
}
if(numericDayOfWeek==4){
return "Wednesday";
}
if(numericDayOfWeek==5){
return "Thursday";
}
if(numericDayOfWeek==6){
return "Friday";
}
return "Error";
}
The compiler considers all paths. If none if the if statements was executed it wouldn't have anything to return. In that case, it won't be able to compile because the method wouldn't guarantee the contract specified by its definition, ie. to return a String.
Follow the comments or the other answer on how to possibly makes this perform better or make it easier to read (switch-case).
This should work:
public String getDayOfWeek(){
if(numericDayOfWeek==0){
return "Saturday";
}
else if(numericDayOfWeek==1){
return "Sunday";
}
else if(numericDayOfWeek==2){
return "Monday";
}
else if(numericDayOfWeek==3){
return "Tuesday";
}
else if(numericDayOfWeek==4){
return "Wednesday";
}
else if(numericDayOfWeek==5){
return "Thursday";
}
else if(numericDayOfWeek==6){
return "Friday";
}
else{
return "Error";
}
}
The reason for the compiler error is that the compiler cannot be certain that your code will always return a String from your method.
In the event that numericDayOfWeek is not in the range of 0 to 6, your function does not specify what value should be returned, and there is no way for the compiler to know or guarantee that numericDayOfWeek will always be within the desired range.
Unfortunately, the compiler is limited in its ability to ensure a return statement even in simple cases. Take the trivial (and useless) method below:
// I have a compiler error!
public boolean testReturn()
{
final boolean condition = true;
if (condition) return true;
if (!condition) return false;
}
The above will result in a compiler error saying the method must return a type of boolean. We could easily fix it by changing the second if statement to be an else clause since that is one of the few ways that allow the compiler to ensure one or the other blocks of code are guaranteed to be executed.
// I compile!
public boolean testReturn()
{
final boolean condition = true;
if (condition) return true
else return false;
}
The rules are that a method with a return type must not complete normally and must instead complete abruptly (abruptly here indicating via a return statement or an exception) per JLS 8.4.7. The compiler looks to see whether normal termination is possible based on the rules defined in JLS 14.21 Unreachable Statements as it also defines the rules for normal completion.
In the case of your specific example, I would suggest considering throwing an IllegalArgumentException as the last line of your method and replacing your if statement with a switch statement. E.g.
public String getDayOfWeek()
{
switch(numericDayOfWeek)
{
case 0: return "Saturday";
case 1: return "Sunday";
case 2: return "Monday";
case 3: return "Tuesday";
case 4: return "Wednesday";
case 5: return "Thursday";
case 6: return "Friday";
}
throw new IllegalArgumentException("numericDayOfWeek is out of range: " + numericDayOfWeek);
}
You can also throw the exception in a default clause of the switch statement, but in this case I would say that is just a matter of personal preference and I prefer outside of the switch here.

How to test my Deck class in Java

I would like to print my ArrayList FullDeckArray to see if my Deck has all 52 cards and values.
This is my Card and Deck Classes below
package blackjack;
/**
*
* #author mvisser
*/
public class Card
{
private int rank;
private int suit;
public String tostring(Card card1)
{
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;
}
}
As you can see in my Deck Class I hava a ArrayList FullDeckArray and all I want to do is
print it out so see what value is bringing back
public class Deck
{
// private Card[][] fullDeck = new Card[0][0];
private Random shuffle = new Random();
public ArrayList<Card> FullDeckArray = new ArrayList<Card>();
// private int numberOfCards = 52;
public Deck()
{
for (int rank = 1; rank <= 13; rank++) {
for (int suit = 1; suit <= 4; suit++)
{
FullDeckArray.add(new Card(rank, suit));
}
}
}
public void shuffle() {
Collections.shuffle(FullDeckArray);
}
public Card DrawCard() {
int cardPosition = shuffle.nextInt(FullDeckArray.size()+1);
return FullDeckArray.remove(cardPosition);
}
public int TotalCards() {
return FullDeckArray.size();
}
public void test() {
System.out.println( ArrayList<Card>( FullDeckArray ) );
}
}
I would use enums, and with the enum.values() method, you can easily loop through all values of the enumeration.
public class Card {
public enum Rank {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING;
public String toString() {
switch(this) {
case ACE: return "Ace";
case TWO: return "Two";
case THREE: return "Three";
case FOUR: return "Four";
case FIVE: return "Five";
case SIX: return "Six";
case SEVEN: return "Seven";
case EIGHT: return "Eight";
case NINE: return "Nine";
case TEN: return "Ten";
case JACK: return "Jack";
case QUEEN: return "Queen";
case KING: return "King";
default: return "ERROR: no valid rank";
}
}
}
public enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES;
public String toString() {
switch(this) {
case CLUBS: return "Clubs";
case DIAMONDS: return "Diamonds";
case HEARTS: return "Hearts";
case SPADES: return "Spades";
default: return "ERROR: no valid suit";
}
}
}
private Rank rank;
private Suit suit;
public Card(Rank rank, Suit suit) {
this.rank = rank;
this.suit = suit;
}
public String toString() {
return rank.toString() + " of " + suit.toString();
}
public boolean equals(Object other) {
if (!(other instanceof Card)) return false;
Card card = (Card) other;
if (card.rank == this.rank && card.suit == this.suit) return true;
return false;
}
}
while in your deck class, you add all cards with this simple loop:
public void fill() {
for (Rank rank : Card.Rank.values()) {
for (Suit suit : Card.Suit.values()) {
Card card = new Card(rank, suit)
cards.add(card);
System.out.println(card.toString());
}
}
}
The rest of your deck class, you can maintain.
If you want to check for the cards being only added once, you can use a HashSet, as in a set, Objects can only occur once (but you need the equals() method):
HashSet<Card> set = new HashSet<Card>(cards);
cards = new ArrayList<Card>(set);
After that, you can check size with 'cards.size()'.
Update: Here's some code for evading the usage of Arrays in Card and for evading enums:
public class Deck {
private Random shuffle = new Random();
public ArrayList<Card> fullDeck = new ArrayList<Card>();
public Deck() {
for (int rank = 1; rank <= 13; rank++) {
for (int suit = 1; suit <= 4; suit++) {
fullDeck.add(new Card(rank, suit));
}
}
}
public void print() {
String deckOutput = "";
for (Card card : fullDeck) {
deckOutput += card.toString() + "\n";
}
System.out.println(deckOutput);
}
public static void main(String[] args) {
Deck deck = new Deck();
deck.print();
}
}
And for Card, use this:
public class Card {
private int rank;
private int suit;
public Card(int rank, int suit) {
this.rank = rank;
this.suit = suit;
}
public String toString() {
String Srank = "", Ssuit = "";
switch(rank) {
case 1: Srank = "Ace"; break;
case 2: Srank = "Two"; break;
case 3: Srank = "Three"; break;
case 4: Srank = "Four"; break;
case 5: Srank = "Five"; break;
case 6: Srank = "Six"; break;
case 7: Srank = "Seven"; break;
case 8: Srank = "Eight"; break;
case 9: Srank = "Nine"; break;
case 10: Srank = "Ten"; break;
case 11: Srank = "Jack"; break;
case 12: Srank = "Queen"; break;
case 13: Srank = "King"; break;
}
switch(suit) {
case 1: Ssuit = "Clubs"; break;
case 2: Ssuit = "Diamonds"; break;
case 3: Ssuit = "Hearts"; break;
case 4: Ssuit = "Spades"; break;
}
return Srank + " of " + Ssuit;
}
}
To test, you can still use the HashMap/ArrayList method stated above (only if you implement an equals method in Card as well) and check with the fulldeck.size() if there are 52 cards (which will be all different, because of the HashMap).
You should try this
public class DeckTest{
public static void main(String []args){
System.out.println(new Deck().FullDeckArray);
}
}
Your Card class should be like below code
public class Card
{
private int rank;
private int suit;
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;
}
}
you should override your tostring method like:
#override
public String toString(Card card1){
.....
}
and should just pass the arraylist name to System.out.println(). there is no need for type of the array list.
hope this helps...
There are two ways to do this: static and dynamic testing. Static is simpler and less prone to error, but it cannot be an action performed for any other purpose other than to simply verify that this part of your program works properly before moving on with the rest. Dynamic testing is slightly more complicated, but you can test a deck whenever you need to (for when the user modifies the deck in some fashion and you must validate it).
Static testing
The static testing method and the simplest way to do this would be to print out all the cards in a deck and verify it manually. To do that, you would first have to make an addition and a correction. First, you should modify the signature of your tostring method in your Card class to be "toString()" without parameters. This overrides the object method toString() which automatically converts an object to a String. Second, you need to override toString() in your Deck class:
#Override
public void toString() {
StringBuilder sb = new StringBuilder();
for(Card card : FullDeckArray) {
sb.append(card); // calls Card class's toString() method automatically.
sb.append('\n'); // newline character after each card
}
return sb.toString();
}
Now all you have to do is use Deck's toString() method.
public void test() {
System.out.println(this); // calls Deck class's toString() method automatically
}
Dyanmic testing
Testing it dynamically is a little more complicated, but not that much. To test this, how would you go about doing it manually? You'd look for missing cards or duplicates. A good way to test such things are Sets. But before you can use Sets, you must first override hashCode() and equals() methods to redefine how a Card class is considered unique. A card is only equal to another if both rank and suit match.
So add these to your Card class:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + rank;
result = prime * result + suit;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Card other = (Card) obj;
if (rank != other.rank)
return false;
if (suit != other.suit)
return false;
return true;
}
Now that we have that, we proceed with the actual logic. A simple test would go something like this:
For each card in your deck
If card is not in set
Add card to set
Else
Flag not valid! Duplicate card!
If set does not have exactly 52 cards
Flag not valid! Extra or missing cards!
So it naturally flows that the the code would then be:
public boolean test() {
boolean valid = true;
Set<Card> cardSet = new HashSet<Card>();
for(Card card : FullDeckArray) {
if(!cardSet.contains(card)) {
cardSet.add(card);
} else {
valid = false;
}
}
if(cardSet.size() != 52) {
valid = false;
}
return valid;
}
Also, you should look here for using enums. In addition to making code more readable, it also allows you to add methods like a class, and like a class, add toString() method. Also see jUnit for a decent testing library for Java.

Categories

Resources