import java.util.ArrayList;
public class PlayerIMPL implements Player, Runnable
{
//fields
private ArrayList <PlayerIMPL> 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 <PlayerIMPL> 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;
//check if the player needs to retire.
for(int i=0; i < Game.numPlayers; i++)
{
if(players.get(i).chips < (8 * Game.numPlayers))
{
//retire the play
players.get(i).hasRetired();
//if there's only one player left stop the thread.
if(Game.playersActive <= 1)
{
finished = true;
}
}
}
//clear the players cards
for(int x=0; x < Game.numPlayers; x++)
{
//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()
{
Game.players.remove(playerNumber-1);
Game.numPlayers--;
return false;
}
public void receivePayment(int payment)
{
synchronized(theirChipsLock)
{
//give the payment to the opponent.
chips = chips + payment;
}
}
}