import java.applet.*;
import java.awt.*;

import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import java.text.*;
import java.net.*;

public class Omaha extends Applet implements MouseListener, Runnable { 

   /**** Screen constants  ******/
   static final int TinyOFFSET = 5; 
   static final int SmOFFSET = 10; 
   static final int MedOFFSET = 15;
   static final int LgOFFSET = 20; 

   static final int FLOPX = 295;
   static final int FLOPY = 165;
   static final int BUTTONSX = 175;
   static final int BUTTONSY = 385;

   static final int BTNBOTTOM = 397; 
   static final int BTNW = 80; 
   static final int BTNH = 30; 

   static final int CARD = 80; 

   static final int COIN = 30;
   static final int COINX = 255;
   static final int COINY = 200;

   // Where the Button goes
   static final int buttonX[] = {65,198,438,622,672,519,270,120};
   static final int buttonY[] = {150,73,55,107,230,314,325,275};

   // Where the Bets go
   static final int betX[] = {176,302,545,603,578,515,270,130};
   static final int betY[] = {115,60,80,150,230,285,282,225};

   // Where the cards go
   static final int cardX[] = {120, 245, 490, 655, 625, 215, 75};
   static final int cardY[] = {115, 65, 68, 152, 238, 285, 227};

   Player players[] = new Player[8]; 
   static final String names[] = {"ANIL", "JEFF", "ADAM", "JOE", "DICKIE", "YOU", "BILLY", "VINNIE"};

   // the cards and the deal
   static final int CARDS_IN_DECK = 52;
   boolean AvailableCards[] = new boolean[CARDS_IN_DECK]; 
   Card board[] = null;
   Image pics[] = new Image[52];

   String top = "   WELCOME";
   String bottom = "Press START when you're ready";

   // the play
   static final int PREFLOP = 2;
   static final int FLOP = 3;
   static final int TURN = 4;
   static final int RIVER = 5;
   static final int WINNER = 6;

   public final int FOLD = 10;
   public final int CHECK = 20;
   public final int CALL = 30;
   public final int BET = 40;
   public final int RAISE = 50;

   boolean GameInProgress = false;
   boolean HandInProgress = false;
   boolean newRound = false;
   boolean newHand = false;
   boolean choiceMade = false;
   boolean showdown = false;

   MediaTracker tracker = new MediaTracker(this);

   Thread turn = null;
   long interval = 1800;

   int btnPosition = 2;
   boolean blindFlag = true;
   int currentWager = 0;
   int round = PREFLOP;
   int currentPlayer = 0;
   int raises = 0;
   int myraises = 0;
   int pot = 0;

   String displayHigh = "";
   String displayLow = "";

   int boardTrips = 0;
   int boardPair = 0;
   int boardFlush = 0;
   int board3Straight = 0;
   int board4Straight = 0;
   int boardLow[] = new int[5];

   // Set up clicking areas
   Rectangle Fold = new Rectangle(190, BTNBOTTOM, BTNW, BTNH);
   Rectangle Check = new Rectangle(275, BTNBOTTOM, BTNW, BTNH);
   Rectangle Call = new Rectangle(360, BTNBOTTOM, BTNW, BTNH);
   Rectangle Bet = new Rectangle(445, BTNBOTTOM, BTNW, BTNH);
   Rectangle Raise = new Rectangle(530, BTNBOTTOM, BTNW, BTNH);
   Rectangle Start = new Rectangle(650, 10, BTNW, BTNH);

   Font tinyFont = new Font("SansSerif", Font.BOLD, 10);
   Font smallFont = new Font("SansSerif", Font.BOLD, 12);
   Font RegFont = new Font("SansSerif", Font.BOLD, 16);

   public void init() {
	setBackground(Color.pink);
	addMouseListener(this);

	String tempSuits[] = { "C", "D", "S", "H" };
	int cntr = 0;
	URL codeBase = this.getCodeBase();
       for(int x = 0; x < 4; x++) {
          for(int j = 2; j < 15; j++) {
	      String tempName = "Images/" + j + tempSuits[x] + ".gif";
             pics[cntr] = getImage(codeBase, tempName); 
	      cntr++;
	   }
	}
	for(int i = 0; i < names.length; i++) {
	   long l = new Date().getTime() * (i + 1);
	   Random r = new Random(l);
	   int type = Math.abs(r.nextInt()) % 10;
	   players[i] = new Player(names[i], type);
	}
   }

/************************************************************************ 				PAINT METHODS
************************************************************************/ 
   public void update(Graphics g) {
      paint(g);
   }
	
   public void paint(Graphics g) {
	g.setFont(smallFont);
	g.clearRect(0, 0, 750, 450);

	// Add a Start button
	g.setFont(RegFont);
	g.setColor(Color.lightGray);
	g.fill3DRect(650, 10, BTNW, BTNH, true);
	g.setColor(Color.black);
	g.drawRect(650 - 2, 10 - 2, BTNW, BTNH);
	g.drawString("START", 650 + MedOFFSET, 10 + LgOFFSET); 

	// Add the table add the players
	paintTable(g);

	// Add the pot
	if(pot > 0) {
	   paintMoneyLabel(g, 240, COINY + 32, pot);
	   int quarters = pot/25;
	   int startY = COINY;
	   if(quarters > 0) {
		int startX = COINX;
		for(int q = 0; q < quarters; q++) {
		   paintCoin(g, startX, startY, 25);
		   startX -= 15;
		}
		startY -= 20;
	   }
	   int nickels = pot - (25 * quarters);
	   if(nickels > 4) {
		int startX = COINX;
		for(int n = 0; n < nickels/5; n++) {
		   paintCoin(g, startX, startY, 5);
		   startX -= 15;
		}
		startY -= 20;
	   }
	   int pennies = pot % 5;
	   if(pennies > 0) {
		int startX = COINX;
		for(int p = 0; p < pennies; p++) {
		   paintCoin(g, startX, startY, 1);
		   startX -= 15;
		}
	   }
	}
      
	if(GameInProgress) {
	   bottom = "";
	   paintCards(g);
	   paintBoard(g);
	   paintMoney(g);
         if(!HandInProgress) {
	      if(showdown) {
	         for(int i = 0; i < players.length; i++) {
	            if(players[i].In && i != 5) {
		         paintPlayersHand(g, i);
                  }
		   }
	      }
            g.setColor(Color.black);
            g.setFont(RegFont);
            g.drawString(displayHigh, FLOPX - 10, FLOPY - 5);
	      g.drawString(displayLow, FLOPX - 5, 260);
	   }
	}

	if(top.length() > 0 || bottom.length() > 0) {
	   paintYourTurn(g, top, bottom);
	}

	if(currentPlayer == 5 && HandInProgress) {
         if(btnPosition == 3 && round == PREFLOP && currentWager == 3) {
	      paintBigBlindButtons(g);
	   }
	   else {
	      paintBetButtons(g);
	   }
	}
   }

   private void paintBetButtons(Graphics g) {
	g.setColor(Color.black);
	g.fillRect(BUTTONSX, BUTTONSY, 450, 55); 
	g.setColor(Color.cyan);
	g.fillRect(BUTTONSX + 5, BUTTONSY + 5, 440, 45); 

	g.setFont(RegFont);
	
	if(currentWager > 0) {
	   // Fold
	   g.setColor(Color.black);
	   g.fill3DRect(190, BTNBOTTOM, BTNW, BTNH, true);
	   g.setColor(Color.white);
	   g.drawRect(190 - 2, BTNBOTTOM - 2, BTNW, BTNH);
	   g.drawString("FOLD", 187 + LgOFFSET, BTNBOTTOM + LgOFFSET); 

	   // Call
	   g.setColor(Color.black);
	   g.fill3DRect(360, BTNBOTTOM, BTNW, BTNH, true);
	   g.setColor(Color.white);
	   g.drawRect(360 - 2, BTNBOTTOM - 2, BTNW, BTNH);
	   g.drawString("CALL", 357 + LgOFFSET, BTNBOTTOM + LgOFFSET); 

	   if(raises < 3) {
	      // Raise
	      g.setColor(Color.black);
	      g.fill3DRect(530, BTNBOTTOM, BTNW, BTNH, true);
	      g.setColor(Color.white);
	      g.drawRect(530 - 2, BTNBOTTOM - 2, BTNW, BTNH);
	      g.drawString("RAISE", 527 + LgOFFSET, BTNBOTTOM + LgOFFSET); 
         }
 	}
	else {
	   // Check
	   g.setColor(Color.black);
	   g.fill3DRect(275, BTNBOTTOM, BTNW, BTNH, true);
	   g.setColor(Color.white);
	   g.drawRect(275 - 2, BTNBOTTOM - 2, BTNW, BTNH);
	   g.drawString("CHECK", 272 + SmOFFSET, BTNBOTTOM + LgOFFSET); 

    	   // Bet
	   g.setColor(Color.black);
	   g.fill3DRect(445, BTNBOTTOM, BTNW, BTNH, true);
	   g.setColor(Color.white);
	   g.drawRect(445 - 2, BTNBOTTOM - 2, BTNW, BTNH);
	   g.drawString("BET", 445 + LgOFFSET, BTNBOTTOM + LgOFFSET); 
	}
   }

   private void paintBigBlindButtons(Graphics g) {
      g.setColor(Color.black);
	g.fillRect(BUTTONSX + 80, BUTTONSY, 370, 55); 
	g.setColor(Color.cyan);
	g.fillRect(BUTTONSX + 85, BUTTONSY + 5, 360, 45); 

	g.setFont(RegFont);

	// Check
	g.setColor(Color.black);
	g.fill3DRect(275, BTNBOTTOM, BTNW, BTNH, true);
	g.setColor(Color.white);
	g.drawRect(275 - 2, BTNBOTTOM - 2, BTNW, BTNH);
	g.drawString("CHECK", 272 + SmOFFSET, BTNBOTTOM + LgOFFSET); 
	
      // Raise
      g.setColor(Color.black);
      g.fill3DRect(530, BTNBOTTOM, BTNW, BTNH, true);
      g.setColor(Color.white);
      g.drawRect(530 - 2, BTNBOTTOM - 2, BTNW, BTNH);
      g.drawString("RAISE", 527 + LgOFFSET, BTNBOTTOM + LgOFFSET); 
   }

