Simple Blackjack Game

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;

public class BlackjackCommandLineRunner {
    private Blackjack game;

    public BlackjackCommandLineRunner(Blackjack game) {
        this.game = game;
    }

    public static void main(String[] args) throws IOException {
        Blackjack game = new Blackjack();
        BlackjackCommandLineRunner runner = new BlackjackCommandLineRunner(game);
        runner.play();
    }

    public void play() throws IOException {
        while(true){
            game.playHand();
            if (game.gameOver()) {
                break;
            }

            System.out.println("Dealer has: " + game.dealerCards());
            System.out.println("Player has: " + game.playerCards());
            System.out.print("Would you like another card? (y/n)");
            String hit = getConsoleReader().readLine();
            if(hit.toUpperCase().equals("N")){
                game.setGameOver();
                break;
            }
        }

        System.out.println("Game Over!");
        System.out.println("Dealer's cards: " + game.dealerCards());
        System.out.println("Player's cards: " + game.playerCards());
        System.out.println("Dealer has " + game.dealerScore());
        System.out.println("Player has " + game.playerScore());

        if (game.dealerWins()) {
            System.out.println("Dealer wins!");
        } else {
            System.out.println("Player wins!");
        }
    }

    public BufferedReader getConsoleReader(){
        InputStream is = null;
        InputStreamReader isReader = null;
        BufferedReader bufferedReader = null;

        try{
            is = System.in;
            isReader = new InputStreamReader(is);
            bufferedReader = new BufferedReader(isReader);
        }catch(Exception e){}

        return bufferedReader;
    }
}

/----------------------------------------------------------------------------------

import java.util.Stack;
import java.util.Collections;

public class Blackjack {
    private boolean gameOver = false;
    private Stack deck = new Stack();
    private Stack player = new Stack();
    private Stack dealer = new Stack();

    //--------------- public methods ---------------------

    public Blackjack() {
        populateDeck();
        Collections.shuffle(deck);
    }

    public void playHand() {
        Card playerCard = (Card) deck.pop();
        playerCard.setFaceUp();
        player.push(playerCard);

        if (score(dealer) < 17)
            dealer.push(deck.pop());
    }

    public void setGameOver() {
        gameOver = true;
    }

    public Stack playerCards() {
        return (Stack) player.clone();
    }  

    public Stack dealerCards() {
        if (gameOver()) {
            for (int i = 0; i<dealer.size(); i++) {
                Card c = (Card) dealer.get(i);
                c.setFaceUp();
            }
        }
        return (Stack) dealer.clone();
    }

    public int playerScore() {
        return score(player);
    }

    public int dealerScore() {
        return score(dealer);
    }

    public boolean dealerWins() {
        if (playerScore() > 21)
            return true;
        else if (dealerScore() > 21)
            return false
        else
            return dealerScore() >= playerScore();
    }

    public boolean gameOver() {
        return deck.isEmpty() || playerScore() > 21 || gameOver;
    }

    //--------------- private methods ---------------------

    private void populateDeck() {
        for(int suit = 0; suit<4; suit++){
            for(int rank = 2; rank <15; rank++){
                Card c = new Card(suit, rank);
                deck.push(c);
            }
        }
    }

    private int score(Stack s){
        int score = 0;

        for(int i=0; i<s.size(); i++){
            int rank = 0;
            Card c = (Card)s.elementAt(i);
            rank = c.getRank();

            if(rank >= Card.TWO && rank <= Card.JACK){
                score += rank;
            }
            else if (rank > Card.JACK && rank<Card.ACE){
                score += 10;
            }
            else {
                if (score > 10){
                    score += 1;
                } else {
                    score += 11;
                }
            }

        }

        return score;
    }
}

/----------------------------------------------------------------------------------

public class Card {

    //suit constants
    public static final int CLUBS = 0;
    public static final int DIAMONDS = 1;
    public static final int HEARTS = 2;
    public static final int SPADES = 3;

    //rank constants
    public static final int TWO = 2;
    public static final int THREE = 3;
    public static final int FOUR = 4;
    public static final int FIVE = 5;
    public static final int SIX = 6;
    public static final int SEVEN = 7;
    public static final int EIGHT = 8;
    public static final int NINE = 9;
    public static final int TEN = 10;
    public static final int JACK = 11;
    public static final int QUEEN = 12;
    public static final int KING = 13;
    public static final int ACE = 14;

    private int suit;
    private int rank;
    private boolean isFaceUp = false;

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

    public Card(int suit, int rank, boolean isFaceUp) {
        this(suit, rank);
        this.isFaceUp = isFaceUp;
    }

    public int getSuit() {
        return suit;
    }

    public int getRank() {
        return rank;
    }

    public boolean isFaceUp() {
        return isFaceUp;
    }

    public void setFaceUp() {
        isFaceUp = true;
    }

    public void setFaceDown() {
        isFaceUp = false;
    }

    public String toString() {
        if (!isFaceUp)
            return "*";

        String[] suitsAsStrings = new String[4];
        suitsAsStrings[CLUBS] = "C";
        suitsAsStrings[DIAMONDS] = "D";
        suitsAsStrings[HEARTS] = "H";
        suitsAsStrings[SPADES] = "S";

        String rankAsString = String.valueOf(rank);
        switch (rank) {
            case (11):
                rankAsString = "J";
                break;
            case (12):
                rankAsString = "Q";
                break;
            case (13):
                rankAsString = "K";
                break;
            case (14):
                rankAsString = "A";
                break;
        }

        return rankAsString + suitsAsStrings[suit];
    }

    //when you override the equals method, you should also override hashCode
    public boolean equals(Object obj) {
        Card anotherCard = (Card) obj;

        if (getSuit() == anotherCard.getSuit()
                && getRank() == anotherCard.getRank())
            return  true;
        else
            return false;
    }

    private transient final static String UNIQUE_OBJECT = new String();
    public int hashCode() {
        String cardValue = String.valueOf(getSuit()) + getRank() + Card.UNIQUE_OBJECT.hashCode();
        return cardValue.hashCode();
    }
}