Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help with Deck of cards assignment and getting it to deal...

1,082 views
Skip to first unread message

Scott Dunning

unread,
Aug 1, 2014, 9:16:33 PM8/1/14
to
Hello, I have an assignment for my summer class. FYI, I'm super new to
programming in general and this is my first time with java and it's a
summer class so it's going super fast (please be nice!) lol.

Basically I started writing my code in one class, then I split it up
into a Card class and a DeckOfCards class and I now need to figure out
how to get it all to work together. I get a little confused with
calling methods sometimes, especially when separate classes are in play.
I think I just need a method to deal out five cards that also tells
how many cards are left in the deck. Then get it all working together
correctly. Also, I need a toString method but I honestly do not know
how to go about that. Any help is greatly appreciated! If you could
help explain things too that would be awesome! I think I have
everything SO FAR correct but I could be wrong and I'm sure there are
better ways to write the code, I'll take any suggestions for a cleaner
look too. FYI, I think the prof would rather arrays then enums since
we're dealing with arrays right now.

Here are the directions...
Design and implement a class called Card that represents a standard
playing card. Each card has a suit and a face value. Then create a class
called DeckOfCards that stores 52 objects of the Card class. Include
methods to shuffle the deck, deal a card and report the number of cards
left in the deck. The shuffle methods should assume a full deck. Create
a driver class (CardsGame) with a main method that deals five cards from
the shuffled deck, printing each card as it is dealt. Make sure to write
the appropriate constructors, getters, setters, toString and other
methods as required for both classes.


The main class, CardsGame Class

import java.util.Scanner;

public class CardsGame {
public static void main (String [] args) {

}
}

Card Class

class Card {
public static final int SPADE = 4;
public static final int HEART = 3;
public static final int CLUB = 2;
public static final int DIAMOND = 1;

private int rank;
private int suit;
private static final String[] Suit = {"Hearts", "Clubs",
"Spades", "Diamonds"};
private static final String[] Rank = {"Ace", "2", "3", "4", "5",
"6", "7", "8", "9", "10", "Jack", "Queen", "King"};

private int cardSuit;
private int cardRank;

public Card(int suit, int rank) {
if (rank == 1)
cardRank = 14; // Give Ace the rank 14
else
cardRank = (int) rank;
cardSuit = (int) suit;
}

public int suit() {
return this.cardSuit;
}

public String suitStr() {
return(this.Suit[ this.cardSuit ]);

}

public int rank() {
return this.cardRank;
}

public String rankStr() {
return ( Rank[ cardRank ] );
}


public String toString() {
return ( Rank[ cardRank ] + Suit[ cardSuit ] );
}
}

DeckOfCards Class

class DeckOfCards {
public static final int NEWCARDS = 52;
private Card[] deckOfCards; // Contains all 52 cards
private int currentCard; // deal THIS card in deck

public DeckOfCards( ) {
deckOfCards = new Card[NEWCARDS];
int i = 0;

for ( int suit = Card.DIAMOND; suit <= Card.SPADE; suit++ )
for ( int rank = 1; rank <= 13; rank++ )
deckOfCards[i++] = new Card(suit, rank);
currentCard = 0;
}


//shuffle(n): shuffle the deck
public void shuffle(int n) {
int i, j, k;
for ( k = 0; k < n; k++ ) {
i = (int) ( NEWCARDS * Math.random() ); // Pick 2 random cards
j = (int) ( NEWCARDS * Math.random() ); // in the deck?

//swap these randomly picked cards
Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;
}
currentCard = 0; // Reset current card to deal
}
}


Roedy Green

unread,
Aug 2, 2014, 4:42:13 AM8/2/14
to
On Fri, 01 Aug 2014 18:16:33 -0700, Scott Dunning
<scot...@gmail.com> wrote, quoted or indirectly quoted someone who
said :

>Hello, I have an assignment for my summer class. FYI, I'm super new to
>programming in general and this is my first time with java and it's a
>summer class so it's going super fast (please be nice!) lol.

For basic background is shuffling, see
http://mindprod.com/pseudorandom.html
--
Roedy Green Canadian Mind Products http://mindprod.com
The art of strongly-typed language design is largely arranging
that errors are automatically detected as soon as possible
in the compose, compile, run cycle.

Martin Gregorie

unread,
Aug 2, 2014, 6:19:42 AM8/2/14
to
On Sat, 02 Aug 2014 01:42:13 -0700, Roedy Green wrote:

> On Fri, 01 Aug 2014 18:16:33 -0700, Scott Dunning <scot...@gmail.com>
> wrote, quoted or indirectly quoted someone who said :
>
>>Hello, I have an assignment for my summer class. FYI, I'm super new to
>>programming in general and this is my first time with java and it's a
>>summer class so it's going super fast (please be nice!) lol.
>
> For basic background is shuffling, see
> http://mindprod.com/pseudorandom.html

In Java the indices of an array start to zero, not 1. Assuming that they
start from 1, as you've done, will almost certainly cause problems at
runtime by throwing "index out of range" exceptions.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Mike Amling

unread,
Aug 3, 2014, 8:38:42 AM8/3/14
to
Better to throw an exception if suit or rank is outside their
required range than to allow malformed instances.
> if (rank == 1)
> cardRank = 14; // Give Ace the rank 14
> else
> cardRank = (int) rank;
> cardSuit = (int) suit;
Indentation does not match conditional execution.
> }
>
> public int suit() {
> return this.cardSuit;
> }
>
> public String suitStr() {
> return(this.Suit[ this.cardSuit ]);
> }
>
> public int rank() {
> return this.cardRank;
> }
>
> public String rankStr() {
> return ( Rank[ cardRank ] );
> }
>
>
> public String toString() {
> return ( Rank[ cardRank ] + Suit[ cardSuit ] );
> }
> }
>
> DeckOfCards Class
>
> class DeckOfCards {
> public static final int NEWCARDS = 52;
I suggest
private static final Random CHANCE=new Random();
> private Card[] deckOfCards; // Contains all 52 cards
> private int currentCard; // deal THIS card in deck
>
> public DeckOfCards( ) {
> deckOfCards = new Card[NEWCARDS];
> int i = 0;
>
> for ( int suit = Card.DIAMOND; suit <= Card.SPADE; suit++ )
> for ( int rank = 1; rank <= 13; rank++ )
> deckOfCards[i++] = new Card(suit, rank);
> currentCard = 0;
Indented as if it were part of the for loop.
I suggest using the braces for each and every if, else, for, while
and do. You'll never regret it.
> }
>
>
> //shuffle(n): shuffle the deck
> public void shuffle(int n) {
Search for Fisher-Yates shuffling algorithm (sometimes misattributed
to Knuth). There's no need for shuffle to have a parameter if it's
intended to perform a random shuffle.
> int i, j, k;
> for ( k = 0; k < n; k++ ) {
> i = (int) ( NEWCARDS * Math.random() ); // Pick 2 random
> cards
java.util.Random is better for random integers. CHANCE.nextInt(n)
returns a random integer in the range 0 .. n-1, which is what you'll want.
> j = (int) ( NEWCARDS * Math.random() ); // in the deck?
>
> //swap these randomly picked cards
> Card temp = deckOfCards[i];
> deckOfCards[i] = deckOfCards[j];
> deckOfCards[j] = temp;
> }
> currentCard = 0; // Reset current card to deal
> }
Don't you need something like
Card deal() {
if (currentCard==NEWCARDS) {
throw IllegalStateException("All gone.");
}
return deckOfCards[currentCard++];
}
> }

Eric Sosman

unread,
Aug 3, 2014, 10:23:28 AM8/3/14
to
On 8/1/2014 9:16 PM, Scott Dunning wrote:
> [...]
> //shuffle(n): shuffle the deck
> public void shuffle(int n) {
> int i, j, k;
> for ( k = 0; k < n; k++ ) {
> i = (int) ( NEWCARDS * Math.random() ); // Pick 2 random
> cards
> j = (int) ( NEWCARDS * Math.random() ); // in the deck?
>
> //swap these randomly picked cards
> Card temp = deckOfCards[i];
> deckOfCards[i] = deckOfCards[j];
> deckOfCards[j] = temp;
> }
> currentCard = 0; // Reset current card to deal
> }
> }

