Android Open Source - pokerCCF Table






From Project

Back to project page pokerCCF.

License

The source code is released under:

Copyright (c) 2011-2014, Intel Corporation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redist...

If you think the Android project pokerCCF listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

// This file is part of the 'texasholdem' project, an open source
// Texas Hold'em poker application written in Java.
///*from  ww w  .  ja  v  a 2  s .c  o m*/
// Copyright 2009 Oscar Stigter
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file is part of the 'texasholdem' project, an open source
// Texas Hold'em poker application written in Java.
//
// Copyright 2009 Oscar Stigter
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lo.wolo.pokerengine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import android.util.Log;
import lo.wolo.pokerccf.CCFManager;
import lo.wolo.pokerccf.RemoteUser;
import lo.wolo.pokerccf.ServerController;
import lo.wolo.pokerengine.actions.Action;
import lo.wolo.pokerengine.actions.BetAction;
import lo.wolo.pokerengine.actions.CallAction;
import lo.wolo.pokerengine.actions.CheckAction;
import lo.wolo.pokerengine.actions.FoldAction;
import lo.wolo.pokerengine.actions.RaiseAction;

/**
 * Limit Texas Hold'em poker table. <br />
 * <br />
 * 
 * This class forms the heart of the poker engine. It controls the game flow for a single poker table.
 * 
 * @author Oscar Stigter
 */
public class Table {
    
  private static final String TAG = "Table"; 
  
    /** In fixed-limit games, the maximum number of raises per betting round. */
    private static final int MAX_RAISES = 3;
    
    /** Whether players will always call the showdown, or fold when no chance. */
    private static final boolean ALWAYS_CALL_SHOWDOWN = false;
    
    /** Table type (poker variant). */
    private final TableType tableType;
    
    /** The size of the big blind. */
    private final int bigBlind;
    
    /** The players at the table. */
    private final List<Player> players;
    
    /** The active players in the current hand. */
    private final List<Player> activePlayers;
    
    /** The deck of cards. */
    private final Deck deck;
    
    /** The community cards on the board. */
    private final List<Card> board;
    
    /** The current dealer position. */
    private int dealerPosition;

    /** The current dealer. */
    private Player dealer;

    /** The position of the acting player. */
    private int actorPosition;
    
    /** The acting player. */
    private Player actor;

    /** The minimum bet in the current hand. */
    private int minBet;
    
    /** The current bet in the current hand. */
    private int bet;
    
    /** All pots in the current hand (main pot and any side pots). */
    private final List<Pot> pots;
    
    /** The player who bet or raised last (aggressor). */
    private Player lastBettor;
    
    /** Number of raises in the current betting round. */
    private int raises;
    
    private CCFManager serviceManager;
    private ArrayList<RemoteUser> remoteUsers;
    private ServerController serverController;
    
    /**
     * Constructor.
     * 
     * @param bigBlind
     *            The size of the big blind.
     */
    public Table(TableType type, int bigBlind, CCFManager serviceManager, ServerController serverController) {
        this.tableType = type;
        this.bigBlind = bigBlind;
        players = new ArrayList<Player>();
        activePlayers = new ArrayList<Player>();
        deck = new Deck();
        board = new ArrayList<Card>();
        pots = new ArrayList<Pot>();
        
        //initialize remote users
        this.serviceManager = serviceManager;
        this.remoteUsers = serviceManager.getRemoteUsers();
        this.serverController = serverController;
        
    }
    
    /**
     * Adds a player.
     * 
     * @param player
     *            The player.
     */
    public void addPlayer(Player player) {
        players.add(player);
    }
    
