Card.java
class Card { int rank; String suit; public Card(int r, String s) { rank = r; suit = s; } public boolean higher(Card c) { return rank > c.rank; } public boolean lower(Card c) { return rank < c.rank; } public String toString() { return rank + " of " + suit; } }
Deck.java
(Version A)import java.util.Random; class Deck { Card[] cards; public Deck() { String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"}; cards = new Card[52]; int indexOfNextCard = 0; for (int i = 0; i < suits.length; i = i + 1) { for (int j = 1; j < 14; j = j + 1) { cards[indexOfNextCard] = new Card(j, suits[i]); indexOfNextCard = indexOfNextCard + 1; } } } public void shuffle() { Random randy = new Random(); for (int i = 0; i < cards.length; i = i + 1) { int j = randy.nextInt(cards.length); Card temp = cards[i]; cards[i] = cards[j]; cards[j] = temp; } } public Card deal() { Card c = cards[cards.length - 1]; Card[] all_but_last = new Card[cards.length - 1]; for (int i = 0; i < all_but_last.length; i= i + 1) { all_but_last[i] = cards[i]; } cards = all_but_last; return c; } }
Deck
Deck
that gives
a much more efficient implementation of the deal
method
deal
does little more than subtract 1 from the indexshuffle
Deck.java
(Version C)import java.util.Random; class Deck { Card[] cards; int indexOfLastCard; public Deck() { String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"}; cards = new Card[52]; int indexOfNextCard = 0; for (int i = 0; i < suits.length; i = i + 1) { for (int j = 1; j < 14; j = j + 1) { cards[indexOfNextCard] = new Card(j, suits[i]); indexOfNextCard = indexOfNextCard + 1; } } indexOfLastCard = 51; } public void shuffle() { Random randy = new Random(); for (int i = 0; i < indexOfLastCard + 1; i = i + 1) { int j = randy.nextInt(indexOfLastCard + 1); Card temp = cards[i]; cards[i] = cards[j]; cards[j] = temp; } } public Card deal() { Card c = cards[indexOfLastCard]; indexOfLastCard = indexOfLastCard - 1; return c; } }
Deck
class (e.g.
Game
) do not need to be changed
Deck
has changedshuffle
and deal
public
methods
Game.java
import java.util.Scanner; class Game { public void play() { Scanner sc = new Scanner(System.in); int score = 0; Deck d = new Deck(); d.shuffle(); Card currentCard = d.deal(); for (int i = 0; i < 4; i = i + 1) { System.out.print("Will the next card be higher (H) or lower (L) than a " + currentCard + "? "); String guess = sc.nextLine(); Card nextCard = d.deal(); System.out.print("It's a " + nextCard + ". "); if ((guess.equals("L") && nextCard.lower(currentCard)) || (guess.equals("H") && nextCard.higher(currentCard))) { System.out.println("Yes!"); score = score + 1; } else { System.out.println("Bad luck!"); } currentCard = nextCard; } System.out.println("You scored " + score + " out of 4."); } }
Deck
in the 'client' code
on the right:
class Deck { Card[] cards; int indexOfLastCard; public Deck() { // etc. }
class DeckTester { public static void main(String[] args) { Deck d = new Deck(); for (int i = 0; i < d.indexOfLastCard; i = i + 1) { System.out.println(d.cards[i]); } } }
class Deck { Card[] cards; public Deck() { // etc. }
class DeckTester { public static void main(String[] args) { Deck d = new Deck(); for (int i = 0; i < d.cards.length; i = i + 1) { System.out.println(d.cards[i]); } } }
private
private
class Deck { private Card[] cards; private int indexOfLastCard; public Deck() { // etc. }
public
public
,
private
, protected
or default (blank):
public
, the variable is visible to the whole
program – this is totally unacceptable practice!
private
, the variable is visible only within its
class definition – this is the only good practice!
protected
, the variable is visible within this class
definition, within its subclasses (see class hierarchies, later)
and (advanced) in every class definition in the same package –
this is sometimes acceptable
(From Coad, P., Mayfield, M. and Kern, J.: Java Design: Building Better Apps & Applets (2nd edn.), Yourdon Press, 1999)
public
private
class ATM { private String currency; private int[] denominations; private int[] contents; public ATM(String s, int[] denoms) { currency = s; denominations = denoms; contents = new int[denominations.length]; } public String getCurrency() { return currency; } public int getTotal() { int total = 0; for (int i = 0; i < denominations.length; i++) { total = total + denominations[i] * contents[i]; } return total; } public int getQty(int denom) { for (int i = 0; i < denominations.length; i++) { if (denominations[i] == denom) { return contents[i]; } } return 0; } public String toString() { String s = ""; for (int i = 0; i < denominations.length; i++) { s = s + contents[i] + " x " + currency + denominations[i] + "; " ; } return s; } public void load(int qty, int denom) { for (int i = 0; i < denominations.length; i++) { if (denominations[i] == denom) { contents[i] += qty; return; } } } public void dispense(int qty, int denom) { for (int i = 0; i < denominations.length; i++) { if (denominations[i] == denom && contents[i] >= qty) { contents[i] -= qty; return; } } } }
class ATM { private String currency; private int[] denominations; private int[] contents; public ATM(String s, int[] denoms) { currency = s; denominations = denoms; contents = new int[denominations.length]; } public String getCurrency() { return currency; } public int getTotal() { int total = 0; for (int i = 0; i < denominations.length; i++) { total = total + denominations[i] * contents[i]; } return total; } public int getQty(int denom) { int posn = indexOf(denom); if (posn != -1) { return contents[posn]; } else { return 0; } } public String toString() { String s = ""; for (int i = 0; i < denominations.length; i++) { s = s + contents[i] + " x " + currency + denominations[i] + "; " ; } return s; } public void load(int qty, int denom) { int posn = indexOf(denom); if (posn != -1) { contents[posn] += qty; } // else no update } public void dispense(int qty, int denom) { int posn = indexOf(denom); if (posn != -1 && contents[posn] >= qty) { contents[posn] -= qty; } // else no update } private int indexOf(int denom) { for (int i = 0; i < denominations.length; i++) { if (denominations[i] == denom) { return i; } } return -1; } }