import java.lang.*;
import java.io.*;
import java.util.*;
public class BlackJackApp {
public static void main(String args[]) throws IOException,NullPointerException
{
BlackJackGame game=new BlackJackGame();
game.play();
}
}
class BlackJackGame {
int bet;
int money;
String s=null;
Deck deck;
Hand playersHand;
Hand dealersHand;
BufferedReader keyboardInput;
public BlackJackGame() {
bet=0;
money=1000;
deck=new Deck();
//DataInputStream keyboardInput=new DataInputStream(System.in);
BufferedReader keyboardInput = new BufferedReader(new InputStreamReader(System.in));
System.out.println("-------------------------------------");
System.out.println(keyboardInput);
}
void play() throws IOException,NullPointerException {
System.out.println("Welcome to BlackJack!");
System.out.println("You have $"+Integer.toString(money)+".");
do {
placeBet();
if(bet>0) {
initialDeal();
if(playersHand.blackJack()) playerWins();
else {
while(playersHand.under(22)&&playerTakesAHit()) {
playersHand.addCard(deck.deal());
         playersHand.show(false,false);
}
while(dealersHand.mustHit())
dealersHand.addCard(deck.deal());
dealersHand.show(true,false);
showResults();
}
}
} while(bet>0);
}
void placeBet() throws IOException,NumberFormatException,NullPointerException {
DataInputStream keyboards=new DataInputStream(System.in);
do {
System.out.println("Enter bet");
System.out.flush();
s=keyboards.readLine();//这儿不鼓励使用了API怎么办
bet=Integer.parseInt(s);
} while(bet<0||bet>money);
}
void initialDeal() {
System.out.println("New Hand:");
playersHand=new Hand();
dealersHand=new Hand();
for(int i=0;i<2;++i) {
playersHand.addCard(deck.deal());
dealersHand.addCard(deck.deal());
}
dealersHand.show(true,true);
playersHand.show(false,false);
}
void playerWins() {
money+=bet;
System.out.println("Player win $"+Integer.toString(bet)+".");
System.out.println("Player has $"+Integer.toString(money)+".");
}
void dealerWins() {
money-=bet;
System.out.println("Players loses $"+Integer.toString(bet)+".");
System.out.println("players has $"+Integer.toString(money)+".");
}
void tie() {
System.out.println("tie");
System.out.println("player has"+Integer.toString(money)+".");
}
boolean playerTakesAHit() throws IOException {
char ch=' ';
do {
System.out.println("Hit or Stay");
System.out.flush();
String playersDecision=null;
keyboardInput=new BufferedReader(new InputStreamReader(System.in));
playersDecision=keyboardInput.readLine();//这儿不鼓励使用了API怎么办?
try { ch=playersDecision.charAt(0);}
catch (StringIndexOutOfBoundsException e){};
if(ch=='h'||ch=='H') return true;
if(ch=='s'||ch=='S') return false;
} while (true);
}
void showResults() {
if(playersHand.busted()) dealerWins();
else if(dealersHand.busted()) playerWins();
else if(playersHand.bestScore()>dealersHand.bestScore()) playerWins();
else if(playersHand.bestScore()<dealersHand.bestScore()) dealerWins();
else tie();
}
}
class Deck {
int cards[];
int topCard;
Random random;
public Deck() {
cards=new int[52];
for(int i=0;i<52;++i) 
cards[i]=i;
topCard=0;
random=new Random();
Shuffle();
}
public void Shuffle() {
for(int i=0;i<52;++i) {
int j=randomCard();
int k=randomCard();
int temp=cards[j];
cards[j]=cards[k];
cards[k]=temp;
}
}
int randomCard()  {
int r=random.nextInt();
if(r<0) r=0-r;
return r%52;
}
Card deal() {
if(topCard>51) {
Shuffle();
topCard=0;
}
Card card=new Card(cards[topCard]);
++topCard;
return card;
}
}
class Hand {
int numCards;
Card cards[];
static int MaxCards=12;
public Hand() {
numCards=0;
cards=new Card[MaxCards];
}
void addCard(Card c) {
cards[numCards]=c;
++numCards;
}
void show(boolean isDealer,boolean hideFirstCard) {
if(isDealer) System.out.println("Dealer:");
else System.out.println("Player:");
for(int i=0;i<numCards;++i) {
if(i==0&&hideFirstCard) System.out.println("Hidden");
else System.out.println(""+cards[i].value+"of"+cards[i].suit);
}
}
boolean blackJack()  {
if(numCards==2) {
if(cards[0].iValue==1&&cards[1].iValue==10) return true;
if(cards[1].iValue==1&&cards[0].iValue==10) return true;
}
return false;
}
boolean under(int n) {
int points=0;
for(int i=0;i<numCards;++i) points+=cards[i].iValue;
if(points<n) return true;
else return false; }
int bestScore() {
int points=0; boolean haveAce=false;
for(int i=0;i<numCards;++i) {
points+=cards[i].iValue;
if(cards[i].iValue==1) haveAce=true;
}
if(haveAce) {
if(points+10<22) points+=10;
}
return points;
}
boolean mustHit() {
if(bestScore()<11) return true;
else return false;
}
boolean busted() {
if(!under(22)) return true;
else return false;
}
}
class Card {
int iValue;
String value;
String suit;
public Card(int n) {
int isuit=n/13;
iValue=n%13+1;
switch(isuit) {
case 0: suit="Spade";break;
case 1: suit="Hearts";break;
case 2: suit="Clubs";break;
default: suit="Diamonds";
}
if(iValue==1) value="Ace";
else if(iValue==10) value="Ten";
else if(iValue==11) value="Jack";
else if(iValue==12) value="Queen";
else if(iValue==13) value="King";
else value=Integer.toString(iValue);
if(iValue>10) iValue=10;
}
int getValue() {
return iValue;
}
}