    /**
     * Main game loop.
     */
    public void run() {
        Log.i("lolbug", "Displaying all the players...");
        for (Player p : players) {
          int id = Integer.parseInt(p.getName());
          ArrayList<RemoteUser> remoteUserList = serviceManager.getRemoteUsers();
          RemoteUser u = remoteUserList.get(id);
          String s = u.getSession().getUserName();
          serverController.setPlayer(s, id+1);
          Log.i("lolbug", "Username " + id + " = " + s);
        }
        Log.i("lolbug", "Finished displaying players");
        
      
        for (Player player : players) {
            player.getClient().joinedTable(tableType, bigBlind, players);
        }
        Log.d(TAG,"joined tables");
        dealerPosition = -1;
        actorPosition = -1;
        while (true) {
            int noOfActivePlayers = 0;
            for (Player player : players) {
                if (player.getCash() >= bigBlind) {
                    noOfActivePlayers++;
                }
            }
            Log.d(TAG,"Number of Active players: " + Integer.toString(noOfActivePlayers));
            if (noOfActivePlayers > 1) {
              Log.d(TAG,"Start Play hand");
                playHand();
            } else {
                break;
            }
        }
        Log.d(TAG,"Game Over");
        // Game over.

        //REMOVED SET CARDS TO -1 HERE
                
        board.clear();
        pots.clear();
        bet = 0;
        notifyBoardUpdated();
        for (Player player : players) {
            player.resetHand();
        }
        notifyPlayersUpdated(false);
        notifyMessage("Game over.");
    }
    
    /**
     * Plays a single hand.
     */
    private void playHand() {
        for (int i = 1; i <= 5; i++) serverController.setCard(-1, i);
        resetHand();
        
        int id = Integer.parseInt(actor.getName());
        serverController.sendMessage(id, "role dealer");
        // Small blind.
        if (activePlayers.size() > 2) {
            rotateActor();
        }
        id = Integer.parseInt(actor.getName());
        serverController.sendMessage(id, "role smallBlind");
        postSmallBlind();
        
        // Big blind.
        
        rotateActor();
        id = Integer.parseInt(actor.getName());
        serverController.sendMessage(id, "role bigBlind");
        postBigBlind();
        
        // Pre-Flop.
        dealHoleCards();
        doBettingRound();
        
        // Flop.
        if (activePlayers.size() > 1) {
          Log.d(TAG,"ActivePlayers: " + Integer.toString(activePlayers.size()));
            bet = 0;
            dealCommunityCards("Flop", 3);
            
            for (Card cd :board) Log.i("lolbug", Integer.toString(cd.hashCode()));
            
            serverController.setCard(board.get(0).hashCode(), 1);
            serverController.setCard(board.get(1).hashCode(), 2);
            serverController.setCard(board.get(2).hashCode(), 3);
            
            minBet = bigBlind;
            doBettingRound();

            // Turn.
            if (activePlayers.size() > 1) {
                bet = 0;
                dealCommunityCards("Turn", 1);
                
                Log.i("lolbug", Integer.toString(board.get(3).hashCode()));
                serverController.setCard(board.get(3).hashCode(), 4);
                
                if (tableType == TableType.FIXED_LIMIT) {
                    minBet = 2 * bigBlind;
                } else {
                    minBet = bigBlind;
                }
                doBettingRound();

                // River.
                if (activePlayers.size() > 1) {
                    bet = 0;
                    dealCommunityCards("River", 1);
                    
                    Log.i("lolbug", Integer.toString(board.get(4).hashCode()));
                    serverController.setCard(board.get(4).hashCode(), 5);
                    
                    if (tableType == TableType.FIXED_LIMIT) {
                        minBet = 2 * bigBlind;
                    } else {
                        minBet = bigBlind;
                    }
                    doBettingRound();

                    // Showdown.
                    if (activePlayers.size() > 1) {
                        bet = 0;
                        minBet = bigBlind;
                        doShowdown();
                    }
                }
            }
        }
    }
    
