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.
//monitors
private Object readyToCompare = new Object(); //monitor for having all of the threads ready to compute.
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.
public static Object retiring = new Object(); //monitor for when the players are ready for a new game.
public static Object playerLock = new Object();
//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(!hasRetired() && Game.numPlayers > 1)
{
//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++)
{
PlayerIMPL opponent = players.get(x);
synchronized(playerLock)
{
if(!Game.playersRetired.contains(x))
{
if(x+1 != playerNumber)
{
//compare your hand to the other player's.
payment[x] = opponent.compareHands(hand);
opponent.receivePayment(payment[x]);
}
}
else
{
System.out.println(playerNumber);
}
}
//if the number returned is negative, then the opponent won... add to the total paid out.
if (payment[x] < 0)
{
opponent.totalPayments += (-1 * payment[x]);
}
}
//start a new game.
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 runs everything
if(numberForNewGame == Game.numPlayers)
{
//show the outputs
for (int x=0; x < Game.numPlayers; x++)
{
//determine if the player is the winner
String output = Game.gameNumber + " " + players.get(x).playerNumber + " " + Card.toString(players.get(x).hand) + " " + players.get(x).chips;
if(players.get(x).totalPayments == 0)
{
output += "*";
}
//TODO uncomment
//output the final game info.
System.out.println(output);
}
//start a new game.
Game.gameNumber++;
Game.dealer.newHand();
newGame = true;
numberForNewGame = 0; //reset this number before the rest of the threads get woken up.
//clear the players cards
for(int x=0; x < Game.numPlayers; x++)
{
if (!Game.playersRetired.contains(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()
{
if (chips < ((Game.numPlayers-1)*8))
{
Game.playersRetired.add(playerNumber);
Game.numPlayers--;
System.out.println(playerNumber + " retiring! " + Game.numPlayers + " left");
return true;
}
else
return false;
}
public void receivePayment(int payment)
{
synchronized(theirChipsLock)
{
chips += payment;
}
}
}