Others have observed that this shuffling procedure is biased,
and suggested alternatives. I'd just like to point out that it
may not be necessary to shuffle at all!

Here's the idea: The fundamental operation is "deal one card"
(you can do this N times in succession to deal N cards). Judging
by your `currentCard' variable, you plan to shuffle the deck and
then march through it in sequence, dealing the first, second, ...
card in succession. That will work fine (if you shuffle well).

But what if you just left the deck in any old order at all,
even "factory-fresh" with all the suits and ranks in order, *but*
instead of dealing sequentially you dealt a randomly-chosen card?
You'd need to ensure that a card already dealt wouldn't be dealt
again (in the Wild West, the presence of two Aces of Spades in a
single poker game might well provoke a gunfight), so after dealing
the randomly-chosen card you'd need to remove it from the deck.
That's a fairly natural idea, though: If you start with a deck of
fifty-two cards and deal one of them, you expect to be holding a
deck of fifty-one, right?

Okay, so this suggests not a `currentCard' variable that
marches through a shuffled array, but a `cardCount' variable
that keeps track of how many un-dealt cards remain. In a fresh
deck this variable would be 52, and it would decrease as cards
were plucked out and dealt away. Here's an outline:

public class DeckOfCards {
private final Card[] cards;
private int cardCount;

public DeckOfCards() {
cards = new Card[52];
// ... fill the array with Cards ...
cardCount = 52;
}

public Card dealOneCard() {
// Sanity check:
if (cardCount <= 0) {
throw new IllegalStateException("no cards left!");
}

// Choose the card to deal:
int which = (int) (cardCount * Math.random());
Card dealt = cards[which];

// Remove the dealt card from the deck by moving
// the last card into the vacated place (this works
// even when dealing the last card):
cards[which] = cards[cardCount - 1];

// There's one less card than there used to be:
--cardCount;

return dealt;
}

// ... other methods ...
}

(I've written this for clarity; there are ways to tighten it up a
little, and Mike Amling has suggested a better way to get a random
integer, but I've tried to stick with things you've already shown
you're familiar with.)

Your assignment says you're supposed to write a shuffle() method,
and perhaps your instructor will give you poor marks if you don't.
But then you might pacify him with

public void shuffle() {
if (cardCount != 52) {
throw new IllegalStateException(
"not playing with a full deck (as promised)!");
}
}

If he objects that the method is vacuous, your comeback could be
that *by using the other methods of DeckOfCards* there's no way
to detect the vacuousness! He can create as many decks and deal
as many cards as he likes and subject them to every statistical
test at his disposal, and although he might uncover problems with
Math.random() and so on he will never be able to show that you're
not shuffling!

... and *that* is another important aspect of programming,
called "encapsulation." The idea is that a class promises to
provide various behaviors but does not promise to do so in any
particular way. You describe *what* the (exposed) methods of
your class will do, but you don't say *how* they'll do it. This
means that next week when you think of a better way (like, how
to deal a random card without shuffling), you're free to change
how you've done things. A short-order cook filling two orders
for scrambled eggs needn't reveal whether he cooked two small
batches or one big one; all he needs to do is serve up two platefuls
by whatever means he finds convenient. If your classes follow a
similar philosophy, you'll write better classes.

--
eso...@comcast-dot-net.invalid

Jeff Higgins

unread,
Aug 3, 2014, 11:08:01 AM8/3/14
to
On 08/01/2014 09:16 PM, Scott Dunning wrote:
> Hello, I have an assignment for my summer class. FYI, I'm super new to
> programming in general and this is my first time with java and it's a
> summer class so it's going super fast (please be nice!) lol.

No. It seems to be going slowly. The last three assignments you've
brought here are rehashes. Surely by now you should have gone into
interfaces and collections.

Your Card class will be more easily used if it implement the
java.lang.Comparable<T> interface

> Basically I started writing my code in one class, then I split it up
> into a Card class and a DeckOfCards class and I now need to figure out
> how to get it all to work together. I get a little confused with
> calling methods sometimes, especially when separate classes are in play.

PLEASE work your way through the "Learning the Java Language" trail in
the Java Tutorials. Your instructor is not helping you if he hasn't
insisted upon this.

> I think I just need a method to deal out five cards that also tells
> how many cards are left in the deck.

Not necessarily. java.lang.Iterable<T> interface comes to mind.
As others have pointed out: there are many ways to accomplish
an outcome.

> Then get it all working together
> correctly. Also, I need a toString method but I honestly do not know
> how to go about that. Any help is greatly appreciated! If you could
> help explain things too that would be awesome!

For what? Your Card class? What are its attributes? Take out your paper
and pencil, or even just put on your thinking cap and decide how you
want your Card represented as a String.
<http://unicode.org/charts/PDF/U1F0A0.pdf>
You already have a toString method, but it is probably not what you want.
<http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html>
Rank[ cardRank ] + Suit[ cardSuit ] would present a fairly ugly
representation, have you tried it?

> I think I have
> everything SO FAR correct but I could be wrong and I'm sure there are
> better ways to write the code, I'll take any suggestions for a cleaner
> look too. FYI, I think the prof would rather arrays then enums since
> we're dealing with arrays right now.

I'm gaining less respect, especially if the following is verbatim.

> Here are the directions...
> Design and implement a class called Card that represents a standard
> playing card. Each card has a suit and a face value. Then create a class
> called DeckOfCards that stores 52 objects of the Card class. Include
> methods to shuffle the deck, deal a card and report the number of cards
> left in the deck. The shuffle methods should assume a full deck. Create
> a driver class (CardsGame) with a main method that deals five cards from
> the shuffled deck, printing each card as it is dealt. Make sure to write
> the appropriate constructors, getters, setters, toString and other
> methods as required for both classes.

Why show us a place holder?

Eric Sosman

unread,
Aug 3, 2014, 11:41:27 AM8/3/14
to
On 8/3/2014 11:08 AM, Jeff Higgins wrote:
> On 08/01/2014 09:16 PM, Scott Dunning wrote:
>> Hello, I have an assignment for my summer class. FYI, I'm super new to
>> programming in general and this is my first time with java and it's a
>> summer class so it's going super fast (please be nice!) lol.
>
> No. It seems to be going slowly. The last three assignments you've
> brought here are rehashes. Surely by now you should have gone into
> interfaces and collections.
>
> Your Card class will be more easily used if it implement the
> java.lang.Comparable<T> interface

I'd advise against this, because the ordering depends not on the
Card, but on the rules of whatever game is being played. There are
games where Ace is high, games where it is low, games where it can
be either at the discretion of the player, and for all I know there
may be games where Ace can lie between King and Deuce. And then
there's the question of suit: How does the Seven of Hearts compare
to the Jack of Clubs? Would knowing whether Hearts are trumps affect
your answer?

Scott: Don't Go There; you'll just get lost.

--
eso...@comcast-dot-net.invalid

Jeff Higgins

unread,
Aug 3, 2014, 1:25:21 PM8/3/14
to
On 08/03/2014 11:41 AM, Eric Sosman wrote:
> On 8/3/2014 11:08 AM, Jeff Higgins wrote:
>> On 08/01/2014 09:16 PM, Scott Dunning wrote:
>>> Hello, I have an assignment for my summer class. FYI, I'm super new to
>>> programming in general and this is my first time with java and it's a
>>> summer class so it's going super fast (please be nice!) lol.
>>
>> No. It seems to be going slowly. The last three assignments you've
>> brought here are rehashes. Surely by now you should have gone into
>> interfaces and collections.
>>
>> Your Card class will be more easily used if it implement the
>> java.lang.Comparable<T> interface
>
> I'd advise against this,

> because the ordering depends not on the
> Card, but on the rules of whatever game is being played.

Exactly.

> There are
> games where Ace is high, games where it is low, games where it can
> be either at the discretion of the player, and for all I know there
> may be games where Ace can lie between King and Deuce. And then
> there's the question of suit: How does the Seven of Hearts compare
> to the Jack of Clubs? Would knowing whether Hearts are trumps affect
> your answer?
>
> Scott: Don't Go There; you'll just get lost.
>
Scott: If you don't go there you'll never find your way.

package scratch;

/**
* The face value of a {@link Card}.
*
* Rank specifies one of 13 distinct,
* implementation defined values and their order.
*
* The default values and order for Rank are:
* Ace, Two through Ten inclusive, Jack, Queen, King.
*
* @author jeff
*
*/
public interface Rank extends Comparable<Rank> {

}

package scratch;

/**
* The suit of a {@link Card}.
*
* Suit specifies one of an implementation defined
* number of distinct values and their order(if any).
*
* The default values and their order(highest to lowest)
* for Suit are: Spades, Hearts, Diamonds, Clubs.
*
* @author jeff
*
*/
public interface Suit extends Comparable<Suit> {

}

package scratch;

/**
* A playing card.
*
* @author jeff
*
*/
public interface Card extends Comparable<Card> {

/**
* Returns one of the 13 distinct values represented
* in the implementation of the {@link Rank} interface.
*
* @return the Rank of this Card.
*/
Rank getRank();

/**
* Returns one of the distinct values represented
* in the implementation of the {@link Suit} interface.
*
* @return the Suit of this Card.
*/
Suit getSuit();

}

package scratch;

/**
* An ordered set of playing {@link Card}s.
*
* @author jeff
*
*/
public interface Deck extends Iterable<Card> {

}

Implement the Rank and Suit interfaces using the default values as
immutable concrete classes.
Implement an immutable Card interface using your concrete Rank and Suit
classes.
Implement the Deck interface, including its java.lang.Iterator<E>
implementation, as an immutable concrete class.
Design and implement a Game class using the above implemented classes.
The game is to deal a hand of five Cards from the Deck and compare hands
until no further hands may be dealt.

Jeff Higgins

unread,
Aug 3, 2014, 1:36:12 PM8/3/14
to
On 08/03/2014 01:25 PM, Jeff Higgins wrote:

> package scratch;
>
> /**
> * The face value of a {@link Card}.
> *
> * Rank specifies one of 13 distinct,
> * implementation defined values and their order.
> *
> * The default values and order for Rank are:
> * Ace, Two through Ten inclusive, Jack, Queen, King.
> *
> * @author jeff
> *
> */
> public interface Rank extends Comparable<Rank> {
>
> }
>
For a more universal appeal the restriction to 13 may be relaxed.


Jeff Higgins

unread,
Aug 3, 2014, 1:47:50 PM8/3/14
to
On 08/03/2014 01:25 PM, Jeff Higgins wrote:

> package scratch;
>
> /**
> * A playing card.
> *
> * @author jeff
> *
> */
> public interface Card extends Comparable<Card> {
>
> /**
> * Returns one of the 13 distinct values represented
> * in the implementation of the {@link Rank} interface.
> *
> * @return the Rank of this Card.
> */
> Rank getRank();
>
> /**
> * Returns one of the distinct values represented
> * in the implementation of the {@link Suit} interface.
> *
> * @return the Suit of this Card.
> */
> Suit getSuit();
>
> }
>
Hint: java.lang.Comparator<T>
Hint II: java+comparable+vs+comparator
How to implement the Comparable interface using a Comparator?

Jeff Higgins

unread,
Aug 3, 2014, 1:52:27 PM8/3/14
to
On 08/03/2014 01:47 PM, Jeff Higgins wrote:
> Hint:
Once agin the Java Tutorials come through.
<http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html>

lipska the kat

unread,
Aug 3, 2014, 1:52:51 PM8/3/14
to
On 03/08/14 15:23, Eric Sosman wrote:
> On 8/1/2014 9:16 PM, Scott Dunning wrote:

<snip>

> Others have observed that this shuffling procedure is biased,
> and suggested alternatives. I'd just like to point out that it
> may not be necessary to shuffle at all!
>
> Here's the idea: The fundamental operation is "deal one card"
> (you can do this N times in succession to deal N cards). Judging
> by your `currentCard' variable, you plan to shuffle the deck and
> then march through it in sequence, dealing the first, second, ...
> card in succession. That will work fine (if you shuffle well).
>
> But what if you just left the deck in any old order at all,
> even "factory-fresh" with all the suits and ranks in order, *but*
> instead of dealing sequentially you dealt a randomly-chosen card?

