import java.util.ArrayList; public class PlayerIMPL implements Player, Runnable { //fields private ArrayList players; //the array of players private int chips = 0; //the player's number of chips. private int playerNumber; //the player's number. private int numCards; //current number of cards given. private Card[] hand = new Card[Card.HAND_SIZE]; //the player's hand of cards. private int[] payment = new int[Game.numPlayers ]; //total of payments you owe. public static int numberForNewGame = 0; //number of players ready for a new game public int totalPayments = 0; //this will be used to get the total that the players paid out. private boolean finished = false; //monitors private Object readyToCompare = new Object(); //monitor for having all of the threads ready to compute. private Object myChipsLock = new Object(); //monitor for my chips private Object theirChipsLock = new Object(); //monitor for the other player's chips. private static boolean newGame = true; //monitor for creating the new game. public static Object readyForNewGame = new Object(); //monitor for when the players are ready for a new game. //constructor public PlayerIMPL(int chips, int playerNumber, ArrayList players) { this.players = players; this.chips = chips; this.playerNumber = playerNumber + 1; } //threaded method. public void run() { while(!finished) { //Get the cards for all of the players. for (int i=0; i < Card.HAND_SIZE; i++) { synchronized (readyToCompare) { hand[i] = Game.dealer.drawCard(); numCards++; readyToCompare.notifyAll(); } } //compare the hands for(int x=0; x < Game.numPlayers; x++) { if (x+1 != playerNumber) { //get the totals. PlayerIMPL opponent = players.get(x); payment[x] = opponent.compareHands(hand); //if you won, your opponent pays you. (negative means you won in this case.) if (payment[x] < 0) { payment[x] *= -1; //make the amounts paid positive. //remove from your stack synchronized(myChipsLock) { opponent.chips -= payment[x]; } //add to their stack. receivePayment(payment[x]); //add to the total paid out opponent.totalPayments += payment[x]; } } } //determine if the player is the winner String output = Game.gameNumber + " " + playerNumber + " " + Card.toString(hand) + " " + chips; if(totalPayments == 0) { output += "*"; } //output the final game info. System.out.println(output); //ready for a new game, is everyone else?? synchronized(readyForNewGame) { newGame = false; //must remain false for the loop to work. numberForNewGame++; //not every player is ready for a new game. while((PlayerIMPL.numberForNewGame < Game.numPlayers) && !newGame) { try { readyForNewGame.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //last player starts the new game. if(numberForNewGame == Game.numPlayers) { Game.gameNumber++; Game.dealer.newHand(); newGame = true; numberForNewGame = 0; //clear the players cards for(int x=0; x < Game.numPlayers; x++) { //check for those who've retired. hasRetired(); //reset the number of cards so they can play again. players.get(x).numCards = 0; //reset the payments. players.get(x).totalPayments =0; } readyForNewGame.notifyAll(); } } } System.out.println("finished!"); } public int compareHands(Card[] opponentsCards) { //wait until everony has a card to cp synchronized (readyToCompare) { //wait until every player has their cards. while (numCards < Card.HAND_SIZE) { try { readyToCompare.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //return the amount of cash that is owed. return Card.compareHands(opponentsCards, hand); } } public boolean hasRetired() { for(int x=0; x < Game.numPlayers; x++) { if (players.get(x).chips < (Game.numPlayers*8)-1) { System.out.println("player " + players.get(x).playerNumber + " retired"); Game.players.remove(players.get(x).playerNumber-1); Game.numPlayers--; players.get(x).finished = true; } } return true; } public void receivePayment(int payment) { synchronized(theirChipsLock) { //give the payment to the opponent. chips = chips + payment; } } }