   private void paintBoard(Graphics g) {
      int tempX = FLOPX;
      for(int i = 0; i < 5; i++) {
         if(!board[i].Available) {
	      paintCardBack(g, tempX, FLOPY, 50, BTNW);
	      tempX += 50 + 2;
	   }
	   else {
	      try {
	         tracker.waitForID(2);
	      }	
            catch(InterruptedException e){}
	      g.drawImage(pics[board[i].picIndex], tempX, FLOPY, tempX + CARD, FLOPY + CARD, 0, 0, 100, 100, this);
	      tempX += 55 + 2;
	   }
      }
   }

   private void paintCardBack(Graphics g,int startX,int startY,int cW,int cH) {
	g.setColor(Color.blue);	
	g.fillRoundRect(startX, startY, cW, cH, 10, 10);
	g.setColor(Color.white);	
	g.fillRoundRect(startX + 2, startY + 2, cW - 4, cH - 4, 10, 10);
	g.setColor(Color.blue);	
	g.fillRoundRect(startX + 3, startY + 3, cW - 6, cH - 6, 10, 10);
	g.setColor(Color.black);	
	g.drawRoundRect(startX, startY, cW, cH, 10, 10);
   }

   private void paintCards(Graphics g) {
	int player = -1;
	for(int i = 0; i < cardX.length; i++) {
	   player++;
	   if(i == 5) {
	      player++;
		if(players[5].In) {
	         try {
	            tracker.waitForID(0);
	         }	
               catch(InterruptedException e){}
               int tempX = 350;
		 for(int j = 0; j < 4; j++) {
                  int indx = players[5].Hand[j].picIndex;
                  g.drawImage(pics[indx], tempX, 280, tempX + CARD,
					280 + CARD, 0, 0, 100, 100, this);
		    tempX += 35;
		 }   
	     }
	  }
	  if(players[player].In) {
	     int tempX = cardX[i];
	     for(int x = 0; x < 4; x++) {
              paintCardBack(g, tempX, cardY[i], 40, 60);
	        tempX += 5;
	     }
/** DEBUGGING
	     g.setColor(Color.white);
	     g.setFont(RegFont);
	     g.drawString(players[player].Hand[0].Name, cardX[i]+50, cardY[i]);
	     g.drawString(players[player].Hand[1].Name, cardX[i]+50, cardY[i] + 12);
           g.drawString(players[player].Hand[2].Name, cardX[i]+50, cardY[i] + 24);
	     g.drawString(players[player].Hand[3].Name, cardX[i]+50, cardY[i] + 36);
	     g.drawString(":" + players[player].Handicap, cardX[i]+50, cardY[i] + 48);
**/
         }
      }
   }

   private void paintCoin(Graphics g, int startX, int startY, int dollar) {
      g.setColor(Color.black);
      g.fillOval(startX - 1, startY- 1, COIN + 2, COIN + 2);
	g.setColor(Color.cyan);
	if (dollar == 1) {
	   g.setColor(Color.white);	
	}
	else if (dollar == 5) {
	   g.setColor(Color.red);	
	}

	g.fillOval(startX, startY, COIN, COIN);
	g.setColor(Color.white);
	g.fillRect(startX, startY + 13, SmOFFSET, TinyOFFSET);
	g.fillRect(startX + LgOFFSET, startY + 13, SmOFFSET, TinyOFFSET);
	g.fillRect(startX + 13, startY, TinyOFFSET, SmOFFSET);
	g.fillRect(startX + 13, startY + LgOFFSET, TinyOFFSET, SmOFFSET);
	g.setColor(Color.black);
	g.drawLine(startX, startY+MedOFFSET, startX+7, startY + MedOFFSET);
	g.drawLine(startX+23, startY+MedOFFSET, startX+COIN, startY + MedOFFSET);
	g.drawLine(startX+MedOFFSET, startY, startX+MedOFFSET, startY + 7);
	g.drawLine(startX + MedOFFSET, startY + 23, startX + MedOFFSET, startY + COIN);
	g.drawOval(startX, startY, COIN, COIN);
      g.setFont(smallFont);
      g.drawString("$" + dollar, startX + 7, startY + LgOFFSET); 
   }	

   private void paintMoney(Graphics g) {
      for(int i = 0; i < players.length; i++) {
	   if(players[i].InSoFar == 1) {
            paintCoin(g, betX[i], betY[i], 1);
	   }
	   else if(players[i].InSoFar == 3) { 
	      paintCoin(g, betX[i], betY[i], 1);
	      paintCoin(g, betX[i] + 8, betY[i], 1);
	      paintCoin(g, betX[i] + 16, betY[i], 1);
	   }
	   else if(players[i].InSoFar == 6) {
            paintCoin(g, betX[i], betY[i], 5);
	      paintCoin(g, betX[i] + 8, betY[i], 1);
	   }
	   else if(players[i].InSoFar == 9) {
            paintCoin(g, betX[i], betY[i], 5);
	      paintCoin(g, betX[i] + 8, betY[i], 1);
	      paintCoin(g, betX[i], betY[i] + COIN + 1, 1);
	      paintCoin(g, betX[i] + 8, betY[i] + COIN + 1, 1);
	      paintCoin(g, betX[i] + 16, betY[i] + COIN + 1, 1);
	   }
  	   else if(players[i].InSoFar == 12) {
            paintCoin(g, betX[i], betY[i], 5);
	      paintCoin(g, betX[i] + 8, betY[i], 1);
            paintCoin(g, betX[i], betY[i] + COIN + 1, 5);
	      paintCoin(g, betX[i] + 8, betY[i] + COIN + 1, 1);
	   }
  	   else if(players[i].InSoFar == 18) {
            paintCoin(g, betX[i], betY[i], 5);
	      paintCoin(g, betX[i] + 8, betY[i], 5);
	      paintCoin(g, betX[i] + 16, betY[i], 5);
	      paintCoin(g, betX[i], betY[i] + COIN + 1, 1);
	      paintCoin(g, betX[i] + 8, betY[i] + COIN + 1, 1);
	      paintCoin(g, betX[i] + 16, betY[i] + COIN + 1, 1);
	   }
  	   else if(players[i].InSoFar == 24) {
            paintCoin(g, betX[i], betY[i], 5);
	      paintCoin(g, betX[i] + 6, betY[i], 5);
	      paintCoin(g, betX[i] + 12, betY[i], 5);
	      paintCoin(g, betX[i] + 18, betY[i], 5);
	      paintCoin(g, betX[i], betY[i] + COIN + 1, 1);
	      paintCoin(g, betX[i] + 6, betY[i] + COIN + 1, 1);
            paintCoin(g, betX[i] + 12, betY[i] + COIN + 1, 1);
	      paintCoin(g, betX[i] + 18, betY[i] + COIN + 1, 1);
         }
  	   else if(players[i].InSoFar > 0) {
 	      paintCoin(g, betX[i], betY[i], 5);
	      paintCoin(g, betX[i] + 8, betY[i], 1);
	      paintCoin(g, betX[i] + 16, betY[i], 1);
	   }
      }
   }

   private void paintMoneyLabel(Graphics g,int startX,int startY,int amt) {
      g.setColor(Color.black);
	g.setFont(smallFont);
      g.fillRect(startX, startY, 45, 18);  
 	g.setColor(Color.yellow);
	g.fillRect(startX + 2, startY + 2, 41, 14);  	    
 	g.setColor(Color.black);
      g.drawString(" $" + amt, startX + 4, startY + 14); 
   }

   private void paintPlayersHand(Graphics g, int who) {
      // make sure images are loaded - eliminate flickering
	try {
	   tracker.waitForID(1);
	}	
      catch(InterruptedException e){}

	int cardIndex = who;
	if(who > 4) {
	   cardIndex--;
	}
	int x = cardX[cardIndex];
	int y = cardY[cardIndex];
	for(int i = 0; i < 4; i++) {
          int indx = players[who].Hand[i].picIndex;
          g.drawImage(pics[indx],x, y, x + 70, y + 70, 0, 0, 100, 100, this);
	   x += 15;
	}
   }

   private void paintTable(Graphics g) {
	// the table
	g.setColor(Color.black);
	g.fillOval(35, 35, 700, 350);	
	g.setColor(Color.green);
	g.fillOval(45, 45, 680, 330);

	// players and their money labels
	g.setFont(smallFont);
	g.setColor(Color.black);
      g.drawString(names[0], 69, 110); 
	paintMoneyLabel(g, 64, 112, players[0].Bankroll); 
      g.drawString(names[1], 220, 30);
	paintMoneyLabel(g, 214, 32, players[1].Bankroll); 
      g.drawString(names[2], 480, 30); 
	paintMoneyLabel(g, 474, 32, players[2].Bankroll); 
      g.drawString(names[3], 680, 110); 
	paintMoneyLabel(g, 674, 112, players[3].Bankroll); 
	g.drawString(names[4], 680, 320);
	paintMoneyLabel(g, 674, 290, players[4].Bankroll); 
	g.drawString(names[5], 480, 390);
	paintMoneyLabel(g, 474, 360, players[5].Bankroll); 
	g.drawString(names[6], 220, 390);
	paintMoneyLabel(g, 214, 360, players[6].Bankroll); 
	g.drawString(names[7], 60, 320);
	paintMoneyLabel(g, 54, 290, players[7].Bankroll); 

	// the button
	if(GameInProgress) {
 	   g.setFont(tinyFont);
	   g.setColor(Color.black);
	   g.fillOval(buttonX[btnPosition], buttonY[btnPosition], 42, 42);
	   g.setColor(Color.white);	
         g.fillOval(buttonX[btnPosition]+1,buttonY[btnPosition]+1,40,40);
	   g.setColor(Color.black);
	            g.drawOval(buttonX[btnPosition]+1,buttonY[btnPosition]+1,40,40);
	   g.drawString("Dealer",buttonX[btnPosition]+4, buttonY[btnPosition] +26);
      }
   }
	