    /**
     * Resets the game for a new hand.
     */
    private void resetHand() {
        // Clear the board.
        board.clear();
        pots.clear();
        notifyBoardUpdated();
        
        // Determine the active players.
        activePlayers.clear();
        for (Player player : players) {
            player.resetHand();
            // Player must be able to afford at least the big blind.
            if (player.getCash() >= bigBlind) {
                activePlayers.add(player);
            }
        }
        
        // Rotate the dealer button.
        dealerPosition = (dealerPosition + 1) % activePlayers.size();
        dealer = activePlayers.get(dealerPosition);
                
        // Shuffle the deck.
        deck.shuffle();

        // Determine the first player to act.
        actorPosition = dealerPosition;
        actor = activePlayers.get(actorPosition);
        
        // Set the initial bet to the big blind.
        minBet = bigBlind;
        bet = minBet;
        
        // Notify all clients a new hand has started.
        for (Player player : players) {
            player.getClient().handStarted(dealer);
        }
        notifyPlayersUpdated(false);
        notifyMessage("New hand, %s is the dealer.", dealer);
    }

    /**
     * Rotates the position of the player in turn (the actor).
     */
    private void rotateActor() {
        actorPosition = (actorPosition + 1) % activePlayers.size();
        actor = activePlayers.get(actorPosition);
        for (Player player : players) {
            player.getClient().actorRotated(actor);
        }
    }
    
    /**
     * Posts the small blind.
     */
    private void postSmallBlind() {
        final int smallBlind = bigBlind / 2;
        actor.postSmallBlind(smallBlind);
        contributePot(smallBlind);
        notifyBoardUpdated();
        notifyPlayerActed();
    }
    
    /**
     * Posts the big blind.
     */
    private void postBigBlind() {
        actor.postBigBlind(bigBlind);
        contributePot(bigBlind);
        notifyBoardUpdated();
        notifyPlayerActed();
    }
    
    /**
     * Deals the Hole Cards.
     */
    private void dealHoleCards() {
        for (Player player : activePlayers) {
            player.setCards(deck.deal(2));
            int id = Integer.parseInt(player.getName());
            serverController.sendCards(id, player.getCards());
            serverController.sendMessage(id, "money " + player.getCash());
        }
        
        System.out.println();
        notifyPlayersUpdated(false);
        notifyMessage("%s deals the hole cards.", dealer);
    }
    
    /**
     * Deals a number of community cards.
     * 
     * @param phaseName
     *            The name of the phase.
     * @param noOfCards
     *            The number of cards to deal.
     */
    private void dealCommunityCards(String phaseName, int noOfCards) {
        for (int i = 0; i < noOfCards; i++) {
            board.add(deck.deal());
        }
        notifyPlayersUpdated(false);
        notifyMessage("%s deals the %s.", dealer, phaseName);
    }
    