<snip>

This is a poor abstraction I'm afraid. One of the things we try to teach
when we teach an OO language is the concept of the real world abstraction.

In the real world, if you dealt a 'randomly chosen card' your
opponent[s] might be forgiven for `popping a cap in yo' ass` :-)

Not only is a shuffle method required by the specification but it is a
realistic real world abstraction, also it removes any additional
complexity involved in keeping track of which cards have been dealt. I
believe that if you do this in 'Vegas (card counting that is) you will
be politely shown the door by a number of large European gentlemen with
a penchant for olive oil.


<snip>


--
lipska the kat - treacherous feline.
Proudly nominated for IPOTY 2014 - LIGAF
GNU/Linux user #560883 - linuxcounter.net

Jeff Higgins

unread,
Aug 3, 2014, 2:10:27 PM8/3/14
to
On 08/03/2014 01:52 PM, Jeff Higgins wrote:
> On 08/03/2014 01:47 PM, Jeff Higgins wrote:
>> Hint:
Two of your classmates spend some of their spare time studying the
fine manual. They will soon be writing exciting Java programs for
fun and profit. See if you can pick them out. They have already
sussed out their * classmates.


Jeff Higgins

unread,
Aug 3, 2014, 2:16:23 PM8/3/14
to
On 08/03/2014 01:52 PM, lipska the kat upchucked.

Congratulations.
Absolutely Racialicious.

lipska the kat

unread,
Aug 3, 2014, 2:21:02 PM8/3/14
to
What are you suggesting ?

Jeff Higgins

unread,
Aug 3, 2014, 2:38:19 PM8/3/14
to
On 08/03/2014 02:21 PM, lipska the kat wrote:
> On 03/08/14 19:16, Jeff Higgins wrote:
>> On 08/03/2014 01:52 PM, lipska the kat upchucked.
>>
>> Congratulations.
>> Absolutely Racialicious.
>>
>
Your sentence seems out of character.
> What are you suggesting ?
^^
, hmm

lipska the kat

unread,
Aug 3, 2014, 2:41:28 PM8/3/14
to
It's called a question mark.

http://en.wikipedia.org/wiki/Question_mark

oh, wait a minute ...

Eric Sosman

unread,
Aug 3, 2014, 3:00:04 PM8/3/14
to
"Poker" is the name for a popular family of card games in which
this approach Absolutely Will Not Work. I've already mentioned that
Ace can be lower than Deuce, Deuce lower than Trey, ..., Queen lower
than King, and King lower than (oops!) Ace. The "total ordering"
required by Comparable simply doesn't exist, and any attempt to
implement Comparable is just plain doomed.