   private void paintYourTurn(Graphics g, String topLabel, String label2) {
	g.clearRect(0, 0, 173, 53);
	int TempX = 2;
	int TempY = 2;
	g.setColor(Color.gray);
	g.fillRect(TempX, TempY, 180, 50); 
	g.setColor(Color.black);
	g.fillRect(TempX + 5, TempY + 5, 170, 40); 
	g.setColor(Color.white);
	g.setFont(RegFont);
	g.drawString(topLabel, 25, 25); 
	g.setFont(tinyFont);
	g.drawString(label2, 14, 38); 
   }		

   private void determineWinner(Graphics g) {
      HandInProgress = false;

      int hPotShare = 1;
      int lPotShare = 0;
      int hWinners[] = { currentPlayer, -1, -1, -1, -1, -1, -1, -1 };
      int lWinners[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
      if(showdown) {
         top = "GAME OVER!!";
	   int highHand = -1;
	   int lowHand = 88000;
  	   for(int i = 0; i < players.length; i++) {
	      if(players[i].In) {
		   determineBestHand(i);
		   if(players[i].BestLowHand < lowHand) {
		      lowHand = players[i].BestLowHand; 
		      lWinners[0] = i;   
		      lPotShare = 1;  
		   }
		   if(players[i].BestHand > highHand) {
		      highHand = players[i].BestHand; 
		      hWinners[0] = i;     
	         }
		   else if(players[i].BestHand == highHand) {
		      boolean tieIsBroken = false;
		      for(int tie = 0; tie < 5; tie++) {
		 	   int temp = players[i].Tiebreakers[tie];
		         if(temp > players[hWinners[0]].Tiebreakers[tie]) {
			      hWinners[0] = i;
			      tieIsBroken = true;
			      break;
			   }
			   if(players[hWinners[0]].Tiebreakers[tie] > temp) {
	 		      tieIsBroken = true;
			      break;
			   }
		      }	
		      if(!tieIsBroken) {
		         for(int x = 0; x < hWinners.length; x++) {
			      if(hWinners[x] == -1) {
			         hWinners[x] = i;
			         hPotShare++;
				   break;
			      }
			   }
	   	      }
	         }
	      }
         }
	   if(lPotShare == 1) {
            for(int i = 0; i < players.length; i++) {
	         if(i != lWinners[0] && players[i].In 				&& players[i].BestLowHand == lowHand) {
		      lWinners[lPotShare] = i;   
	 	      lPotShare += 1;  
               }
	      }  
	   }

	   int howHigh = highHand % 100;
	   String toWhat = "";
	   if(howHigh < 11) {
	      toWhat = String.valueOf(howHigh);
	   }
	   else {
	      if(howHigh == 14) {
                toWhat = "Ace";
	      }
	      else if(howHigh == 13) {
                toWhat = "King";
	      }
	      else if(howHigh == 12) {
                toWhat = "Queen";
	      }
	      else if(howHigh == 11) {
                toWhat = "Jack";
	      }
	   }
	   if(highHand > 800) {
	      if(howHigh == 14) {
	         displayHigh = "Royal Flush Wins!";
	      }
	      else {
	         displayHigh = "Straight Flush Wins!";
	      }
	   }
	   else if(highHand > 700) {
	      displayHigh = "Four " + toWhat + "s Win!";
	   }
	   else if(highHand > 600) {
	      displayHigh = toWhat + "s Full Wins!";
	   }
	   else if(highHand > 500) {
	      displayHigh = toWhat + " high Flush Wins!";
	   }
	   else if(highHand > 400) {
	      if(howHigh == 14) {
		  displayHigh = "Broadway Wins!";
	      }
	      else if(howHigh == 5) {
		  displayHigh = "The Wheel Wins!";
	      }
             else {
	         displayHigh = toWhat + " high Straight Wins!";
	      }
	   }
	   else if(highHand > 300) {
	      displayHigh = "Three " + toWhat + "s Win!";
	   }
	   else if(highHand > 200) {
	      displayHigh = "Two Pair Wins!";
	   }
	   else if(highHand > 100) {
	      displayHigh = "Pair of " + toWhat + "s Win!";
	   }
         else {
	      displayHigh = toWhat + " high Wins!";
	   }
	   if(lowHand < 88000) {
	      if(lowHand < 55000) {
	         displayLow = "The Wheel is Low! ";
	      }
	      else {
	         String temp = String.valueOf(lowHand);
               for(int i = 0; i < 4; i++) {
	            displayLow += temp.substring(i, i + 1) + "-";
	         }
	         String lastCard = temp.substring(4);
	         if(lastCard.equals("1")) {
		      displayLow += "Ace is Low! ";
	         }
	         else {
	           displayLow += lastCard + " is Low! ";
	         }
	      }	
         }
      }
      else {
	   displayHigh = "No Callers!";
      }

      int winnings = pot;
      int lWinnings = (lPotShare > 0) ? (pot/2)/lPotShare : 0;
      int hWinnings = 
       (lPotShare > 0) ? (pot/2)/hPotShare : pot/hPotShare;

      if(hPotShare == 1 && hWinners[0] == 5) {
         displayHigh += " You can take it down.";
         players[5].Bankroll += hWinnings;
      }
      else {
	   displayHigh += " Take it down ";
         for(int x = 0; x < hWinners.length; x++) {
            if(hWinners[x] > -1) {
	         if(x > 0) {
	            displayHigh += ", ";
	         }
               displayHigh += players[hWinners[x]].Name;  
	         if(players[hWinners[x]].InSoFar > 0) {
	            hWinnings += players[hWinners[x]].InSoFar;
               }
	         players[hWinners[x]].Bankroll += hWinnings;
	      }
            else {
	        break;
	     }
	   }
      }
      if(lPotShare == 1 && lWinners[0] == 5) {
         displayLow += "You Win!";
         players[5].Bankroll += winnings / 2;
      }
      else if(lPotShare > 0) { 
	   displayLow += "It's yours ";
         for(int x = 0; x < lWinners.length; x++) {
            if(lWinners[x] > -1) {
	         if(x > 0) {
	            displayLow += ", ";
	         }
               displayLow += players[lWinners[x]].Name;  
	         players[lWinners[x]].Bankroll += lWinnings;
	      }
	   }
      }	
	
      repaint();
   }

/********************Determine Winner*********************/

   public Hashtable determineBestHand(int player) {
      // reset player
      players[player].BestLowHand = 99999;
      players[player].BestHand = 0;		
      for(int tie = 0; tie < 5; tie++) {
         players[player].Tiebreakers[tie] = -1;
      }

      // build a test array of hands
      Hashtable possibles = players[player].getPossibles(board);

      int lowHand = 99999;
      int bestHand = 0;
      Enumeration enum = possibles.elements();
      while(enum.hasMoreElements()) {
         Card tester[] = (Card[])enum.nextElement();

         // check for low hand
         int pair = hasPair(tester);
         if(pair < 100 && tester[4].Value == 14) {
            if(tester[3].Value < 9) {
	         String low = "";
	         for(int i = 3; i > -1; i--) {
	            low = low.concat(String.valueOf(tester[i].Value));
  	         }
	         lowHand = (Integer.parseInt(low) * 10) + 1;
            }
	   }
	   else if(pair < 100 && tester[4].Value < 9) {
	      String low = "";
	      for(int i = 4; i > -1; i--) {
	         low = low.concat(String.valueOf(tester[i].Value));
	      }
	      lowHand = Integer.parseInt(low);
	   }
	   if(lowHand < players[player].BestLowHand) {
	      players[player].BestLowHand = lowHand;
	   }
         // check for high hand
	   bestHand = getBestHand(tester);
	   if(bestHand > players[player].BestHand) {
		setTiebreakers(bestHand, player, tester, false);
	      players[player].BestHand = bestHand;
	   }
	   else if(bestHand == players[player].BestHand) {
		setTiebreakers(bestHand, player, tester, true);
	   }
      }
      return possibles;
   }

   public void setTiebreakers(int bestHand, int player, 
				Card[] tester, boolean checkFirst) {
     if((bestHand > 500 && bestHand < 600) || bestHand < 200) {
	   // best hand is a flush or a pair or high card only
	   // put all 5 cards in tiebreaker
         int x = 4;
	   if(checkFirst) {
	      for(int tie = 0; tie < 5; tie++) {
               if(tester[x].Value < players[player].Tiebreakers[tie]) {
			   return;
		   }
		   x--;
		}
	   }
	   x = 4;
	   for(int tie = 0; tie < 5; tie++) {
	      players[player].Tiebreakers[tie] = tester[x].Value;
            x--;
	   }
	}
	else if((bestHand > 600 && bestHand < 700) 
		||(bestHand > 300 && bestHand < 400)) {
	   // best hand is a boat or trips 
	   // put 2 cards in tiebreaker - reset other 3
         int trips = bestHand % 100;
	   int tie = 0;
	   if(checkFirst) {
	      for(int x = tester.length -1; x > -1; x--) {
		   if(tester[x].Value != trips) {
		      if(tester[x].Value < players[player].Tiebreakers[tie]) {
			   return;
			}
		      tie++;
		   }   
		}
	   }
	   tie = 0;
	   for(int x = tester.length -1; x > -1; x--) {
		if(tester[x].Value != trips) {
               players[player].Tiebreakers[tie] = tester[x].Value;
               tie++;
	      }
	   }
         players[player].Tiebreakers[2] = -1;	   
         players[player].Tiebreakers[3] = -1;	   
         players[player].Tiebreakers[4] = -1;	   
	}
	else if(bestHand < 300) {
	   // best hand is two pair 
	   // put 3 cards in tiebreaker - reset other 3
         int twoPair = bestHand % 100;
	   int cards[] = {0, 0 ,0};
         int indx = 0;
	   for(int x = tester.length -1; x > -1; x--) {
		if(tester[x].Value != twoPair) {
               cards[indx] = tester[x].Value;
		   indx++;
            }
         }	   

	   int secondPair = 0;
	   int fifthCard = 0;
	   if(cards[0] == cards[1]) {
		secondPair = cards[0];
	   	fifthCard = cards[2];
	   }
	   else if(cards[0] == cards[2]) {
		secondPair = cards[0];
	   	fifthCard = cards[1];
	   }
	   else {
  		secondPair = cards[1];
	   	fifthCard = cards[0];
	   }
	   if(checkFirst) {
		if(players[player].Tiebreakers[0] < secondPair 
			|| players[player].Tiebreakers[0] < fifthCard) {
		   return;
		}
         }	   
         players[player].Tiebreakers[0] = secondPair;
         players[player].Tiebreakers[1] = fifthCard;
         players[player].Tiebreakers[2] = -1;
         players[player].Tiebreakers[3] = -1;	   
         players[player].Tiebreakers[4] = -1;	   
	}
	else {
	   // best hand is 4 of a kind, straight, or straight flush
	   // no tiebreaker is required 
         for(int tie = 0; tie < 5; tie++) {
            players[player].Tiebreakers[tie] = -1;
         }
	}
   }

   public int hasStraightFlush(Card[] tester) { 
	sortHandBySuit(tester); 
	int flush = 0;
	int ttlValue = 0;
	int counter = 0;
	for(int x = 0; x < tester.length; x++) {
	   counter++;
	   if((ttlValue + 1) == tester[x].TtlValue) {
	      if(counter == 5) {
	         flush = tester[x].Suit;
	         break;
	      }
	   }
	   else {
	      ttlValue = tester[x].TtlValue;
	      counter = 0;
	   }
	}
	if(flush > 0) {
	   for(int x = tester.length - 1; x > -1; x--) {
	      if(tester[x].Suit == flush) {
		   return 800 + tester[x].Value;
	      }
	   }
	}
	return 0;
   }

   public int hasFourOfAKind(Card[] tester) { 
	sortHand(tester); 
      int four = 0;
      int value = 0;
	int counter = 1;
	for(int x = 0; x < tester.length; x++) {
	   counter++;
         if(value == tester[x].Value) {
	      if(counter == 4) {
		   four = 700 + value;
               break;
	      }
	   }
	   else {
	      value = tester[x].Value;
   	      counter = 1;
	   }
	}
	return four;
   }

   public int hasFullHouse(Card[] tester) { 
	sortHand(tester); 
      int trips = 0;
      int value = 0;
	int counter = 0;
	for(int x = tester.length - 1; x > -1; x--) {
	   counter++;
         if(value == tester[x].Value) {
	      if(counter == 2) {
		   trips = value;
	         break;
		}
	   }
	   else {
	      value = tester[x].Value;
		counter = 0;
	   }
	}
	if(trips > 0) {
	   value = 0;
	   for(int x = tester.length - 1; x > -1; x--) {
	      if(tester[x].Value != trips) {
	         if(value == tester[x].Value) { 
	            return 600 + trips;
		   }
	         else {
	            value = tester[x].Value;
	         }
	      }
	   }
	}
	return 0;
   }	

   public int hasFlush(Card[] tester, int howMany) { 
	sortHandBySuit(tester); 
	int flush = 0;
	int suit = -1;
	int counter = 0;
	for(int x = 0; x < tester.length; x++) {
	   counter++;
	   if(suit == tester[x].Suit) {
	      if(counter >= (howMany - 1)) {
	         flush = 500 + tester[x].Value;
	      }
	   }
	   else {
	      suit = tester[x].Suit;
	      counter = 0;
	   }
	}
	return flush;
   }
 
   public int hasFourStraight(Card[] tester, int howMany) { 
	if(tester.length < howMany) {
	   return 0;
	}
	sortHand(tester); 
	for(int x = 2; x < 11; x++) {
	   int value = x - 1;
	   int counter = 0;
 	   for(int i = 0; i < tester.length; i++) {
	      if(value == tester[i].Value) {
	         continue;
	      }
	      if(tester[i].Value >= x && tester[i].Value < (x + 5)) {
	         counter++;
               value = tester[i].Value;
	         if(counter == howMany) {
	            return value;
	         }
	      }
	   }
	}
	return 0;
   }

   public int hasStraight(Card[] tester) { 
	sortHand(tester); 
      int straight = 0;
      int value = 0;
	int counter = 1;
	// first check for the wheel
	if(tester[0].Value == 2) {
	   value = 2;
	   for(int x = 1; x < tester.length; x++) {
	      if((value + 1) == tester[x].Value) {
	         counter++;
	         value++;
	         if(counter == 4) {
		      // 2 - 5 now look for the Ace
		      for(int i = 0; i < tester.length; i++) {
			   if(tester[i].Value == 14) {
			      return 405;
		         }
		      }
		   }
	      }
	      else {
	         value = tester[x].Value;
	         counter = 1;
	      }
	   }    
	} 
	value = 0;
	counter = 1;
	for(int i = tester.length - 1; i > -1; i--) {
	   if((value - 1) == tester[i].Value) {
	      counter++;
	      value--;
	      if(counter == 5) {
	         straight = 400 + (value + 4);
	 	   break;
	      }
	   }
	   else {
	      value = tester[i].Value;
	      counter = 1;
	   }
	}
	return straight;
   }

   public int hasTrips(Card[] tester) { 
	sortHand(tester); 
      int trips = 0;
      int value = 0;
	int counter = 0;
	for(int x = tester.length -1; x > -1; x--) {
	   counter++;
         if(value == tester[x].Value) {
	      if(counter == 2) {
		   trips = 300 + value;
	         break;
		}
	   }
	   else {
	      value = tester[x].Value;
		counter = 0;
	   }
	}
	return trips;
  }	

   public int hasTwoPair(Card[] tester) { 
	sortHand(tester); 
      int twoPair = 0;
      int firstPair = 0;
      int secondPair = 0;
      int value = 0;
	int pairCounter = 0;
	for(int x = tester.length - 1; x > -1; x--) {
         if(value == tester[x].Value) {
            pairCounter++;
		if(pairCounter == 1) {
               firstPair = value;
		   value = 0;
		}
		if(pairCounter == 2) {
		   twoPair = 200 + firstPair;
               secondPair = value;
		   break;
		}
	   }
	   else {
	      value = tester[x].Value;
	   }
	}
	return twoPair;
   }

   public int hasPair(Card[] tester) { 
	sortHand(tester); 
      int pair = 0;
      int value = 0;
	for(int x = tester.length - 1; x >= 0; x--) {
         if(value == tester[x].Value) {
  	      pair = 100 + value;
	      break;
	   }
	   else {
	      value = tester[x].Value;
	   }
	}
	if(pair == 0) {
	   pair = tester[tester.length - 1].Value;
	}
	return pair;
   }

   public int[] hasLow(Card[] tester, int howMany) { 
      int bestLows[] = {-1, -1, -1, -1, -1};

      // find out if there are 3 or more to a low
      // and populate a vector with each distinct low
      sortHand(tester);
      Vector lowCards = new Vector();
      if(tester[tester.length - 1].Value == 14) {
	   lowCards.addElement(new Integer(1));
      }
      for(int i = 0; i < tester.length; i++) {
         if(tester[i].Value < 9) {
            Integer temp = new Integer(tester[i].Value);
	      if(!lowCards.contains(temp)) {
	         lowCards.addElement(temp);
	      }
	   }
      }
      if(lowCards.size() < howMany) {
	   return bestLows;
      }

      // if there are 3 or more lows populate bestLows with
      // ints that represent possible lows 
      // ex: 12 = Ace, duece   35 = 3, 5
      // first - check if there are 4 cards between ace and 5
      // ex: use 50 to represent that 5 and any other card is nut
      int ctr = 0;
      int notIncluded = 0;
      for(int j = 1; j < 6; j++) {
         Integer temp = new Integer(j);
	  if(lowCards.contains(temp)) {
	     ctr++;
	  }
	  else {
	     notIncluded = j;
	  }	
      }
      if(ctr > 3) {
	  int value = 0;
         if(notIncluded > 0) {
	     value = notIncluded * 10;
	  }
	  bestLows[0] = value;
	  return bestLows;
      }

      int card1 = 0;
      int indx = 0;
      for(int x = 2; x < 7; x++) {
         if(!lowCards.contains(new Integer(x))) {
            card1 = x;
	      for(int j = 1; j < x; j++) {
               if(!lowCards.contains(new Integer(j))) {
		      bestLows[indx] = (j * 10) + card1;
		      indx += 1;
		      if(indx > 4) {
			   return bestLows;
		      }
               }
	      }
	   }
      }
      return bestLows;
   }

   public void sortHand(Card hand[]) {
      Card Temp;
      for(int x = 0; x < hand.length; x++) {
         int min = x;
	   for(int i = x; i < hand.length; i++) {
	      if(hand[i].Value < hand[min].Value)
   	         min = i;
	   }
	   Temp = hand[x];
	   hand[x] = hand[min];
	   hand[min] = Temp;
      } 	
   } 

   public void sortHandBySuit(Card hand[]) {
      Card Temp;
      for(int x = 0; x < hand.length; x++) {
         int min = x;
         for(int i = x; i < hand.length; i++) {
	      if(hand[i].TtlValue < hand[min].TtlValue)
	         min = i;
	   }
	   Temp = hand[x];
	   hand[x] = hand[min];
	   hand[min] = Temp;
      } 
   } 

   public int getBestHand(Card[] testers) {
      int retValue = hasStraightFlush(testers);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasFourOfAKind(testers);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasFullHouse(testers);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasFlush(testers, 5);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasStraight(testers);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasTrips(testers);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasTwoPair(testers);
      if(retValue > 0) {
         return retValue;
      }
      retValue = hasPair(testers);
      return retValue;
   }

/***********************************************************************
		Main Thread	
************************************************************************/ 
   public void run() {
      Graphics g = getGraphics();

      while(true) {
         /** Returns true if the game is over
	       Returns false and sets the next current player
	       if the game continues  ***/
	   if(advancePlayer(g)) {
	      newHand = false;
            showdown = false;	      
	      determineWinner(g);
	      try {
  	         turn.sleep(5000);
            }
            catch(InterruptedException ie){}
	      resetHand(g);
	      postBlinds(g);
	      DealCards();
	      continue;
	   }
	   else {
	      newHand = false;
            /** Returns true if the betting round is over
	          Returns false and sets the next round
	          if the game continues  ***/
	      if(!moreWorkToDo()) {
               if(currentPlayer == 5 && btnPosition == 3
			&& round == PREFLOP && currentWager == 3
						 && blindFlag == true) {
		      blindFlag = false;
		      choiceMade = false;
  	            top = "YOUR TURN!!";
	            repaint();
                  turn.stop();
	            break;
		   }
		   else {
	            try {
  	               turn.sleep(interval);
	               if(!advanceRound(g)) {
	  	            showdown = true;
	                  determineWinner(g);
		            turn.sleep(10000);
		            resetHand(g);
		            postBlinds(g);
			      DealCards();
	                  continue;
		         }
	            }
                  catch(InterruptedException ie){}
	         }
	      }
	      else {
               newRound = false;
	         if(currentPlayer == 5) {
		      choiceMade = false;
  	            top = "YOUR TURN!!";
	            turn = null;
	            repaint();
	            break;
	         }
	         else {
 	            try {
	               turn.sleep(interval);
	               computerTurn(g);
	               repaint();
 	               turn.sleep(interval);
	            }
	            catch(InterruptedException ie){}
	         }
 	      }
         }	
      }
   }

   public void stop() {
	turn = null;
   }

   public boolean moreWorkToDo() {
	boolean retValue = false;
	for(int i = 0; i < players.length; i++) {
	   if(players[i].In && players[i].InSoFar < currentWager) { 
	      retValue = true;
	      break;
	   }
	}
	return retValue;
   }

   public boolean advanceRound(Graphics g) {
      boolean retValue = true;
      newRound = true;
      round++;
      raises = 0;
      myraises = 0;
      currentWager = 0;
      for(int i = 0; i < players.length; i++) {
	   if(players[i].InSoFar > -1) {
	      pot += players[i].InSoFar ;
            players[i].InSoFar = -1;
	   }
      }

      if(round > PREFLOP && round < WINNER) {
         // find out what the board offers
         //  (3 to a low, 3 to a flush, 3 to straight, pair, trips)
         Card theBoard[] = new Card[round];
         for(int x = 0; x < round; x++) {
	      theBoard[x] = new Card(board[x].Suit, board[x].Value);
         }

         boardTrips = hasTrips(theBoard);
         boardPair = 
	     (boardTrips > 0) ? boardTrips - 100 : hasPair(theBoard);
         boardFlush = hasFlush(theBoard, 3);
         board3Straight = hasFourStraight(theBoard, 3);
         board4Straight = hasFourStraight(theBoard, 4);
         boardLow = hasLow(theBoard, 3);
      }

      if(round == FLOP) {
	   top = "THE FLOP";
	   board[0].Available = true;
	   board[1].Available = true;
	   board[2].Available = true;
      }
      else if(round == TURN) {
	   top = "THE TURN";
	   board[3].Available = true;
      }
      else if(round == RIVER) {
	   top = "THE RIVER";
	   board[4].Available = true;
      }
      else {
	   retValue = false;
      }
      repaint();
      return retValue;
   }

   /** Returns true if the game is over
	 Returns false and sets the next current player
	 if the game continues  ***/
   public boolean advancePlayer(Graphics g) {
      // Need to do 2 things
	// 1: See if the game is over (only one player)
	// 2: Set the currentPlayer to the next active player
      boolean gameOver = true;
      if(newRound && !newHand){
         int firstAfterBtn = btnPosition;
         int activePlayers = 0;
         int firstActive = -1;
         for (int i = 0; i < 8; i++) {
            if(firstAfterBtn == 7) {
	         firstAfterBtn = -1;
	      }
	      firstAfterBtn++;
	      if(players[firstAfterBtn].In) {
	         if(activePlayers > 0) {
		      gameOver = false;
		      break;
	         }
		   else {
	            firstActive = firstAfterBtn;
		   }
	         activePlayers++;
	      }	   
         }
         currentPlayer = firstActive;
         return gameOver;
      }

      int firstActive = currentPlayer;    
      int activePlayers = 0;
      for (int i = 0; i < 8; i++) {
	   if(currentPlayer == 7) {
	      currentPlayer = -1;
	   }
	   currentPlayer++;
	   if(players[currentPlayer].In) {
	      if(activePlayers > 0) {
		   gameOver = false;
		   break;
	      }
	      firstActive = currentPlayer;
	      activePlayers++;
	   }	   
      }
      currentPlayer = firstActive;
      return gameOver;
   }

/***********************************************************************
		Start Game	
************************************************************************/ 

   public void resetHand(Graphics g) {
      if(btnPosition < 7) {
         btnPosition++;
      }
      else {
	   btnPosition = 0;
      }

      interval = 1800;
      raises = 0;
      myraises = 0;
      pot = 0;
      blindFlag = true;
      top = "NEW HAND";
      for(int i = 0; i < players.length; i++) {
	   players[i].In = true;
         players[i].InSoFar = -1;
      }
      HandInProgress = true;
      round = PREFLOP;
      newHand = true;
      displayLow = "";
   }

   private void postBlinds(Graphics g) {
	int lBlind = (btnPosition == 7) ? 0 : btnPosition + 1;
	players[lBlind].Bankroll--;
	players[lBlind].InSoFar = 1;

	int bBlind = (btnPosition > 5) ? btnPosition - 6 : btnPosition + 2;
	players[bBlind].Bankroll -= 3;
	players[bBlind].InSoFar = 3;

	// the thread will advance the player so subtract one here
	currentPlayer = bBlind;
	currentWager = 3;

	if(turn == null) {
	   turn = new Thread(this);
	   turn.start();
	}
   }

   private void DealCards() {
      // reset the deck
      for(int i = 0; i < CARDS_IN_DECK; i++) {
         AvailableCards[i] = true;
      }	
      int aCard;
      // deal a hand to each of the 8 players
      for(int x = 0; x < players.length; x++) { 
         // Deal the appropriate amount of cards
         for(int i = 0; i < 4; i++) {
	      while(true) {
	         aCard = (int)(Math.random() * CARDS_IN_DECK);
	         if(AvailableCards[aCard] == true) {
		      //take that card out of circulation
	            AvailableCards[aCard] = false; 	  
	            break;
	         }
	      } 
	      players[x].Hand[i] = new Card(aCard);
	      int indx = players[x].Hand[i].picIndex;
	      if(x == 5) {
	         tracker.addImage(pics[indx], 0);
	      }
	      else {
	         tracker.addImage(pics[indx], 1);
	      }
	   }
      } 

      board = new Card[5];
      for(int i = 0; i < 5; i++) {
	   while(true) {
	      aCard = (int)(Math.random() * CARDS_IN_DECK);
	      if(AvailableCards[aCard] == true) {
	         //take that card out of circulation
	    	   AvailableCards[aCard] = false; 	  
		   break;
	      }
	   } 
	   board[i] = new Card(aCard);
          int indx = board[i].picIndex;
	   tracker.addImage(pics[indx], 2, 50, CARD);
	   board[i].Available = false;
      }
      repaint(); 
   }	

/***********************************************************************
		Computer Moves	
************************************************************************/ 

   public void computerTurn(Graphics g) {
      int move = (currentWager == 0) ? CHECK : FOLD;

      // how many active players between you and the button
      int behind = getActivePlayersBehindYou();

      // get move
      if(round == PREFLOP) {
         move = players[currentPlayer].determineMove(behind, raises);
      }
      else {  //start big else
	   /*****ASSEMBLE SOME INFORMATION**********/
         // how many active players 
	  int alive = -1; // don't count me
	  for(int x = 0; x < players.length; x++) {
	     if(players[x].In) {
	        alive++;
 	     }
	  }

	  boolean fourFlush = false;
	  boolean fourStraight = false;
        boolean fourLow = false;

	  // find out the best you have
        Hashtable possible = determineBestHand(currentPlayer);
	  int bestHand = players[currentPlayer].BestHand;
	  int howHigh = bestHand % 100;

	  if(round < RIVER) {
	     // find out the best you have possible
           Enumeration enum = possible.elements();
           while(enum.hasMoreElements()) {
              Card tester[] = (Card[])enum.nextElement(); 
                
		  // fourflush means nothing if there are 3 suits on board
              int tempFlush = 0;
		  if(boardFlush == 0) { 
		     tempFlush = hasFlush(tester, 4);
		  }

		  // fourStraight means nothing if 3 to a straight on board
	        int tempStraight = 0;
		  if(board3Straight == 0) { 
		     hasFourStraight(tester, 4);
		  }
               
		  // fourLow means nothing if there are 3 lows on board
		  if(boardLow[0] == -1) {    
		     int tempLow[] = hasLow(tester, 4);
                 if(tempLow[0] > -1) {
		        fourLow = true;
		     }
		  }

		  if(tempFlush > 0) {
		     fourFlush = true;
		  }
		  if(tempStraight > 0) {
		     fourStraight = true;
		  }
		  if(fourFlush && fourStraight && fourLow) {
		     break;
		  }
           }
	  }

	  // ignore humans raises
   	  int theRaises = raises - myraises;

	  int type = players[currentPlayer].Handicap;

        // not accessing whether its a good boat
	  if(bestHand > 600) {    // I have a boat or better
	     if(type == 5 && round < RIVER) {
	        // just for fun - 5 is a slow player
	        move = (currentWager == 0) ? CHECK : CALL;
           }
           else if(raises < 3 && type > 6) {
	        move = (currentWager == 0) ? BET : RAISE;
	     }
           else if(raises < 2 && type > 3) {
	        move = (currentWager == 0) ? BET : RAISE;
	     }
           else {
	        move = (currentWager == 0) ? BET : CALL;
	     }
	  }
        else if(boardTrips > 0) {  // no boat
	     if(bestHand > 400 && type > 4 && theRaises == 0) {
	     	  move = (currentWager == 0) ? CHECK : CALL;
	     }
	     else if(alive == 1 && players[5].In && type > 5) {
	        // I don't have a boat but there is only the human
		  move = (currentWager == 0) ? BET : CALL;
	     }
	     else if(type == 9 && behind == 0) {
		  move = (currentWager == 0) ? BET : FOLD;
	     }
        }
       else if(boardPair > 100) {
          if(bestHand > 500) {   // board pair - I have a flush
             if(type > 6 && raises < 2) {
                move = (currentWager == 0) ? BET : RAISE;
	       }
		 else if(type > 3 && theRaises == 0) {
		    move = (currentWager == 0) ? BET : CALL;
		 }	
		 else  {
		    move = (currentWager == 0) ? CHECK : CALL;
		 }	
	    }
          else if(bestHand > 400) { // board pair - I have a straight
             if(type > 7 && raises < 2) {
                move = (currentWager == 0) ? BET : RAISE;
		 }
		 else if(type > 4 && theRaises == 0) {
		    move = (currentWager == 0) ? BET : CALL;
		 }	
		 else  {
		    move = (currentWager == 0) ? CHECK : CALL;
		 }	
	    }
          else if(bestHand > 300) {    // board pair - I have trips
		 if(boardFlush == 0 && board4Straight == 0) {
                if(type > 6 && raises < 2) {
                   move = (currentWager == 0) ? BET : RAISE;
		    }
		    else if(type > 3 && (theRaises == 0 || fourFlush)) {
		       move = (currentWager == 0) ? BET : CALL;	 
                  }
		 }
		 else {
                if(type > 4) {
                   move = (currentWager == 0) ? BET : CALL;
		    }	
		 }
		 if(move == FOLD) {
		    move = (currentWager == 0) ? CHECK : CALL;
             }
	   }
	   else if(bestHand > 200) { // board pair - I have 2 pair
            if(type > 7 && theRaises < 2) {
               move = (currentWager == 0) ? BET : CALL;
		}
		else if(type > 3 && (theRaises == 0 || fourFlush)) {
		   move = (currentWager == 0) ? CHECK : CALL;
		}	
	  }
	  else if(type == 9 && behind == 0) {
	     move = (currentWager == 0) ? BET : FOLD;
	  }
       }
       else if(boardFlush > 0) {
	    if(bestHand > 500) {  // I have a flush - ??? if its nut 
             if(type == 5 && round < RIVER) {
	          // just for fun - 5 is a slow player
	          move = (currentWager == 0) ? CHECK : CALL;
             }
             else if(type > 6 && raises < 3) {
                move = (currentWager == 0) ? BET : RAISE;
		 }
		 else {
		    move = (currentWager == 0) ? BET : CALL;
		 }	
	    }
           else if(bestHand > 400) {    // board flush - I have a straight
              if(type > 6 && theRaises == 0) {
                 move = (currentWager == 0) ? BET : RAISE;
		  }
		  else if(type > 3 && theRaises < 2) {
		     move = (currentWager == 0) ? BET : CALL;
	        }
		  else if(fourLow) {
	           move = (currentWager == 0) ? CHECK : CALL;
		  }		
	     }
	     else if(bestHand > 300) {    // board flush - I have trips
              if(type > 6 && board4Straight == 0) {
                 move = (currentWager == 0) ? BET : CALL;
		  }
	        else if((board4Straight == 0 && theRaises == 0)
								 || fourLow) {
		     move = (currentWager == 0) ? CHECK : CALL;
	 	  }	
           }
	     else if(bestHand > 200) {    // board flush - I have 2 pair 
              if(round < RIVER && theRaises == 0) {
		     if((type > 7 && board4Straight == 0) || fourLow) {
                    move = (currentWager == 0) ? CHECK : CALL;
                 }
	        }
	     }
	     else if(type == 9 && behind == 0) {
	        move = (currentWager == 0) ? BET : FOLD;
	     }
        }
	  else if(board4Straight > 0 || board3Straight > 0) {
           if(bestHand > 400) {  // I have a straight - ??? if nut 
              if(type == 5 && round < RIVER) {
	           // just for fun - 5 is a slow player
	           move = (currentWager == 0) ? CHECK : CALL;
              }
              else if(type > 6 && raises < 3) {
                 move = (currentWager == 0) ? BET : RAISE;
		  }
              else if(type > 3 && raises < 2 && fourFlush) {
                 move = (currentWager == 0) ? BET : RAISE;
		  }
		  else {
		     move = (currentWager == 0) ? BET : CALL;
		  }	
	     }
	     else if(bestHand > 300) {     // board Straight - I have trips
                if(type > 6 && board4Straight == 0 
						&& theRaises == 0) {
                 move = (currentWager == 0) ? BET : CALL;
		  }
		  else if((board4Straight == 0 && theRaises == 0)
						|| fourLow || fourFlush) {
		     move = (currentWager == 0) ? CHECK : CALL;
		  }
           }
	     else if(bestHand > 200) {    // board Straight - I have 2 pair
              if(type > 7 && board4Straight == 0 
						&& theRaises == 0) {
                 move = (currentWager == 0) ? BET : CALL;
		  }
		  else if(type > 3 && (board4Straight == 0 
				&& theRaises == 0) || fourLow || fourFlush) {
		     move = (currentWager == 0) ? CHECK : CALL;
		  }
           }
           else if(fourFlush) {
              if((type > 7 && board4Straight == 0 && theRaises == 0) 
								|| fourLow) {
                 move = (currentWager == 0) ? CHECK : CALL;
	        }
	     }
	  }
	  else {
           if(bestHand > 300) {    // no pair - I have trips
              if(type > 6) {
                 move = (currentWager == 0) ? BET : CALL;
		  }
		  else {
		     move = (currentWager == 0) ? CHECK : CALL;
		  }	
           }
           else if(fourFlush || fourStraight || 
			(fourLow && pot > 20 && alive > 1)) {
              if(type > 6 && round == FLOP) {
                 move = (currentWager == 0) ? BET : CALL;
              }
              else if(theRaises == 0) {
                 move = (currentWager == 0) ? CHECK : CALL;
              }	
          }
	     else if(bestHand > 200) {    // no pair - I have 2 pair
              if(type > 7) {
                 move = (currentWager == 0) ? BET : CALL;
	        }
	        else if(type > 4 || fourLow) {
	           move = (currentWager == 0) ? CHECK : CALL;
	        }	
           }
	    else if(type == 9 && behind == 0) {  // no pair - bluffing 
              move = (currentWager == 0) ? BET : FOLD;
	    }
	  }
	 
	  // We've determined a move based on high hand only
	  // Use low to improve the bet not decrease it
        if(move < RAISE && boardLow[0] > -1) {
	     Card temp[] = players[currentPlayer].Hand;
	     sortHand(temp);
	     // boardLow contains an array of the best possible lows
	     // if our hand contains any of them it is good to bet
	     // first - check first element of array for multiple lows 
	     boolean nutLow = false;
            if(boardLow[0] == 0 
			&& players[currentPlayer].BestLowHand < 99999) {
	        // ex: 0 means any 2 below a 6 is wheel
		  nutLow = true;
	      }
	     else if((boardLow[0] % 10) == 0 
			&& players[currentPlayer].BestLowHand < 99999) {
	        // ex: 40 means 4 and any other below a 6 is wheel
              int matchLow = boardLow[0] / 10;
 	       matchLow = (matchLow == 1) ? 14 : matchLow;
             for(int i = 0; i < 4; i++) {
                 if(temp[i].Value == matchLow) {      
 		         nutLow = true;
		     }
              }
	     }
           else {
	        for(int i = 0; i < 5; i++) {
                 int card1 = boardLow[i] % 10;
                 int card2 = (boardLow[i] - card1) / 10;
	           card2 = (card2 == 1) ? 14 : card2;
	           boolean oneMatch = false;
	           boolean twoMatch = false;
	           for(int j = 0; j < 4; j++) {
                    if(temp[j].Value == card1) {
			     oneMatch = true;
		        }
		        else if(temp[j].Value == card2) {
			     twoMatch = true;
		        }
                 }
                 if(oneMatch && twoMatch) {
                    if(type == 5 && round < RIVER) {
	                 // just for fun - 5 is a slow player
	                 move = (currentWager == 0) ? CHECK : CALL;
			     nutLow = false; 
                    }
                    else if(i == 0) {  
		           nutLow = true;
		        }
		        else {
		           // good low
		           if(type > 6 && raises < 3) {
		              move = (currentWager == 0) ? BET : RAISE;
		           }
		           else if(type > 3) {
			        move = (currentWager == 0) ? BET : CALL;
		           }
		           else if(move == FOLD) {			        				  move = (currentWager == 0) ? CHECK : CALL;
		           }
		        }
		        break;
                 }
	         }  // end for loop
             } // end else
	      if(nutLow) {
              if(raises < 3) {
                 move = (currentWager == 0) ? BET : RAISE;
		  }
		  else {
		     move = (currentWager == 0) ? BET : CALL;
	   	  }
             }
	   }
      } // end big else
	/*********TAKE ACTION*******************/
      
	int inSoFar = 0;
	if(players[currentPlayer].InSoFar	> -1) {
	   inSoFar = players[currentPlayer].InSoFar;
      }

	if(move == RAISE) {
	   if(round > FLOP) {
	      currentWager += 6;
	   }
	   else {
	      currentWager += 3;
	   }
  	   top = players[currentPlayer].Name + " RAISES!!";

	   players[currentPlayer].Bankroll -= (currentWager - inSoFar);
	   players[currentPlayer].InSoFar = currentWager;
	   raises++;
	}
	else if(move == BET) {
	   if(round > FLOP) {
	      currentWager = 6;
	   }
	   else {
	      currentWager = 3;
	   }
  	   top = players[currentPlayer].Name + " BETS!!";
 	   players[currentPlayer].Bankroll -= currentWager;
	   players[currentPlayer].InSoFar = currentWager;
	}
	else if(move == CALL) {
  	   top = players[currentPlayer].Name + " CALLS!!";
	   players[currentPlayer].Bankroll -= (currentWager - inSoFar);
	   players[currentPlayer].InSoFar = currentWager;
	}
	else if(move == FOLD) {
  	   top = players[currentPlayer].Name + " FOLDS!!";
	   players[currentPlayer].In = false;
	}
	else {
         // Check
  	   top = players[currentPlayer].Name + " CHECKS!!";
	   players[currentPlayer].InSoFar = 0;	
	}
   }

   public int getActivePlayersBehindYou() {
      int active = 0;
      if(currentPlayer == btnPosition) {
         active = 0;
      }
      else if(currentPlayer < btnPosition) {
         for(int x = currentPlayer + 1; x <= btnPosition; x++) {
	      if(players[x].In) {
	         active++;
 	      }
	   }
      }
      else {
	   int indx = currentPlayer + 1; 
         int stop = 8 - (currentPlayer - btnPosition);
	   for(int x = 0; x < stop; x++) {
	      indx = (indx > 7) ? 0 : indx;
	      if(players[indx].In) {
	         active++;
	      }
	      indx++;
	   }
      }
      return active;
   }

/************************************************************************ The user has clicked the applet. Figure out where and what they want.
************************************************************************/ 
   public void mouseReleased(MouseEvent e) {	
	int MEx = e.getX();
	int MEy = e.getY();
	Graphics g = getGraphics();
      if(Start.contains(MEx, MEy) && !GameInProgress) {
	   GameInProgress = true;
	   resetHand(g);
	   postBlinds(g);
	   DealCards();
	}

	if(currentPlayer == 5 && HandInProgress) {
	   int inSoFar = 0;
	   if(players[5].InSoFar > 0) {
	      inSoFar = players[5].InSoFar;
	   } 
	   if(Fold.contains(MEx, MEy) && currentWager > 0 ) {
		players[5].In = false;
		choiceMade = true;
		interval = 900;
	   }
	   if(Check.contains(MEx, MEy)) {
	      if(currentWager < 1) { 
		   players[5].InSoFar = 0;
	 	   choiceMade = true;
	      }
	      else if(btnPosition == 3 
		     && round == PREFLOP && currentWager == 3) {
	 	   choiceMade = true;
	      }
	   }
	   if(Call.contains(MEx, MEy) && currentWager > 0 ) {
	      players[5].Bankroll -= (currentWager - inSoFar);	
       	players[5].InSoFar = currentWager;
		choiceMade = true;
	   }
	   if(Bet.contains(MEx, MEy) && currentWager < 1 ) {
		if(round > FLOP) {
		   currentWager = 6;
		}
		else {
		   currentWager = 3;
		}
		players[5].InSoFar = currentWager;
 		players[5].Bankroll -= currentWager;
		choiceMade = true;
	   }
	   if(Raise.contains(MEx, MEy) && currentWager > 0 && raises < 3) {
		if(round > FLOP) {
		   currentWager += 6;
		}
		else {
		   currentWager += 3;
		}
	     	players[5].Bankroll -= (currentWager - inSoFar);
		players[5].InSoFar = currentWager;
		raises++;
	      myraises++;
		choiceMade = true;
	   }
	   if(choiceMade) {
		g.clearRect(BUTTONSX, BUTTONSY, 450, 55);
	      g.setFont(smallFont);
	      g.setColor(Color.black);
	      g.drawString(names[5], 480, 390);
	      g.drawString(names[6], 220, 390);
		turn = new Thread(this);
		turn.start();
	   }
	}
   }

   public void mousePressed(MouseEvent e) {}
   public void mouseClicked(MouseEvent e) {}
   public void mouseEntered(MouseEvent e){}
   public void mouseExited(MouseEvent e) {}

   public void destroy() {
      removeMouseListener(this);
   }
   
   public String getAppletInfo() {
	return "Omaha Hi-Lo by Jay Lipp";
   }

/************************************************************************ 			Inner classes
************************************************************************/ 

   class Card {
      // 0=Clubs, 1=Diamonds, 3=Hearts, 2=Spades
      // 11=Jack, 12=Queen, 13=King 14=Ace

	public int Value;
	public int TtlValue;
	public int Suit;
	public String Name;
	//public Image pic; 
       public int picIndex;
	private String theSuit;
	public boolean Available;

	public Card(int x) {
	   Suit = x % 4;
	   if(Suit == 0) {	
	      theSuit = "C";
	      picIndex = 0;
          }
	   else if(Suit == 1) {
	   	theSuit = "D";
 	       picIndex = 13;
         }
	   else if(Suit == 2) {
	   	theSuit = "S";
 	       picIndex = 26;
         }
	   else {
	   	theSuit = "H";
	       picIndex = 39;
	   }
	   Value = x % 13;
 	   if(Value == 0)
		Value = 13;
 	   if(Value == 1)
		Value = 14;

	   TtlValue = ((Suit * 2) * 13) + Value;
 	   Name = String.valueOf(Value) + theSuit;
          picIndex += (Value - 2);
	}

	public Card(int suit, int value) {
	   Suit = suit;
	   if(Suit == 0) {	
	      theSuit = "C";
	      picIndex = 0;
          }
	   else if(Suit == 1) {
	   	theSuit = "D";
 	       picIndex = 13;
         }
	   else if(Suit == 2) {
	   	theSuit = "S";
 	       picIndex = 26;
         }
	   else {
	   	theSuit = "H";
	       picIndex = 39;
	   }

	   Value = value;
	   TtlValue = ((Suit * 2) * 13) + Value;
 	   Name = String.valueOf(Value) + theSuit;
          picIndex += (Value - 2);
	}
   } 	

   class Player {
      public int Bankroll;
      public String Name;
      public Card Hand[] = new Card[4]; 
      public boolean In = true;
      private int Handicap;
      public int InSoFar;
      public int BestHand;
      public int BestLowHand;
      public int Tiebreakers[];

      public final int FOLD = 10;
      public final int CHECK = 20;
      public final int CALL = 30;
      public final int BET = 40;
      public final int RAISE = 50;

      public Player(String name, int type) {
	   Bankroll = 500;
	   Name = new String(name);	
	   Handicap = type;
	   InSoFar = 0;	
         Tiebreakers = new int[5];	
      }

      // Used for preflop decisions
      public int determineMove(int buttonPosition, int raises) {
	   // First check if this hand is a strong high hand contender
	   int highHand = potentialHighHand();
	   if(this.Handicap > 6) {
	      if(highHand > 2 && raises < 3) {
	         return RAISE;
	      }
	      if(highHand > 1) {
		   return CALL;
	      }
	   }  
	   if(this.Handicap > 3) {
	      if(highHand > 4 && raises < 3) {
		   return RAISE;
	      }
	      if(highHand > 2) {
	  	   return CALL;
	      }
	   }  
	   else { 
	      if(highHand > 5 && raises < 3) {
		   return RAISE;
	      }
	      if(highHand > 3) {
		   return CALL;
	      }
	   }
	   int totalPoints = 0;
	   // award points for 2 lowest cards
         sortHand(this.Hand);
	   int card1 = 0;
	   int card2 = 0;
	   int card3 = 0;
	   int card4 = 0;
	   if(this.Hand[3].Value == 14) {
            card1 = 14;
            card2 = this.Hand[0].Value;
	      if(card2 == 2) {
	         totalPoints = 20;
	      }	
	      else if(card2 == 3) {
	         totalPoints = 17;	 
	      }	
	      else if(card2 == 4) {
	         totalPoints = 13;	 
	      }	
	      else if(card2 == 5) {
	         totalPoints = 10;	 
	      }	
            card3 = this.Hand[1].Value;
            card4 = this.Hand[2].Value;
	   }
	   else {
	      card1 = this.Hand[0].Value;
	      card2 = this.Hand[1].Value;
            card3 = this.Hand[2].Value;
            card4 = this.Hand[3].Value;
	      if(card1 + card2 == 5) {
		   totalPoints = 15;
            }
	      if(card1 == 2 && card2 == 4) {
		   totalPoints = 12;
            }
	      if(card1 + card2 == 7) { // 2/5 0r 3/4
		   totalPoints = 11;
            }
	      if(card1 == 4 && card2 == 5) {
		   totalPoints = 8;
            }
	   }

	   // award points for the other 2 cards
         if(card3 == 3 || card4 == 3) {
	      if(card1 != 3 && card2 != 3) {
               totalPoints += 9;
	      }
	   }
         if(card3 == 4 || card4 == 4) {
	      if(card1 != 4 && card2 != 4) {
	 	   totalPoints += 6;
	      }
	   }
         if(card3 == 5 || card4 == 5) {
	      if(card1 != 5 && card2 != 5) {
	 	   totalPoints += 9;
	      }
	   }
	   if(card3 == 11 || card3 == 12 || card3 == 13
		|| card4 == 11 || card4 == 12 || card4 == 13 ) {
	      totalPoints += 2; 
	   }
	   else if(card3 == 6 || card3 == 10 || card4 == 6 || card4 == 10) {
	      totalPoints += 1; 
	   }
 
	   // award points for pairs
         int trips = hasTrips(this.Hand);
	  if(trips == 0) {
            int pair = 0;
            int value = 0;
	     for(int x = this.Hand.length -1; x >= 0; x--) {
               if(value == this.Hand[x].Value) {
  	           pair = value;
	           break;
	        }
	        else {
	           value = this.Hand[x].Value;
	        }
	     }
	      if(pair == 2) {
		   totalPoints += 3;
	      }
	      else if(pair > 11 || this.Handicap > 6) {
		   totalPoints += (pair/2);
	      }   
	   }	  

	   // award points for suited sets
         int fourFlush = hasFlush(this.Hand, 4);
	   int threeFlush = hasFlush(this.Hand, 3);
	   if(fourFlush == 0 && threeFlush > 0) {  
	      int flushToThe = threeFlush - 500; 
            if(flushToThe > 7) {
               flushToThe = (flushToThe - 7) / 2;
		   totalPoints += flushToThe;
	      }
	   }
	   else if(fourFlush == 0){
	      int suit = -1;
	      int oldSuit = -1;
	      int setCounter = 0;
	      for(int x = 0; x < this.Hand.length; x++) {
	         if(suit==this.Hand[x].Suit&&this.Hand[x].Suit != oldSuit) {
	            setCounter++; 
		      if(setCounter == 1) {
                     totalPoints += this.Hand[x].Value - 7;
		         oldSuit = suit;
 		         suit = -1;
		      }
		      if(setCounter == 2) {
		         if(this.Hand[x].Value > 7) {
			      totalPoints += this.Hand[x].Value - 7;
			   }
		      }
		   }
 	         else {
	            suit = this.Hand[x].Suit;
	         }
	      }
 	   }
		
	   // adjust for seating position
	   if(buttonPosition == 0) {
	      totalPoints += 4;
	   }
	   if(buttonPosition == 1) {
	      totalPoints += 2;
	   }

	   // adjust for raises
         totalPoints -= (raises == 0) ? 0 : raises * 2;

	   // adjust for handicap
         totalPoints += this.Handicap;

         if(totalPoints > 30 && raises < 3) {
	      return RAISE;  
	   }
	   else if(currentWager == this.InSoFar) {
	      return CHECK;
	   }
	   else if(totalPoints > 17) {
	      return CALL;
	   }
	   else {
	      return FOLD;     
         }
      }

      private int potentialHighHand() {
	   // A true high hand must have all 4 cards over 9 and either:
	   // 2 Pair
	   // 2 sets of suited cards
	   // 1 pair and 1 set of suited cards
     
	   int retValue = 0;
 
	   int over9 = 0; 
	   for(int i = 0; i < 4; i++) {
            if(this.Hand[i].Value > 9) {
	         over9++;
	      }
 	   }	  

	   if(over9 == 3) {
	      retValue = 1;
	   }
	   if(over9 == 4) {
	      retValue = 2;
	   }
	  
         sortHand(this.Hand);

	   // rule out trips
         int trips = hasTrips(this.Hand);
	   if(trips > 0) {
            return 0;
 	   }
 
	   // check for two pair
         int value = 0;
	   int pairCounter = 0;
	   for(int x = this.Hand.length - 1; x > -1; x--) {
            if(value == this.Hand[x].Value) {
	         pairCounter++;
	         if(pairCounter == 1) {
 		      value = 0;
		      retValue++;
		   }
		   if(pairCounter == 2) {
		      retValue++;
		   }
	      }
	      else {
	         value = this.Hand[x].Value;
	      }
	   }
	  
         // check for two suited sets
	   sortHandBySuit(this.Hand); 
	   int suit = -1;
	   int oldSuit = -1;
	   int setCounter = 0;
	   for(int x = 0; x < this.Hand.length; x++) {
	      if(suit==this.Hand[x].Suit && this.Hand[x].Suit != oldSuit) {
	         setCounter++; 
		   if(setCounter == 1) {
		      oldSuit = suit;
 		      suit = -1;
		      retValue++;
		   }
		   if(setCounter == 2) {
		      retValue++;
		   }
	      }
 	      else {
	         suit = this.Hand[x].Suit;
	      }
	   }

	   return retValue;
      }

      public Hashtable getPossibles(Card[] board) {
         // populate a hashtable with 6, 12, 0r 36 possible hands
	   // use 3 from the board and 2 from the hand
	   int size = 0;
	   for(int i = 0; i < board.length; i++) {
	      if(board[i].Available) {
		   size += 1;
	      }
	   }
	   Hashtable possible = new Hashtable();
	   if(size == 3) {	
  	      getPossibleSix(possible, board, 0); 
	   }
	   if(size > 3) {	
	      Card possBoard1[] = new Card[3];
	      possBoard1[0] = board[0];
	      possBoard1[1] = board[1];
	      possBoard1[2] = board[2];
  	      getPossibleSix(possible, possBoard1, 0); 

	      Card possBoard2[] = new Card[3];
	      possBoard2[0] = board[0];
	      possBoard2[1] = board[1];
	      possBoard2[2] = board[3];
  	      getPossibleSix(possible, possBoard2, 6); 

	      Card possBoard3[] = new Card[3];
	      possBoard3[0] = board[0];
	      possBoard3[1] = board[2];
	      possBoard3[2] = board[3];
  	      getPossibleSix(possible, possBoard3, 12); 

	      Card possBoard4[] = new Card[3];
	      possBoard4[0] = board[1];
	      possBoard4[1] = board[2];
	      possBoard4[2] = board[3];
  	      getPossibleSix(possible, possBoard4, 18); 
	   }
	   if(size == 5) {	
	      Card possBoard5[] = new Card[3];
	      possBoard5[0] = board[0];
	      possBoard5[1] = board[2];
	      possBoard5[2] = board[4];
  	      getPossibleSix(possible, possBoard5, 24); 

	      Card possBoard6[] = new Card[3];
	      possBoard6[0] = board[0];
	      possBoard6[1] = board[3];
	      possBoard6[2] = board[4];
  	      getPossibleSix(possible, possBoard6, 30); 

	      Card possBoard7[] = new Card[3];
	      possBoard7[0] = board[0];
	      possBoard7[1] = board[1];
	      possBoard7[2] = board[4];
  	      getPossibleSix(possible, possBoard7, 36); 

	      Card possBoard8[] = new Card[3];
	      possBoard8[0] = board[1];
	      possBoard8[1] = board[2];
	      possBoard8[2] = board[4];
  	      getPossibleSix(possible, possBoard8, 42);

	      Card possBoard9[] = new Card[3];
	      possBoard9[0] = board[1];
	      possBoard9[1] = board[3];
	      possBoard9[2] = board[4];
  	      getPossibleSix(possible, possBoard9, 48);

	      Card possBoard10[] = new Card[3];
	      possBoard10[0] = board[2];
	      possBoard10[1] = board[3];
	      possBoard10[2] = board[4];
  	      getPossibleSix(possible, possBoard10, 54);
	   }

	   return possible;
      }

      private void getPossibleSix(Hashtable possible, 
					Card[] board, int index) {
	   // six possibilities
         Card possHand1[] = new Card[5];
	   possHand1[0] = board[0];
	   possHand1[1] = board[1];
	   possHand1[2] = board[2];
         possHand1[3] = this.Hand[0];
         possHand1[4] = this.Hand[1];
	   possible.put(String.valueOf(index++), possHand1); 

         Card possHand2[] = new Card[5];
	   possHand2[0] = board[0];
	   possHand2[1] = board[1];
	   possHand2[2] = board[2];
         possHand2[3] = this.Hand[0];
         possHand2[4] = this.Hand[2];
	   possible.put(String.valueOf(index++), possHand2); 

         Card possHand3[] = new Card[5];
	   possHand3[0] = board[0];
	   possHand3[1] = board[1];
	   possHand3[2] = board[2];
         possHand3[3] = this.Hand[0];
         possHand3[4] = this.Hand[3];
	   possible.put(String.valueOf(index++), possHand3); 

         Card possHand4[] = new Card[5];
	   possHand4[0] = board[0];
	   possHand4[1] = board[1];
	   possHand4[2] = board[2];
         possHand4[3] = this.Hand[1];
         possHand4[4] = this.Hand[2];
	   possible.put(String.valueOf(index++), possHand4); 

         Card possHand5[] = new Card[5];
	   possHand5[0] = board[0];
	   possHand5[1] = board[1];
	   possHand5[2] = board[2];
         possHand5[3] = this.Hand[1];
         possHand5[4] = this.Hand[3];
	   possible.put(String.valueOf(index++), possHand5);  

         Card possHand6[] = new Card[5];
	   possHand6[0] = board[0];
	   possHand6[1] = board[1];
	   possHand6[2] = board[2];
         possHand6[3] = this.Hand[2];
         possHand6[4] = this.Hand[3];
	   possible.put(String.valueOf(index++), possHand6);  
      }
   } 	
}