    /**
     * Performs a betting round.
     */
    private void doBettingRound() {
      Log.d(TAG,"Betting Round started");
        // Determine the number of active players.
        int playersToAct = activePlayers.size();
        // Determine the initial player and bet size.
        if (board.size() == 0) {
            // Pre-Flop; player left of big blind starts, bet is the big blind.
            bet = bigBlind;
        } else {
            // Otherwise, player left of dealer starts, no initial bet.
            actorPosition = dealerPosition;
            bet = 0;
        }
        
        /*if (playersToAct == 2) {  //removed, fix by IW
            // Heads Up mode; player who is not the dealer starts.
            actorPosition = dealerPosition;
        }*/
        
        lastBettor = null;
        raises = 0;
        notifyBoardUpdated();
        
        while (playersToAct > 0) {
          
            rotateActor();
            Action action = null;
            if (actor.isAllIn()) {
                // Player is all-in, so must check.
                action = Action.CHECK;
                playersToAct--;
            } else {
                // Otherwise allow client to act.
                Set<Action> allowedActions = getAllowedActions(actor);
                //Send Allowed Actions to remoteUsers
                int actorID = Integer.parseInt(actor.getName());
                Log.d(TAG,"actorID " + actorID);
                RemoteUser actorRemoteUser = remoteUsers.get(actorID);
                
                if (actorRemoteUser.getsessionState() == CCFManager.SessionState.CONNECTED) {
                  Log.d(TAG,actorRemoteUser.toString() + " isConected");
                  serverController.sendActionsAllowed(actorID,allowedActions);
                  // Highlight the user name
                  serverController.highlightPlayer(actorID);
                } else {
                  Log.d("Table","Actor: " + actor.getName() + " was NOTCONECTED");
                }
                
                //Sends money message
                serverController.sendMessage(actorID, "money " + actor.getCash());
                
                //Pool player's next action
                ClientCCF actorClient = ((ClientCCF)actor.getClient());
                while (actorClient.getNextAction() == null) {
                  try {
            Thread.sleep(300);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
                  actorClient.setNextAction(serviceManager.actionList.get(actorID));
                  serviceManager.actionList.set(actorID,null);
                }
                //Action has been set
                
                action = actor.getClient().act(minBet, bet, allowedActions);
                // Verify chosen action to guard against broken clients (accidental or on purpose).
                Log.d(TAG,"Action is: " + action.getName());
                Log.d(TAG,"allowedActions: ");
                for (Action a : allowedActions) {
                  Log.d(TAG,a.getName());
                }
                
                Iterator<Action> it = allowedActions.iterator();
                boolean found = false;
                while (it.hasNext() && !found)
                  found = it.next().equals(action);
                if (!found)
                  throw new IllegalStateException(String.format("Player '%s' acted with illegal %s action", actor, action));

                // TODO check Illegal actions
//                if (!allowedActions.contains(action)) {
//                    if (!(action instanceof BetAction && allowedActions.contains(Action.BET)) && !(action instanceof RaiseAction && allowedActions.contains(Action.RAISE))) {
//                        throw new IllegalStateException(String.format("Player '%s' acted with illegal %s action", actor, action));
//                    }
//                }
                playersToAct--;
                if (action instanceof CheckAction) {
                    // Do nothing.
                } else if (action instanceof CallAction) {
                    int betIncrement = bet - actor.getBet();
                    if (betIncrement > actor.getCash()) {
                        betIncrement = actor.getCash();
                    }
                    actor.payCash(betIncrement);
                    actor.setBet(actor.getBet() + betIncrement);
                    contributePot(betIncrement);
                } else if (action instanceof BetAction) {
                    int amount = (tableType == TableType.FIXED_LIMIT) ? minBet : action.getAmount();
                    if (amount < minBet && amount < actor.getCash()) {
                        throw new IllegalStateException("Illegal client action: bet less than minimum bet!");
                    }
                    if (amount > actor.getCash() && actor.getCash() >= minBet) {
                        throw new IllegalStateException("Illegal client action: bet more cash than you own!");
                    }
                    bet = amount;
                    serverController.setBetText(bet);
                    minBet = amount;
                    int betIncrement = bet - actor.getBet();
                    if (betIncrement > actor.getCash()) {
                        betIncrement = actor.getCash();
                    }
                    actor.setBet(bet);
                    actor.payCash(betIncrement);
                    contributePot(betIncrement);
                    lastBettor = actor;
                    playersToAct = (tableType == TableType.FIXED_LIMIT) ? activePlayers.size() : (activePlayers.size() - 1);
                } else if (action instanceof RaiseAction) {
                    int amount = (tableType == TableType.FIXED_LIMIT) ? minBet : action.getAmount();
                    if (amount < minBet && amount < actor.getCash()) {
                        throw new IllegalStateException("Illegal client action: raise less than minimum bet!");
                    }
                    if (amount > actor.getCash() && actor.getCash() >= minBet) {
                        throw new IllegalStateException("Illegal client action: raise more cash than you own!");
                    }
                    bet += amount;
                    serverController.setBetText(bet);
                    minBet = amount;
                    int betIncrement = bet - actor.getBet();
                    if (betIncrement > actor.getCash()) {
                        betIncrement = actor.getCash();
                    }
                    actor.setBet(bet);
                    actor.payCash(betIncrement);
                    contributePot(betIncrement);
                    lastBettor = actor;
                    raises++;
                    if (tableType == TableType.FIXED_LIMIT && (raises < MAX_RAISES || activePlayers.size() == 2)) {
                        // All players get another turn.
                        playersToAct = activePlayers.size();
                    } else {
                        // Max. number of raises reached; other players get one more turn.
                        playersToAct = activePlayers.size() - 1;
                    }
                } else if (action instanceof FoldAction) {
                    actor.setCards(null);
                    activePlayers.remove(actor);
                    actorPosition--;
                    if (activePlayers.size() == 1) {
                        // Only one player left, so he wins the entire pot.
                        notifyBoardUpdated();
                        notifyPlayerActed();
                        Player winner = activePlayers.get(0);
                        int amount = getTotalPot();
                        winner.win(amount);
                        notifyBoardUpdated();
                        notifyMessage("%s wins $ %d.", winner, amount);
                        playersToAct = 0;
                    }
                } else {
                    // Programming error, should never happen.
                    throw new IllegalStateException("Invalid action: " + action);
                }
            }
            actor.setAction(action);
            if (activePlayers.size() > 1) {
                notifyBoardUpdated();
                notifyPlayerActed();
            }
        }
        
        // Reset player's bets.
        for (Player player : activePlayers) {
            player.resetBet();
        }
        notifyBoardUpdated();
        notifyPlayersUpdated(false);
    }
    
    /**
     * Returns the allowed actions of a specific player.
     * 
     * @param player
     *            The player.
     * 
     * @return The allowed actions.
     */
    private Set<Action> getAllowedActions(Player player) {
        Set<Action> actions = new HashSet<Action>();
        if (player.isAllIn()) {
            actions.add(Action.CHECK);
        } else {
            int actorBet = actor.getBet();
            if (bet == 0) {
                actions.add(Action.CHECK);
                if (tableType == TableType.NO_LIMIT || raises < MAX_RAISES || activePlayers.size() == 2) {
                    actions.add(Action.BET);
                }
            } else {
                if (actorBet < bet) {
                    actions.add(Action.CALL);
                    if (tableType == TableType.NO_LIMIT || raises < MAX_RAISES || activePlayers.size() == 2) {
                        actions.add(Action.RAISE);
                    }
                } else {
                    actions.add(Action.CHECK);
                    if (tableType == TableType.NO_LIMIT || raises < MAX_RAISES || activePlayers.size() == 2) {
                        actions.add(Action.RAISE);
                    }
                }
            }
            actions.add(Action.FOLD);
        }
        return actions;
    }
    
    /**
     * Contributes to the pot.
     * 
     * @param amount
     *            The amount to contribute.
     */
    private void contributePot(int amount) {
        for (Pot pot : pots) {
            if (!pot.hasContributer(actor)) {
                int potBet = pot.getBet();
                if (amount >= potBet) {
                    // Regular call, bet or raise.
                    pot.addContributer(actor);
                    amount -= pot.getBet();
                } else {
                    // Partial call (all-in); redistribute pots.
                    pots.add(pot.split(actor, amount));
                    amount = 0;
                }
            }
            if (amount <= 0) {
                break;
            }
        }
        if (amount > 0) {
            Pot pot = new Pot(amount);
            pot.addContributer(actor);
            pots.add(pot);
        }
        int tamount = 0;
        for (int i = 0; i < pots.size(); i++) {
          tamount += pots.get(i).getValue();
        }
        
        if (pots.size() >= 1) 
          serverController.setPotText(tamount);
    }
    
    /**
     * Performs the showdown.
     */
    private void doShowdown() {
//        System.out.println("\n[DEBUG] Pots:");
//        for (Pot pot : pots) {
//            System.out.format("  %s\n", pot);
//        }
//        System.out.format("[DEBUG]  Total: %d\n", getTotalPot());
        
        // Determine show order; start with all-in players...
        List<Player> showingPlayers = new ArrayList<Player>();
        for (Pot pot : pots) {
            for (Player contributor : pot.getContributors()) {
                if (!showingPlayers.contains(contributor) && contributor.isAllIn()) {
                    showingPlayers.add(contributor);
                }
            }
        }
        // ...then last player to bet or raise (aggressor)...
        if (lastBettor != null) {
            if (!showingPlayers.contains(lastBettor)) {
                showingPlayers.add(lastBettor);
            }
        }
        //...and finally the remaining players, starting left of the button.
        int pos = (dealerPosition + 1) % activePlayers.size();
        while (showingPlayers.size() < activePlayers.size()) {
            Player player = activePlayers.get(pos);
            if (!showingPlayers.contains(player)) {
                showingPlayers.add(player);
            }
            pos = (pos + 1) % activePlayers.size();
        }
        
        // Players automatically show or fold in order.
        boolean firstToShow = true;
        int bestHandValue = -1;
        for (Player playerToShow : showingPlayers) {
            Hand hand = new Hand(board);
            hand.addCards(playerToShow.getCards());
            HandValue handValue = new HandValue(hand);
            boolean doShow = ALWAYS_CALL_SHOWDOWN;
            if (!doShow) {
                if (playerToShow.isAllIn()) {
                    // All-in players must always show.
                    doShow = true;
                    firstToShow = false;
                } else if (firstToShow) {
                    // First player must always show.
                    doShow = true;
                    bestHandValue = handValue.getValue();
                    firstToShow = false;
                } else {
                    // Remaining players only show when having a chance to win.
                    if (handValue.getValue() >= bestHandValue) {
                        doShow = true;
                        bestHandValue = handValue.getValue();
                    }
                }
            }
            if (doShow) {
                // Show hand.
                for (Player player : players) {
                    player.getClient().playerUpdated(playerToShow);
                }
                notifyMessage("%s has %s.", playerToShow, handValue.getDescription());
            } else {
                // Fold.
                playerToShow.setCards(null);
                activePlayers.remove(playerToShow);
                for (Player player : players) {
                    if (player.equals(playerToShow)) {
                        player.getClient().playerUpdated(playerToShow);
                    } else {
                        // Hide secret information to other players.
                        player.getClient().playerUpdated(playerToShow.publicClone());
                    }
                }
                notifyMessage("%s folds.", playerToShow);
            }
        }
        
        // Sort players by hand value (highest to lowest).
        Map<HandValue, List<Player>> rankedPlayers = new TreeMap<HandValue, List<Player>>();
        for (Player player : activePlayers) {
            // Create a hand with the community cards and the player's hole cards.
            Hand hand = new Hand(board);
            hand.addCards(player.getCards());
            // Store the player together with other players with the same hand value.
            HandValue handValue = new HandValue(hand);
//            System.out.format("[DEBUG] %s: %s\n", player, handValue);
            List<Player> playerList = rankedPlayers.get(handValue);
            if (playerList == null) {
                playerList = new ArrayList<Player>();
            }
            playerList.add(player);
            rankedPlayers.put(handValue, playerList);
        }

        // Per rank (single or multiple winners), calculate pot distribution.
        int totalPot = getTotalPot();
        Map<Player, Integer> potDivision = new HashMap<Player, Integer>();
        for (HandValue handValue : rankedPlayers.keySet()) {
            List<Player> winners = rankedPlayers.get(handValue);
            for (Pot pot : pots) {
                // Determine how many winners share this pot.
                int noOfWinnersInPot = 0;
                for (Player winner : winners) {
                    if (pot.hasContributer(winner)) {
                        noOfWinnersInPot++;
                    }
                }
                if (noOfWinnersInPot > 0) {
                    // Divide pot over winners.
                    int potShare = pot.getValue() / noOfWinnersInPot;
                    for (Player winner : winners) {
                        if (pot.hasContributer(winner)) {
                            Integer oldShare = potDivision.get(winner);
                            if (oldShare != null) {
                                potDivision.put(winner, oldShare + potShare);
                            } else {
                                potDivision.put(winner, potShare);
                            }
                            
                        }
                    }
                    // Determine if we have any odd chips left in the pot.
                    int oddChips = pot.getValue() % noOfWinnersInPot;
                    if (oddChips > 0) {
                        // Divide odd chips over winners, starting left of the dealer.
                        pos = dealerPosition;
                        while (oddChips > 0) {
                            pos = (pos + 1) % activePlayers.size();
                            Player winner = activePlayers.get(pos);
                            Integer oldShare = potDivision.get(winner);
                            if (oldShare != null) {
                                potDivision.put(winner, oldShare + 1);
//                                System.out.format("[DEBUG] %s receives an odd chip from the pot.\n", winner);
                                oddChips--;
                            }
                        }
                        
                    }
                    pot.clear();
                }
            }
        }
        
        // Divide winnings.
        StringBuilder winnerText = new StringBuilder();
        int totalWon = 0;
        for (Player winner : potDivision.keySet()) {
            int potShare = potDivision.get(winner);
            winner.win(potShare);
            totalWon += potShare;
            if (winnerText.length() > 0) {
                winnerText.append(", ");
            }
            winnerText.append(String.format("%s wins $ %d", winner, potShare));
            notifyPlayersUpdated(true);
        }
        winnerText.append('.');
        notifyMessage(winnerText.toString());
        
        // Sanity check.
        if (totalWon != totalPot) {
            throw new IllegalStateException("Incorrect pot division!");
        }
    }
    
    /**
     * Notifies listeners with a custom game message.
     * 
     * @param message
     *            The formatted message.
     * @param args
     *            Any arguments.
     */
    private void notifyMessage(String message, Object... args) {
        message = String.format(message, args);
        for (Player player : players) {
            player.getClient().messageReceived(message);
        }
    }
    
    /**
     * Notifies clients that the board has been updated.
     */
    private void notifyBoardUpdated() {
        int pot = getTotalPot();
        for (Player player : players) {
            player.getClient().boardUpdated(board, bet, pot);
        }
    }
    
    /**
     * Returns the total pot size.
     * 
     * @return The total pot size.
     */
    private int getTotalPot() {
        int totalPot = 0;
        for (Pot pot : pots) {
            totalPot += pot.getValue();
        }
        return totalPot;
    }

    /**
     * Notifies clients that one or more players have been updated. <br />
     * <br />
     * 
     * A player's secret information is only sent its own client; other clients
     * see only a player's public information.
     * 
     * @param showdown
     *            Whether we are at the showdown phase.
     */
    private void notifyPlayersUpdated(boolean showdown) {
        for (Player playerToNotify : players) {
            for (Player player : players) {
                if (!showdown && !player.equals(playerToNotify)) {
                    // Hide secret information to other players.
                    player = player.publicClone();
                }
                playerToNotify.getClient().playerUpdated(player);
            }
        }
    }
    
    /**
     * Notifies clients that a player has acted.
     */
    private void notifyPlayerActed() {
        for (Player p : players) {
            Player playerInfo = p.equals(actor) ? actor : actor.publicClone();
            p.getClient().playerActed(playerInfo);
        }
    }
    
}




Java Source Code List

com.intel.friend.invitation.FriendInvitationBase.java
com.intel.friend.invitation.FriendInvitationError.java
com.intel.friend.invitation.FriendInvitationMessage.java
com.intel.friend.invitation.FriendInvitationService.java
com.intel.friend.invitation.FriendReceiveInvitationActivity.java
com.intel.friend.invitation.FriendReceiveInvitationState.java
com.intel.friend.invitation.FriendSendInvitationActivity.java
com.intel.friend.invitation.FriendSendInvitationState.java
com.intel.friend.invitation.IDataStreamEventListener.java
com.intel.friend.invitation.IFriendInvitationEventListener.java
com.intel.friend.invitation.ReadEngine.java
com.intel.friend.invitation.SendInvitationDialogFragment.java
com.intel.friend.invitation.WriteEngine.java
com.intel.inproclib.user_details.UpdateUserDetailsActivity.java
com.intel.inproclib.user_details.UserSettingsFragment.java
com.intel.inproclib.utility.ImageViewNoLayoutRefresh.java
com.intel.inproclib.utility.InProcConstants.java
com.intel.inproclib.utility.InProc_ImageManager_Assets.java
com.intel.inproclib.utility.InProc_ListViewImageManager_FileSystem.java
com.intel.inproclib.utility.InProc_ListViewImageManager.java
com.intel.inproclib.utility.MaxLengthTextWatcher.java
com.intel.inproclib.utility.NoNewlineEditText.java
com.intel.startup.AvatarFragment.java
com.intel.startup.AvatarPickerFragment.java
com.intel.startup.CloudAuthorizationActivity.java
com.intel.startup.DeviceNameFragment.java
com.intel.startup.NewUnboxFragment.java
com.intel.startup.NewUnbox.java
com.intel.startup.StartupFragment.java
com.intel.startup.UserNameFragment.java
com.intel.ux.ImageUtilities.java
com.intel.ux.StcSessionListAdapter.java
lo.wolo.pokerccf.AbstractServiceUsingActivity.java
lo.wolo.pokerccf.CCFManager.java
lo.wolo.pokerccf.ChatAdapter.java
lo.wolo.pokerccf.Constants.java
lo.wolo.pokerccf.DiscoveryNodeActivity.java
lo.wolo.pokerccf.IServiceIOListener.java
lo.wolo.pokerccf.ISimpleDiscoveryListener.java
lo.wolo.pokerccf.MultiConnectRegisterApp.java
lo.wolo.pokerccf.NodeListAdapter.java
lo.wolo.pokerccf.NodeWrapper.java
lo.wolo.pokerccf.ReadEngine.java
lo.wolo.pokerccf.RemoteUser.java
lo.wolo.pokerccf.ServerController.java
lo.wolo.pokerccf.SessionAdapter.java
lo.wolo.pokerccf.WriteEngine.java
lo.wolo.pokerengine.Card.java
lo.wolo.pokerengine.ClientCCF.java
lo.wolo.pokerengine.Client.java
lo.wolo.pokerengine.Deck.java
lo.wolo.pokerengine.HandEvaluator.java
lo.wolo.pokerengine.HandValueType.java
lo.wolo.pokerengine.HandValue.java
lo.wolo.pokerengine.Hand.java
lo.wolo.pokerengine.Player.java
lo.wolo.pokerengine.Pot.java
lo.wolo.pokerengine.TableType.java
lo.wolo.pokerengine.Table.java
lo.wolo.pokerengine.actions.Action.java
lo.wolo.pokerengine.actions.AllInAction.java
lo.wolo.pokerengine.actions.BetAction.java
lo.wolo.pokerengine.actions.BigBlindAction.java
lo.wolo.pokerengine.actions.CallAction.java
lo.wolo.pokerengine.actions.CheckAction.java
lo.wolo.pokerengine.actions.ContinueAction.java
lo.wolo.pokerengine.actions.FoldAction.java
lo.wolo.pokerengine.actions.RaiseAction.java
lo.wolo.pokerengine.actions.SmallBlindAction.java
lo.wolo.pokerengine.bots.BasicBot.java
lo.wolo.pokerengine.bots.Bot.java
lo.wolo.pokerengine.bots.DummyBot.java
lo.wolo.pokerengine.util.PokerUtils.java