It gets worse: There are situations where Ace compares unequal
to Ace, that is, where one Ace compares lower/higher than another,
as in A 2 3 4 5 (the lowest possible straight) vs. T J Q K A (the
highest possible). The result of `ACE.compareTo(ACE)' could be
negative, zero, or positive depending on the situation -- and the
compareTo() method doesn't have access to situational information.

But wait! That's not all; it gets even worse still! There are
situations where the very same instance of an Ace is both high and
low at the same time! Ordinary poker variants award the entire pot
to the highest-ranking hand, but "high-low" variants divide it between
the highest and the lowest hand. If you hold A 2 3 4 5 you have a
chance of being both the lowest *and* the highest: Call the Ace low
and you've got a straight (not a rock-crusher, but a fairly good hand),
or call it high and have a bust with one high card (not the worst
possible hand, but pretty weak). In this situation the very same
instance of Ace is both higher *and* lower than Deuce, both higher
*and* lower than itself! And you want to capture this in Comparable?

Given the variety of card games, Comparable is a wrong-headed
approach for ranks, for suits, and even for hands.

Scott: Don't Go There; you'll just get lost.

--
eso...@comcast-dot-net.invalid

Arne Vajhøj

unread,
Aug 3, 2014, 3:26:13 PM8/3/14
to
I must admit that I can not follow you.

The fact that different games may use a different ordering is
not an argument against Comparable<>.

Comparable<> is not the one and only ordering. Comparable<> is
just the natural ordering. It is perfectly valid to have a
Comparable<> with the natural ordering and a bunch of
Comparator<> to handle the context specific orderings.

Arne



lipska the kat

unread,
Aug 3, 2014, 3:34:11 PM8/3/14
to
On 03/08/14 20:26, Arne Vajh�j wrote:
> On 8/3/2014 3:00 PM, Eric Sosman wrote:
>> On 8/3/2014 1:25 PM, Jeff Higgins wrote:
>>> On 08/03/2014 11:41 AM, Eric Sosman wrote:
>>>> On 8/3/2014 11:08 AM, Jeff Higgins wrote:
>>>>> On 08/01/2014 09:16 PM, Scott Dunning wrote:

<snip>

>> Given the variety of card games, Comparable is a wrong-headed
>> approach for ranks, for suits, and even for hands.
>>
>> Scott: Don't Go There; you'll just get lost.
>
> I must admit that I can not follow you.
>
> The fact that different games may use a different ordering is
> not an argument against Comparable<>.
>
> Comparable<> is not the one and only ordering. Comparable<> is
> just the natural ordering. It is perfectly valid to have a
> Comparable<> with the natural ordering and a bunch of
> Comparator<> to handle the context specific orderings.

Exactly, and what better way to encapsulate the rules of a game than in
a Comparator.

You can develop Deck and Shuffle and Hand etc etc and simply (well
perhaps not 'simply') implement different games by implementing
different Comparators ... Sounds 'OO' to me.

Jeff Higgins

unread,
Aug 3, 2014, 3:45:50 PM8/3/14
to
On 08/03/2014 03:00 PM, Eric Sosman wrote:
> Given the variety of card games, Comparable is a wrong-headed
> approach for ranks, for suits, and even for hands.
>
Perhaps, but just for my own enlightenment, allow me one more interface
and then describe a *simple* game that that cannot be implemented given
the provided interfaces.

package scratch;

import java.util.Collection;

/**
* A Card game controller.
* While we have hands to play, compare hands.
*
* @author jeff
*
*/
public interface Ruler extends Iterable<Ruler>,
Comparable<Collection<Card>> {

}


Jeff Higgins

unread,
Aug 3, 2014, 4:01:43 PM8/3/14
to
Well, that could probably have been done better but you get my drift.

Eric Sosman

unread,
Aug 3, 2014, 4:49:27 PM8/3/14
to
On 8/3/2014 3:26 PM, Arne Vajh�j wrote:
>[...]
> I must admit that I can not follow you.
>
> The fact that different games may use a different ordering is
> not an argument against Comparable<>.
>
> Comparable<> is not the one and only ordering. Comparable<> is
> just the natural ordering. It is perfectly valid to have a
> Comparable<> with the natural ordering and a bunch of
> Comparator<> to handle the context specific orderings.

Although one could select different Comparators for different
games -- one for Ace-low, say, and another for Ace-high -- there
is no way a Comparator could work for "Ace-either" games like Poker
(and certainly not for "Ace-both" games like high-low Poker!). Like
Comparable, Comparator reflects a _total ordering_ on the objects it
compares, and a total ordering must be transitive:

If X < Y and Y < Z then X < Z, for all X,Y,Z.

In Poker, one can have

Ace < Five and Five < Ten but Ten < Ace

... violating transitivity, so the ranks do not follow a total order.

One could, of course, implement a Comparator (or a Comparable)
that broke the rules and violated its "contractual obligation" to
impose a total order. But a Comparable/Comparator that didn't behave
as it should would make mockery of the claim

> Your Card class will be more easily used if it implement the
> java.lang.Comparable<T> interface

... because none of the Comparable- or Comparator-based utility
classes and methods would behave properly: Collections.sort(),
Arrays.binarySearch(), SortedMap(), ... Something that simply
doesn't work cannot be "more easily used."

--
eso...@comcast-dot-net.invalid

Arne Vajhøj

unread,
Aug 3, 2014, 5:01:48 PM8/3/14
to
On 8/3/2014 4:49 PM, Eric Sosman wrote:
> On 8/3/2014 3:26 PM, Arne Vajh�j wrote:
>> [...]
>> I must admit that I can not follow you.
>>
>> The fact that different games may use a different ordering is
>> not an argument against Comparable<>.
>>
>> Comparable<> is not the one and only ordering. Comparable<> is
>> just the natural ordering. It is perfectly valid to have a
>> Comparable<> with the natural ordering and a bunch of
>> Comparator<> to handle the context specific orderings.
>
> Although one could select different Comparators for different
> games -- one for Ace-low, say, and another for Ace-high -- there
> is no way a Comparator could work for "Ace-either" games like Poker
> (and certainly not for "Ace-both" games like high-low Poker!). Like
> Comparable, Comparator reflects a _total ordering_ on the objects it
> compares, and a total ordering must be transitive:
>
> If X < Y and Y < Z then X < Z, for all X,Y,Z.
>
> In Poker, one can have
>
> Ace < Five and Five < Ten but Ten < Ace
>
> ... violating transitivity, so the ranks do not follow a total order.
>
> One could, of course, implement a Comparator (or a Comparable)
> that broke the rules and violated its "contractual obligation" to
> impose a total order. But a Comparable/Comparator that didn't behave
> as it should would make mockery of the claim

So maybe a game need something more advanced than a Comparator<>, but
that does still not show that a Card class should not be
Comparable<>.

Arne


Mike Amling

unread,
Aug 3, 2014, 5:05:20 PM8/3/14
to
On 8/3/14 9:23 AM, Eric Sosman wrote:
> public class DeckOfCards {
> private final Card[] cards;
> private int cardCount;
>
> public DeckOfCards() {
> cards = new Card[52];
> // ... fill the array with Cards ...
> cardCount = 52;
> }
>
> public Card dealOneCard() {
> // Sanity check:
> if (cardCount <= 0) {
> throw new IllegalStateException("no cards left!");
> }
>
> // Choose the card to deal:
> int which = (int) (cardCount * Math.random());
> Card dealt = cards[which];
>
> // Remove the dealt card from the deck by moving
> // the last card into the vacated place (this works
> // even when dealing the last card):
> cards[which] = cards[cardCount - 1];
>
> // There's one less card than there used to be:
> --cardCount;
>
> return dealt;
> }
>
> // ... other methods ...
> }

So, the shuffle method is superfluous. Rather than myDeck.shuffle(),
one would code myDeck=new DeckOfCards()? Not bad.

--Mike Amling
R2VuZXJhbGl6YWJsZSB0byBkcmF3aW5nIGZyb20gdXJucy4=

Eric Sosman

unread,
Aug 3, 2014, 5:05:28 PM8/3/14
to
I think so. However, I've already mentioned the "high-low" types
of Poker, where a single hand can be both higher and lower than another.
I gave one example upthread; here's another:

With Aces high, A A A 7 7 is a "full house," a very strong hand.
It is just a little bit stronger than K K K J J, another full house,
because when two full houses meet they are ranked by their triples:
In this case, AAA beats KKK so the first hand is higher. But play
the Aces low instead, and now KKK beats AAA so the second hand is
higher. If the deal's final showdown involved these two hands, the
first could be *both* high and low, and win the entire pot by
trapping the second hand "in between."

Your challenge, then, should you choose to accept it: Write a
compareTo() method for which AAA77.compareTo(KKKJJ) returns a
value that is simultaneously positive and negative. Maybe when
quantum computing comes of age ...

Yes, okay, I see your "*simple*" -- but I reject it as weasel-
wording: Confronted with a game for which your approach won't work,
you could just say "Oh, but that's not *simple* in the way I choose
to define it." Problem-avoidance is a viable strategy sometimes, but
it shouldn't be mistaken for problem-solving.

--
eso...@comcast-dot-net.invalid

Jeff Higgins

unread,
Aug 3, 2014, 5:19:17 PM8/3/14
to
On 08/03/2014 04:49 PM, Eric Sosman wrote:
> On 8/3/2014 3:26 PM, Arne Vajh�j wrote:
>> [...]
>> I must admit that I can not follow you.
>>
>> The fact that different games may use a different ordering is
>> not an argument against Comparable<>.
>>
>> Comparable<> is not the one and only ordering. Comparable<> is
>> just the natural ordering. It is perfectly valid to have a
>> Comparable<> with the natural ordering and a bunch of
>> Comparator<> to handle the context specific orderings.
>
> Although one could select different Comparators for different
> games -- one for Ace-low, say, and another for Ace-high -- there
> is no way a Comparator could work for "Ace-either" games like Poker
> (and certainly not for "Ace-both" games like high-low Poker!). Like
> Comparable, Comparator reflects a _total ordering_ on the objects it
> compares, and a total ordering must be transitive:
>
> If X < Y and Y < Z then X < Z, for all X,Y,Z.
>
> In Poker, one can have
>
> Ace < Five and Five < Ten but Ten < Ace
>
> ... violating transitivity, so the ranks do not follow a total order.

In my proposed interface Ace is a valid Rank but Five and Five is not.
In my proposed interface I cannot see where any contract is broken by
run time variation of the natural ordering of the Rank. Sure, comparing
one Rank object at different times or places and getting different
results might seem odd but not wrong. I may be though. Please correct
me if this is the case.

Jeff Higgins

unread,
Aug 3, 2014, 5:37:18 PM8/3/14
to
I've not written an interface that compares Collections of Ranks
or Suits or Cards or Decks. A Game will require such behavior.
I still believe that behavior is implementable using the interfaces
I've described, and not uncleanly. Please describe a *simple*
situation that disproves my belief, I promise not to exercise my
Weasel options.

Jeff Higgins

unread,
Aug 3, 2014, 6:09:40 PM8/3/14
to
On 08/03/2014 05:05 PM, Eric Sosman wrote:

> Your challenge, then, should you choose to accept it: Write a
> compareTo() method for which AAA77.compareTo(KKKJJ) returns a
> value that is simultaneously positive and negative. Maybe when
> quantum computing comes of age ...
Noone have asked for any simultaneously positive and negative value.
Since you've thrown out the "total order" term (somewhere in these
threads) I'll throw "predicate" in there.

Jeff Higgins

unread,
Aug 3, 2014, 6:19:12 PM8/3/14
to
On 08/03/2014 05:37 PM, Jeff Higgins wrote:

> I've not written an interface that compares Collections of Ranks
> or Suits or Cards or Decks. A Game will require such behavior.
> I still believe that behavior is implementable using the interfaces
> I've described, and not uncleanly. Please describe a *simple*
> situation that disproves my belief, I promise not to exercise my
> Weasel options.

"as an ook cometh of a litel spyr". There I've done it.
One variation of my all time favorite quotation becomes
apropos if we consider the interfaces I've proposed as
part of the "litel spyr".


Jeff Higgins

unread,
Aug 3, 2014, 6:34:09 PM8/3/14
to
Someone please tell me if I should be concentrating on this evening's
supper of ground beef patties instead of following
comp.lang.java.programmer.

Roedy Green

unread,
Aug 3, 2014, 6:54:52 PM8/3/14
to
On Sat, 2 Aug 2014 10:19:42 +0000 (UTC), Martin Gregorie
<mar...@address-in-sig.invalid> wrote, quoted or indirectly quoted
someone who said :

>
>In Java the indices of an array start to zero, not 1. Assuming that they
>start from 1, as you've done, will almost certainly cause problems at
>runtime by throwing "index out of range" exceptions.

http://mindprod.com/jgloss/pseudorandom.html

I scanned the page, but I could not find an example where your comment
applies. I showed you how to generate a random number in the bounds
low .. high, but other than that all the others start at 0.

Could you please give me the context of the error, or perhaps you were
referring to something OP or another poster said.
--
Roedy Green Canadian Mind Products http://mindprod.com
The art of strongly-typed language design is largely arranging
that errors are automatically detected as soon as possible
in the compose, compile, run cycle.

Eric Sosman

unread,
Aug 3, 2014, 8:37:16 PM8/3/14
to
Ground lamb would be my preference, but I have no quarrel
with ground beef and agree it might be tastier than c.l.j.p.
Good night!

--
eso...@comcast-dot-net.invalid

Jeff Higgins

unread,
Aug 3, 2014, 8:40:12 PM8/3/14
to
I'll take it with the grain of salt it lacks.

Jeff Higgins

unread,
Aug 3, 2014, 8:49:30 PM8/3/14
to
And have a nice day! :)

David Postill

unread,
Aug 4, 2014, 3:00:22 AM8/4/14
to
In article <lrlrug$6nk$1...@dont-email.me>, on Sun, 03 Aug 2014 13:36:12
-0400, Jeff Higgins wrote:

| On 08/03/2014 01:25 PM, Jeff Higgins wrote:
|
| > package scratch;
| >
| > /**
| > * The face value of a {@link Card}.
| > *
| > * Rank specifies one of 13 distinct,
| > * implementation defined values and their order.
| > *
| > * The default values and order for Rank are:
| > * Ace, Two through Ten inclusive, Jack, Queen, King.
| > *
| > * @author jeff
| > *
| > */
| > public interface Rank extends Comparable<Rank> {
| >
| > }
| >
| For a more universal appeal the restriction to 13 may be relaxed.

I was wondering what happened to the Jokers in the pack ;)
--
David Postill
Dance your Life - Biodanza in Alkmaar, Holland - <http://www.danceyourlife.eu>

Eric Sosman

unread,
Aug 4, 2014, 8:14:17 AM8/4/14
to
On 8/3/2014 5:19 PM, Jeff Higgins wrote:
> On 08/03/2014 04:49 PM, Eric Sosman wrote:
>> On 8/3/2014 3:26 PM, Arne Vajh�j wrote:
>>> [...]
>>> I must admit that I can not follow you.
>>>
>>> The fact that different games may use a different ordering is
>>> not an argument against Comparable<>.
>>>
>>> Comparable<> is not the one and only ordering. Comparable<> is
>>> just the natural ordering. It is perfectly valid to have a
>>> Comparable<> with the natural ordering and a bunch of
>>> Comparator<> to handle the context specific orderings.
>>
>> Although one could select different Comparators for different
>> games -- one for Ace-low, say, and another for Ace-high -- there
>> is no way a Comparator could work for "Ace-either" games like Poker
>> (and certainly not for "Ace-both" games like high-low Poker!). Like
>> Comparable, Comparator reflects a _total ordering_ on the objects it
>> compares, and a total ordering must be transitive:
>>
>> If X < Y and Y < Z then X < Z, for all X,Y,Z.
>>
>> In Poker, one can have
>>
>> Ace < Five and Five < Ten but Ten < Ace
>>
>> ... violating transitivity, so the ranks do not follow a total order.
>
> In my proposed interface Ace is a valid Rank but Five and Five is not.

What rank, then, does the Five of Spades have?

> In my proposed interface I cannot see where any contract is broken by
> run time variation of the natural ordering of the Rank. Sure, comparing
> one Rank object at different times or places and getting different
> results might seem odd but not wrong. I may be though. Please correct
> me if this is the case.

See the Javadoc for Comparable. The very first sentence reads:

"This interface imposes a total ordering on the objects of each
class that implements it."

The Javadoc for Comparator begins with a sentence fragment rather than
with a sentence, but that fragment reads:

"A comparison function, which imposes a _total ordering_ on some
collection of objects."

Observe further that both interfaces expose the imposed total order
by way of pairwise comparisons; neither interface has a method to sort
N objects (much less "all" objects) simultaneously. Therefore, when we
try to investigate the imposed total order we must do so by comparing
one pair at a time. So: We discover X < Y *now* and Y < Z *next*, and
by virtue of the total order we can conclude X < Z *hereafter*. We
don't even need to make the comparison; we already know the answer --
*if* there's a total ordering. If we make the comparison anyhow and
discover Z < X we must conclude that there is *not* a total ordering,
and that the Comparable or Comparator does not behave as advertised.

Lest you think this is all "theoretical" or something, consider how
Arrays.binarySearch() works: It compares the sought key S to some object
in the array, discovers S < X, and eliminates all elements >= X from
further consideration. Is it justified in eliminating those elements?
Only if the total ordering holds.

If you don't like arrays and prefer collections, consider TreeMap:
Can you explain how a TreeMap could work in the absence of a total
ordering? Or how it could work if the ordering were somehow changed
*after* some affected keys had already been inserted? "Ah, the sought
key compares greater than the key of the root node, so I'll follow the
right branch of the tree -- oh, wait, maybe I should follow both
branches, just in case the ordering has changed ..."

One could (as Arne Vajh�j pointed out) implement Comparable anyhow
for Ranks, Suits, Cards, and Hands, and one could implement it in a way
that satisfies all Java's expectations. But such Comparables would not
be able to capture the rules of popular card games, because those rules
do not always admit of a total ordering. I do not deny that Comparable
could be implemented, but I maintain that

> Your Card class will be more easily used if it implement the
> java.lang.Comparable<T> interface

is false for many card games.

--
eso...@comcast-dot-net.invalid

Martin Gregorie

unread,
Aug 4, 2014, 9:00:20 AM8/4/14
to
On Sun, 03 Aug 2014 15:54:52 -0700, Roedy Green wrote:

> On Sat, 2 Aug 2014 10:19:42 +0000 (UTC), Martin Gregorie
> <mar...@address-in-sig.invalid> wrote, quoted or indirectly quoted
> someone who said :
>
>
>>In Java the indices of an array start to zero, not 1. Assuming that they
>>start from 1, as you've done, will almost certainly cause problems at
>>runtime by throwing "index out of range" exceptions.
>
> http://mindprod.com/jgloss/pseudorandom.html
>
> I scanned the page, but I could not find an example where your comment
> applies. I showed you how to generate a random number in the bounds low
> .. high, but other than that all the others start at 0.
>
> Could you please give me the context of the error, or perhaps you were
> referring to something OP or another poster said.
>
Looking at the double loop scanning suits and card ranks (both 1-based)
and using these ranges to control array filling made my teeth itch. OK,
he generated the deck index separately, but it just struck me as a bad
practice to get used to when you're using languages like C or Java with a
fixed zero lower bound for arrays.

BTW: there's another Java flaw that nobody has yet mentioned: why is
there a primitive array type, especially now we have generics? Surely an
array should be an object containing the element list as well as the
upper and lower bounds. It should also provide methods that return the
bounds: the ability to set array bounds to suit the natural index range
of the data in the array is very helpful for writing clear code.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Chris Uppal

unread,
Aug 4, 2014, 3:32:29 PM8/4/14
to
Arne Vajh�j wrote:

> So maybe a game need something more advanced than a Comparator<>, but
> that does still not show that a Card class should not be
> Comparable<>.

How about: "Because making it easier to get things wrong than to get things
right is rarely a good idea" ?

-- chris


Jeff Higgins

unread,
Aug 4, 2014, 8:03:04 PM8/4/14
to
On 08/04/2014 08:14 AM, Eric Sosman wrote:
> On 8/3/2014 5:19 PM, Jeff Higgins wrote:
>> On 08/03/2014 04:49 PM, Eric Sosman wrote:
>>> On 8/3/2014 3:26 PM, Arne Vajh�j wrote:
>>>> [...]
>>>> I must admit that I can not follow you.
>>>>
>>>> The fact that different games may use a different ordering is
>>>> not an argument against Comparable<>.
>>>>
>>>> Comparable<> is not the one and only ordering. Comparable<> is
>>>> just the natural ordering. It is perfectly valid to have a
>>>> Comparable<> with the natural ordering and a bunch of
>>>> Comparator<> to handle the context specific orderings.
>>>
>>> Although one could select different Comparators for different
>>> games -- one for Ace-low, say, and another for Ace-high -- there
>>> is no way a Comparator could work for "Ace-either" games like Poker
>>> (and certainly not for "Ace-both" games like high-low Poker!). Like
>>> Comparable, Comparator reflects a _total ordering_ on the objects it
>>> compares, and a total ordering must be transitive:
>>>
>>> If X < Y and Y < Z then X < Z, for all X,Y,Z.
>>>
>>> In Poker, one can have
>>>
>>> Ace < Five and Five < Ten but Ten < Ace
>>>
>>> ... violating transitivity, so the ranks do not follow a total order.
>>
>> In my proposed interface Ace is a valid Rank but Five and Five is not.
>
> What rank, then, does the Five of Spades have?

Does the word Rank connote a hand of cards to you?
Or that the Rank of a Card has the two attributes,
face value and suit? For me the rank(Rank) of a Card
is its face value, Ace, Two - Ten, Jack, Queen, King.

Have you looked at the interfaces I've proposed?
I will reproduce them below for reference.
I'm not especially proud of the wording of some of the Javadoc comments,
but we can leave that for later.

The Five of Spades would be a Card.
A Card has a Comparable<Rank> Rank(its face value),
and a Comparable<Suit> Suit,(its Suit)
so in this case its Rank is Five and Suit is Spades.

In my card game, which I haven't produced, much less tested,
I ask to compare two Cards: my Cards compareTo calls its Ranks
compareTo method which looks in the rule book and discovers
that at this point in this particular game your Five is greater
than my Four, Cards compareTo then calls its Suits compareTo
which determines that at this point your Spades is greater than
my Club, Cards compareTo then looks in the rule book and determines
that at this moment in this game my Card is greater than your Card.
Since this is my one card one hand game I win.

Nowhere have I described a Comparable Hand of cards - which seems to
me to to be what you are arguing about - or a Game of Cards

[snip]

> > Your Card class will be more easily used if it implement the
> > java.lang.Comparable<T> interface

This statement may very well be wrong because
Scott's Card class is not Jeff's Card class.
But not because of some total ordering that
Comparable requires.
If you consider that weaseling - so be it.

>
> is false for many card games.


package scratch;

/**
* The face value of a {@link Card}.
*
* Rank specifies one of 13 distinct,
* implementation defined values and their order.
*
* The default values and order for Rank are:
* Ace, Two through Ten inclusive, Jack, Queen, King.
*
* @author jeff
*
*/
public interface Rank extends Comparable<Rank> {

}

package scratch;

/**
* The suit of a {@link Card}.
*
* Suit specifies one of an implementation defined
* number of distinct values and their order(if any).
*
* The default values and their order(highest to lowest)
* for Suit are: Spades, Hearts, Diamonds, Clubs.
*
* @author jeff
*
*/
public interface Suit extends Comparable<Suit> {

}

package scratch;

/**
* A playing card.
*
* @author jeff
*
*/
public interface Card extends Comparable<Card> {

/**
* Returns one of the 13 distinct values represented
* in the implementation of the {@link Rank} interface.
*
* @return the Rank of this Card.
*/
Rank getRank();

/**
* Returns one of the distinct values represented
* in the implementation of the {@link Suit} interface.
*
* @return the Suit of this Card.
*/
Suit getSuit();

}

package scratch;

/**
* An ordered set of playing {@link Card}s.
*
* @author jeff
*
*/
public interface Deck extends Iterable<Card> {

}

Jeff Higgins

unread,
Aug 4, 2014, 8:29:36 PM8/4/14
to
On 08/04/2014 08:03 PM, Jeff Higgins wrote:
Ah. Now I see the problem.
"This interface is a member of the Java Collections Framework."
It's sacrosanct. Not to used for mundane comparisons - especially
when one might violate the terms of use. If I had used my JComparable
all of this lathering could have been avoided. And the potential
for disaster by someone inadvertently placing my Rank in a TreeMap also.

Roedy Green

unread,
Aug 4, 2014, 9:43:12 PM8/4/14
to
On Fri, 01 Aug 2014 18:16:33 -0700, Scott Dunning
<scot...@gmail.com> wrote, quoted or indirectly quoted someone who
said :

>Here are the directions...
>Design and implement a class called Card that represents a standard
>playing card.

See http://mindprod.com/jgloss/homework.html

There is no doubt most of the people in this forum could solve this
problem in their sleep. But solving the problem is not the task. The
goal is to improve your skill level.

Chris Uppal

unread,
Aug 5, 2014, 6:19:57 AM8/5/14
to
Roedy Green wrote:
> On Fri, 01 Aug 2014 18:16:33 -0700, Scott Dunning
> <scot...@gmail.com> wrote, quoted or indirectly quoted someone who
> said :
>
> > Here are the directions...
> > Design and implement a class called Card that represents a standard
> > playing card.
>
> See http://mindprod.com/jgloss/homework.html
>
> There is no doubt most of the people in this forum could solve this
> problem in their sleep. But solving the problem is not the task. The
> goal is to improve your skill level.

I take it that you have read neither the rest of Scott's post, not the
subsequence discussion.

-- chris


Chris Uppal

unread,
Aug 5, 2014, 6:28:50 AM8/5/14
to
I wrote:

> I take it that you have read neither the rest of Scott's post, not the
> subsequence discussion.

Sorry: spellchecker.

I take it that you have read neither the rest of Scott's post, nor the
subsequent discussion.

-- chris


Arne Vajhøj

unread,
Aug 19, 2014, 5:45:46 PM8/19/14
to
You think that because Card is Comparable<> then people would mess up
the core game logic of comparing hands?

I am not so worried about that. That is one thing that will typical
be very well-defined in the game rules.

Arne


Arne Vajhøj

unread,
Aug 19, 2014, 5:48:58 PM8/19/14
to
On 8/4/2014 9:00 AM, Martin Gregorie wrote:
> BTW: there's another Java flaw that nobody has yet mentioned: why is
> there a primitive array type, especially now we have generics? Surely an
> array should be an object containing the element list as well as the
> upper and lower bounds.

To some extent it is.

It is an object.
It contains elements.
Lower bound is always 0.
x.length-1 gives upper bound

> It should also provide methods that return the
> bounds: the ability to set array bounds to suit the natural index range
> of the data in the array is very helpful for writing clear code.

I agree.

Pascal/Modula-2/Ada has it.

But the idea never caught on in the C/C++/Java/C# world.

I think Java should have had it. It really helps making
the language even stronger type safe.

But too late now.

Arne


Chris Uppal

unread,
Aug 20, 2014, 5:48:15 AM8/20/14
to
Arne Vajh�j wrote:

> > It should also provide [..]
> > the ability to set array bounds to suit the natural index range
> > of the data in the array is very helpful for writing clear code.
>
> I agree.
>
> Pascal/Modula-2/Ada has it.

Didn't Wirth state that, in retrospect, it had been a mistake in Pascal ? And
(I thought) he'd removed it in Modula2 (or maybe it was some later iteration of
"The Wirth Language") ?

> But the idea never caught on in the C/C++/Java/C# world.

I think the reasoning (which I agree with) is that having only one form for
loops over an array makes off-by-one errors less likely, since there's only a
single idiom to remember.

Of course, explicitly looping over an array is not something you usually want
to do these days.

-- chris


Chris Uppal

unread,
Aug 20, 2014, 5:50:38 AM8/20/14
to
Arne Vajh�j wrote:

> > How about: "Because making it easier to get things wrong than to get
> > things right is rarely a good idea" ?
>
> You think that because Card is Comparable<> then people would mess up
> the core game logic of comparing hands?
>
> I am not so worried about that. That is one thing that will typical
> be very well-defined in the game rules.

What I'd expect to see is people attempting to use the Comparable<> interface
regardless of the game rules. And then patching their logic with ad-hoc
special cases when they realised that the pre-defined Comparable<> didn't do
exactly what the rules require.

Better not to set traps for the unwary.

-- chris


Brixomatic

unread,
Aug 31, 2014, 4:17:45 AM8/31/14
to
In article <Jd6dnaYWEdDi7WnO...@bt.com>, Chris Uppal
(chris...@metagnostic.REMOVE-THIS.org) says...

> > You think that because Card is Comparable<> then people would mess up
> > the core game logic of comparing hands?
>
> What I'd expect to see is people attempting to use the Comparable<> interface
> regardless of the game rules. And then patching their logic with ad-hoc
> special cases when they realised that the pre-defined Comparable<> didn't do
> exactly what the rules require.
>
> Better not to set traps for the unwary.

Better not use Comparable at all. Put a Comparator implementation in sme
public final field and use that instead, always.

While overriding hashCode and equals is often beneficial and correct, I
find that implementing Comparable is often a mistake.

I've hat it numerous times that I ran into problems because some people
implemented Comparable for some special purpose (like "sorting by
name"), but did not implement equals and hashCode accordingly, because
that would have messed up the rest (like equals was "equality by ID" or
"all fields equal" and that must not be changed). What you end up with
is objects that are equal according to "compareTo", but not equal
according to "equals" and "hashCode".

And correcting that mistake later is a pain in the butt:
Try to find all arrays, lists, sets and other usages, where this class
of objects might end up, search where these may be sorted or comparedto
use a Comparator object instead.

Sure, you might run your test suite and set a breakpoint in the
comparable implementation, but that will only take you so far as your
test suite goes and let's be real: most programs have a rather lousy
unit test coverage.

To put it with Glenn Danzig's words: "Do you want to cross that line?
Cause it's a long way back from hell, and you don't want to go with me."

Kind regards,
Wanja

--
..Alesi's problem was that the back of the car was jumping up and down
dangerously - and I can assure you from having been teammate to
Jean Alesi and knowing what kind of cars that he can pull up with,
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

lipska the kat

unread,
Aug 31, 2014, 12:31:38 PM8/31/14
to
On 02/08/14 02:16, Scott Dunning wrote:
> Hello, I have an assignment for my summer class. FYI, I'm super new to
> programming in general and this is my first time with java and it's a
> summer class so it's going super fast (please be nice!) lol.
<snip>

Seeing as this thread just won't die I thought I'd offer the following.
It's just a bit of fun

I particularly like the shuffle method.

Go ahead, do your worst :-)

package cards.allinone;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;


enum Suit {
HERTS, CLUBS, DIAMONDS, SPADES
};

enum Rank {
ACE, KING, QUEEN, JACK, TEN, NINE, EIGHT, SEVEN, SIX, FIVE, FOUR,
THREE, TWO
};

class Card {

private final Rank rank;
private final Suit suit;

public Card(Rank rank, Suit suit) {
this.rank = rank;
this.suit = suit;
}

public Rank getRank() {
return rank;
}

public Suit getSuit() {
return suit;
}
}

class Deck {

private Stack<Card> cards = new Stack<>();

public Deck() {
for(Suit suit: Suit.values()){
for(Rank rank: Rank.values()){
cards.push(new Card(rank, suit));
}
}
}

public void printDeck(){
for(Card card: cards){
System.out.println(card.getRank() + " of " + card.getSuit());
}
}

public Boolean moreCards(){
return !cards.empty();
}

public Card nextCard(){
return cards.pop();
}

public void shuffle(){
Collections.shuffle(cards);
}
}

class Hand {

private List<Card> cards = null;

public Hand() {
cards = new ArrayList<>();
}

public void addCard(Card card){
cards.add(card);
}

public Card getCard(int index){
return cards.get(index);
}

public void printHand(){
for(int i = 0; i < cards.size(); i++){
System.out.println("card " + i + ":" + cards.get(i).getRank() + " of
" + cards.get(i).getSuit());
}
}
}

public class CardGame {

private Deck deck = null;
private Map<Integer, Hand> players = null;

public CardGame() {
deck = new Deck();
deck.shuffle();
players = new HashMap<>();
}

public void deal(int hands, int cardsPerHand){
for(int i = 0; i < hands; i++){
players.put(i, new Hand());
}

for(int i = 0; i < cardsPerHand; i++){
for(int j = 0; j < hands; j++){
players.get(j).addCard(deck.nextCard());
}
}
}

public void printHands(){
for(Integer key: players.keySet()){
System.out.println("Player " + key + " hand:");
players.get(key).printHand();
System.out.println("----------");
}
}

public void play(){
//?
}

public static void main(String[] args) {
CardGame game = new CardGame();
game.deal(4, 7);
game.printHands();
}
}



--
lipska the kat - treacherous feline.
Proudly nominated for IPOTY 2014 - LIGAF
GNU/Linux user #560883 - linuxcounter.net

Chris Uppal

unread,
Sep 4, 2014, 10:13:05 AM9/4/14
to
Brixomatic wrote:
> In article <Jd6dnaYWEdDi7WnO...@bt.com>, Chris Uppal
> (chris...@metagnostic.REMOVE-THIS.org) says...
>
> > > You think that because Card is Comparable<> then people would mess up
> > > the core game logic of comparing hands?
> >
> > What I'd expect to see is people attempting to use the Comparable<>
> > interface regardless of the game rules. And then patching their logic
> > with ad-hoc special cases when they realised that the pre-defined
> > Comparable<> didn't do exactly what the rules require.
> >
> > Better not to set traps for the unwary.
>
> Better not use Comparable at all. Put a Comparator implementation in sme
> public final field and use that instead, always.

Yes. Or a bunch of 'em for commonly occurring situation (Ace high, Ace low,
...). Though I'd be inclined to skip the predefined interfaces altogether
(for cards) since the comparison is more likely to be between /hands/.


> While overriding hashCode and equals is often beneficial and correct, I
> find that implementing Comparable is often a mistake.
>
> I've hat it numerous times that I ran into problems because some people
> implemented Comparable for some special purpose (like "sorting by
> name"), but did not implement equals and hashCode accordingly, because
> that would have messed up the rest (like equals was "equality by ID" or
> "all fields equal" and that must not be changed). What you end up with
> is objects that are equal according to "compareTo", but not equal
> according to "equals" and "hashCode".

That makes sense.

-- chris


Eric Sosman

unread,
Sep 4, 2014, 10:55:35 AM9/4/14
to
On 9/4/2014 10:14 AM, Chris Uppal wrote:
> [... about Comparable/Comparator for Cards ...]
>
> Yes. Or a bunch of 'em for commonly occurring situation (Ace high, Ace low,
> ...). Though I'd be inclined to skip the predefined interfaces altogether
> (for cards) since the comparison is more likely to be between /hands/.

It depends on the game at, er, hand. There's been much mention
of Poker in this thread, a game in which hands are in fact compared
(but not in a way Comparable/Comparator can always model). But games
like Bridge do not compare hands, though they compare cards.

... and the comparison is not amenable to Comparable. For example,
if the Ace of Spades, King of Spades, seven of Clubs, and four of Hearts
are played to one trick, which card ranks the highest? We can infer
that it's not the King of Spades, but any of the other three cards might
be the one that takes the trick:

- The Ace wins if either it or the King was led first and neither
Hearts nor Clubs are trumps, or if Spades are trumps,

- The seven wins if Clubs are trumps, or if it was led first and
neither Spades nor Hearts are trumps,

- The seven wins if Hearts are trumps, or if it was led first and
neither Spades nor Clubs are trumps.

To implement this properly, I think you'd need a suite of different
Comparators: One for each possible first-led suit, and one for each
possible choice of trump suit. (Some economies are possible: The
Comparator for a no-trump contract with a Spade lead would give the
same result as that for a Spades contract with a spade lead, so I think
you'd only need sixteen different Comparators, not twenty.)

Tomorrow, we'll discuss Slap-Jack. ;-)

--
eso...@comcast-dot-net.invalid

Chris Uppal

unread,
Sep 4, 2014, 11:16:10 AM9/4/14
to
Eric Sosman wrote:
> On 9/4/2014 10:14 AM, Chris Uppal wrote:
> > [... about Comparable/Comparator for Cards ...]
> >
> > Yes. Or a bunch of 'em for commonly occurring situation (Ace high, Ace
> > low, ...). Though I'd be inclined to skip the predefined interfaces
> > altogether (for cards) since the comparison is more likely to be
> > between /hands/.
>
> It depends on the game at, er, hand. There's been much mention
> of Poker in this thread, a game in which hands are in fact compared
> (but not in a way Comparable/Comparator can always model). But games
> like Bridge do not compare hands, though they compare cards.

True. Or at least, I shall happily take your word for it -- I have never been
able to make any sense at all of Bridge[*].

And there are games where comparison, as such, doesn't come into it at all
(Cheat is the example I'm thinking of -- one of the few card games I have ever
enjoyed playing and felt I truly understood :-).

-- chris

[*] Always feels an axiom system with some of the axioms missing.


Eric Sosman

unread,
Sep 4, 2014, 3:05:58 PM9/4/14
to
On 9/4/2014 11:12 AM, Chris Uppal wrote:
> Eric Sosman wrote:
>> [...]
>> It depends on the game at, er, hand. There's been much mention
>> of Poker in this thread, a game in which hands are in fact compared
>> (but not in a way Comparable/Comparator can always model). But games
>> like Bridge do not compare hands, though they compare cards.
>
> True. Or at least, I shall happily take your word for it -- I have never been
> able to make any sense at all of Bridge[*].
>
> And there are games where comparison, as such, doesn't come into it at all
> (Cheat is the example I'm thinking of -- one of the few card games I have ever
> enjoyed playing and felt I truly understood :-).
>
> [*] Always feels an axiom system with some of the axioms missing.

Bridge is a lot like Java: The fundamentals are simple, but
nobody understands the class libraries.

--
eso...@comcast-dot-net.invalid

Gene Wirchenko

unread,
Sep 5, 2014, 1:03:40 PM9/5/14
to
On Thu, 04 Sep 2014 10:55:18 -0400, Eric Sosman
<eso...@comcast-dot-net.invalid> wrote:

>On 9/4/2014 10:14 AM, Chris Uppal wrote:
>> [... about Comparable/Comparator for Cards ...]
>>
>> Yes. Or a bunch of 'em for commonly occurring situation (Ace high, Ace low,
>> ...). Though I'd be inclined to skip the predefined interfaces altogether
>> (for cards) since the comparison is more likely to be between /hands/.
>
> It depends on the game at, er, hand. There's been much mention
>of Poker in this thread, a game in which hands are in fact compared
>(but not in a way Comparable/Comparator can always model). But games
>like Bridge do not compare hands, though they compare cards.
>
> ... and the comparison is not amenable to Comparable. For example,
>if the Ace of Spades, King of Spades, seven of Clubs, and four of Hearts
>are played to one trick, which card ranks the highest? We can infer
>that it's not the King of Spades, but any of the other three cards might
>be the one that takes the trick:

Poker with wild cards would be another fun one to try. And after
determining that two hands are the same with regard to what card
values have been assigned to the wild cards, then you have to count
wild cards as the fewer wild cards, the higher the hand ranks.

[snip]

Sincerely,

Gene Wirchenko

Arne Vajhøj

unread,
Sep 7, 2014, 9:42:25 PM9/7/14
to
On 8/20/2014 5:48 AM, Chris Uppal wrote:
> Arne Vajhøj wrote:
>>> It should also provide [..]
>>> the ability to set array bounds to suit the natural index range
>>> of the data in the array is very helpful for writing clear code.
>>
>> I agree.
>>
>> Pascal/Modula-2/Ada has it.
>
> Didn't Wirth state that, in retrospect, it had been a mistake in Pascal ? And
> (I thought) he'd removed it in Modula2

No.

> (or maybe it was some later iteration of
> "The Wirth Language") ?

It was dropped in Oberon.

>> But the idea never caught on in the C/C++/Java/C# world.
>
> I think the reasoning (which I agree with) is that having only one form for
> loops over an array makes off-by-one errors less likely, since there's only a
> single idiom to remember.

I am very skeptical about a claim that using the natural indexes would
increase off-by-one errors, that goes against the philosophy in
programming language design about modelling the code as closely to
the real world as possible.

And it is certainly not true for Ada where the compiler rather
aggressively enforces type safety.

> Of course, explicitly looping over an array is not something you usually want
> to do these days.

It still happens quite often. I would tend to think that it is about
50%-50% now. There are simply too many cases where for each concept
is not suited.

Arne


Arne Vajhøj

unread,
Sep 7, 2014, 9:45:30 PM9/7/14
to
On 8/20/2014 5:50 AM, Chris Uppal wrote:
Avoid adding stuff that could be used wrong seems as a hopeless
strategy to me.

Arne


Eric Sosman

unread,
Sep 7, 2014, 10:04:49 PM9/7/14
to
On 8/20/2014 5:48 AM, Chris Uppal wrote:
>[...]
> Of course, explicitly looping over an array is not something you usually want
> to do these days.

???!

When was the array deprecated?

When was iteration over an array's elements deprecated?

When were arrays with more "slots" than "active elements"
deprecated?

When did we all go stark raving MAD?????

--
eso...@comcast-dot-net.invalid

Arne Vajhøj

unread,
Sep 7, 2014, 10:08:34 PM9/7/14
to
I will not rule out that we are all stark raving mad.

:-)

But traditional for loop to go through arrays is not deprecated.

If one only need to read the elements *and* one need to read all
elements *and* one does not need to know the index, then a new
for loop is probably better.

But that was a whole bunch of if's. Which are not always true.

Arne



Eric Sosman

unread,
Sep 7, 2014, 10:14:02 PM9/7/14
to
Avoiding stuff that is seldom right seems worth while, though.

--
eso...@comcast-dot-net.invalid
0 new messages