Search in sources :

Example 51 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCGameMessageHandler method handleENDTURN.

// / Flow of Game ///
/**
 * handle "end turn" message.
 * This normally ends a player's normal turn (phase {@link SOCGame#PLAY1}).
 * On the 6-player board, it ends their placements during the
 * {@link SOCGame#SPECIAL_BUILDING Special Building Phase}.
 *
 * @param c  the connection that sent the message
 * @param mes  the message
 * @since 1.0.0
 */
private void handleENDTURN(SOCGame ga, Connection c, final SOCEndTurn mes) {
    final String gname = ga.getName();
    if (ga.isDebugFreePlacement()) {
        // turn that off before ending current turn
        handler.processDebugCommand_freePlace(c, gname, "0");
    }
    ga.takeMonitor();
    try {
        final String plName = c.getData();
        if (ga.getGameState() == SOCGame.OVER) {
            // Should not happen; is here just in case.
            SOCPlayer pl = ga.getPlayer(plName);
            if (pl != null) {
                String msg = ga.gameOverMessageToPlayer(pl);
                // msg = "The game is over; you are the winner!";
                // msg = "The game is over; <someone> won.";
                // msg = "The game is over; no one won.";
                srv.messageToPlayer(c, gname, msg);
            }
        } else if (handler.checkTurn(c, ga)) {
            SOCPlayer pl = ga.getPlayer(plName);
            if ((pl != null) && ga.canEndTurn(pl.getPlayerNumber()))
                handler.endGameTurn(ga, pl, true);
            else
                srv.messageToPlayer(c, gname, "You can't end your turn yet.");
        } else {
            srv.messageToPlayer(c, gname, "It's not your turn.");
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception caught at handleENDTURN");
    }
    ga.releaseMonitor();
}
Also used : SOCPlayer(soc.game.SOCPlayer)

Example 52 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCPlayerTracker method recalcLargestArmyETA.

/**
 * calculate the largest army ETA
 */
public void recalcLargestArmyETA() {
    int laSize = 0;
    SOCPlayer laPlayer = game.getPlayerWithLargestArmy();
    if (laPlayer == null) {
        // /
        // / no one has largest army
        // /
        laSize = 3;
    } else if (laPlayer.getPlayerNumber() == playerNumber) {
        // /
        // / we have largest army
        // /
        largestArmyETA = 0;
        return;
    } else {
        laSize = laPlayer.getNumKnights() + 1;
    }
    // /
    // / figure out how many knights we need to buy
    // /
    knightsToBuy = 0;
    if (// OLD + NEW knights
    (player.getNumKnights() + player.getInventory().getAmount(SOCDevCardConstants.KNIGHT)) < laSize) {
        knightsToBuy = laSize - (player.getNumKnights() + player.getInventory().getAmount(SOCInventory.OLD, SOCDevCardConstants.KNIGHT));
    }
    if (game.getNumDevCards() >= knightsToBuy) {
        // /
        // / figure out how long it takes to buy this many knights
        // /
        SOCBuildingSpeedEstimate bse = new SOCBuildingSpeedEstimate(player.getNumbers());
        int[] ourBuildingSpeed = bse.getEstimatesFromNothingFast(player.getPortFlags());
        int cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
        largestArmyETA = (cardETA + 1) * knightsToBuy;
    } else {
        // /
        // / not enough dev cards left
        // /
        largestArmyETA = 500;
    }
}
Also used : SOCPlayer(soc.game.SOCPlayer)

Example 53 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class RobberStrategy method getBestRobberHex.

/**
 * Determine the best hex to move the robber.
 */
public static int getBestRobberHex(SOCGame game, SOCPlayer ourPlayerData, HashMap<Integer, SOCPlayerTracker> playerTrackers, Random rand) {
    log.debug("%%% MOVEROBBER");
    final int[] hexes = game.getBoard().getLandHexCoords();
    final int prevRobberHex = game.getBoard().getRobberHex();
    /**
     * decide which player we want to thwart
     */
    int[] winGameETAs = new int[game.maxPlayers];
    for (int i = game.maxPlayers - 1; i >= 0; --i) winGameETAs[i] = 100;
    Iterator<SOCPlayerTracker> trackersIter = playerTrackers.values().iterator();
    while (trackersIter.hasNext()) {
        SOCPlayerTracker tracker = trackersIter.next();
        final int trackerPN = tracker.getPlayer().getPlayerNumber();
        log.debug("%%%%%%%%% TRACKER FOR PLAYER " + trackerPN);
        try {
            tracker.recalcWinGameETA();
            winGameETAs[trackerPN] = tracker.getWinGameETA();
            log.debug("winGameETA = " + tracker.getWinGameETA());
        } catch (NullPointerException e) {
            log.debug("Null Pointer Exception calculating winGameETA");
            winGameETAs[trackerPN] = 500;
        }
    }
    final int ourPlayerNumber = ourPlayerData.getPlayerNumber();
    int victimNum = -1;
    for (int pnum = 0; pnum < game.maxPlayers; pnum++) {
        if (game.isSeatVacant(pnum))
            continue;
        if ((victimNum < 0) && (pnum != ourPlayerNumber)) {
            // The first pick
            log.debug("Picking a robber victim: pnum=" + pnum);
            victimNum = pnum;
        } else if ((pnum != ourPlayerNumber) && (winGameETAs[pnum] < winGameETAs[victimNum])) {
            // A better pick
            log.debug("Picking a better robber victim: pnum=" + pnum);
            victimNum = pnum;
        }
    }
    // Postcondition: victimNum != -1 due to "First pick" in loop.
    /**
     * figure out the best way to thwart that player
     */
    SOCPlayer victim = game.getPlayer(victimNum);
    SOCBuildingSpeedEstimate estimate = new SOCBuildingSpeedEstimate();
    int bestHex = prevRobberHex;
    int worstSpeed = 0;
    // can't move robber to desert
    final boolean skipDeserts = game.isGameOptionSet("RD");
    SOCBoard gboard = (skipDeserts ? game.getBoard() : null);
    for (int i = 0; i < hexes.length; i++) {
        /**
         * only check hexes that we're not touching,
         * and not the robber hex, and possibly not desert hexes
         */
        if ((hexes[i] != prevRobberHex) && ourPlayerData.getNumbers().hasNoResourcesForHex(hexes[i]) && !(skipDeserts && (gboard.getHexTypeFromCoord(hexes[i]) == SOCBoard.DESERT_HEX))) {
            estimate.recalculateEstimates(victim.getNumbers(), hexes[i]);
            int[] speeds = estimate.getEstimatesFromNothingFast(victim.getPortFlags());
            int totalSpeed = 0;
            for (int j = SOCBuildingSpeedEstimate.MIN; j < SOCBuildingSpeedEstimate.MAXPLUSONE; j++) {
                totalSpeed += speeds[j];
            }
            log.debug("total Speed = " + totalSpeed);
            if (totalSpeed > worstSpeed) {
                bestHex = hexes[i];
                worstSpeed = totalSpeed;
                log.debug("bestHex = " + Integer.toHexString(bestHex));
                log.debug("worstSpeed = " + worstSpeed);
            }
        }
    }
    log.debug("%%% bestHex = " + Integer.toHexString(bestHex));
    /**
     * Pick a spot at random if we can't decide.
     * Don't pick deserts if the game option is set.
     * Don't pick one of our hexes if at all possible.
     * It's not likely we'll need to pick one of our hexes
     * (we try 30 times to avoid it), so there isn't code here
     * to pick the 'least bad' one.
     * (TODO) consider that: It would be late in the game
     *       if the board's that crowded with pieces.
     *       Use similar algorithm as picking for opponent,
     *       but apply it worst vs best.
     */
    if (bestHex == prevRobberHex) {
        int numRand = 0;
        while ((bestHex == prevRobberHex) || (skipDeserts && (gboard.getHexTypeFromCoord(bestHex) == SOCBoard.DESERT_HEX)) || ((numRand < 30) && ourPlayerData.getNumbers().hasNoResourcesForHex(bestHex))) {
            bestHex = hexes[Math.abs(rand.nextInt()) % hexes.length];
            log.debug("%%% random pick = " + Integer.toHexString(bestHex));
            ++numRand;
        }
    }
    return bestHex;
}
Also used : SOCBoard(soc.game.SOCBoard) SOCPlayer(soc.game.SOCPlayer)

Example 54 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCPlayerTracker method updateLRValues.

/**
 * update the longest road values for all possible roads/ships.
 *<P>
 * longest road value is how much this
 * road/ship would increase our longest road
 * if it were built.
 *<P>
 * the longest road potential is how much
 * this road/ship would increase our LR value
 * if other roads supported by this one were
 * built.
 */
public void updateLRValues() {
    SOCPlayer dummy = new SOCPlayer(player);
    int lrLength = player.getLongestRoadLength();
    // 
    // for each possible road with no necessary roads
    // 
    Iterator<SOCPossibleRoad> posRoadsIter = possibleRoads.values().iterator();
    while (posRoadsIter.hasNext()) {
        SOCPossibleRoad posRoad = posRoadsIter.next();
        if (posRoad.getNecessaryRoads().isEmpty()) {
            // 
            // calc longest road value
            // 
            SOCRoad dummyRoad;
            if (posRoad.isRoadNotShip() || ((posRoad instanceof SOCPossibleShip) && ((SOCPossibleShip) posRoad).isCoastalRoadAndShip))
                // TODO better coastal handling
                dummyRoad = new SOCRoad(dummy, posRoad.getCoordinates(), null);
            else
                dummyRoad = new SOCShip(dummy, posRoad.getCoordinates(), null);
            dummy.putPiece(dummyRoad, true);
            int newLRLength = dummy.calcLongestRoad2();
            if (newLRLength <= lrLength) {
                posRoad.setLRValue(0);
            } else {
                posRoad.setLRValue(newLRLength - lrLength);
            }
            // D.ebugPrintln("$$ updateLRValue for "+Integer.toHexString(posRoad.getCoordinates())+" is "+posRoad.getLRValue());
            // 
            // update potential LR value
            // 
            posRoad.setLRPotential(0);
            updateLRPotential(posRoad, dummy, dummyRoad, lrLength, LR_CALC_LEVEL);
            dummy.removePiece(dummyRoad, null);
        } else {
            posRoad.setLRValue(0);
            posRoad.setLRPotential(0);
        }
    }
    dummy.destroyPlayer();
}
Also used : SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer) SOCRoad(soc.game.SOCRoad)

Example 55 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCPlayerTracker method addOurNewRoadOrShip.

/**
 * Add one of our roads or ships that has just been built.
 * Look for new adjacent possible settlements.
 * Calls {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}
 * on newly possible adjacent roads or ships.
 *
 * @param road         the road or ship
 * @param trackers     player trackers for the players
 * @param expandLevel  how far out we should expand roads/ships;
 *                     passed to {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}
 */
private void addOurNewRoadOrShip(SOCRoad road, HashMap<Integer, SOCPlayerTracker> trackers, int expandLevel) {
    // D.ebugPrintln("$$$ addOurNewRoad : "+road);
    // 
    // see if the new road was a possible road
    // 
    Iterator<SOCPossibleRoad> prIter = possibleRoads.values().iterator();
    while (prIter.hasNext()) {
        SOCPossibleRoad pr = prIter.next();
        // 
        // reset all expanded flags for possible roads
        // 
        pr.resetExpandedFlag();
        if (pr.getCoordinates() == road.getCoordinates()) {
            // 
            // if so, remove it
            // 
            // D.ebugPrintln("$$$ removing "+Integer.toHexString(road.getCoordinates()));
            possibleRoads.remove(Integer.valueOf(pr.getCoordinates()));
            removeFromNecessaryRoads(pr);
            break;
        }
    }
    // D.ebugPrintln("$$$ checking for possible settlements");
    // 
    // see if this road/ship adds any new possible settlements
    // 
    // check adjacent nodes to road for potential settlements
    // 
    final SOCBoard board = game.getBoard();
    Collection<Integer> adjNodeEnum = board.getAdjacentNodesToEdge(road.getCoordinates());
    for (Integer adjNode : adjNodeEnum) {
        if (player.canPlaceSettlement(adjNode.intValue())) {
            // 
            // see if possible settlement is already in the list
            // 
            // D.ebugPrintln("$$$ seeing if "+Integer.toHexString(adjNode.intValue())+" is already in the list");
            SOCPossibleSettlement posSet = possibleSettlements.get(adjNode);
            if (posSet != null) {
                // 
                // if so, clear necessary road list and remove from np lists
                // 
                // D.ebugPrintln("$$$ found it");
                removeFromNecessaryRoads(posSet);
                posSet.getNecessaryRoads().clear();
                posSet.setNumberOfNecessaryRoads(0);
            } else {
                // 
                // else, add new possible settlement
                // 
                // D.ebugPrintln("$$$ adding new possible settlement at "+Integer.toHexString(adjNode.intValue()));
                SOCPossibleSettlement newPosSet = new SOCPossibleSettlement(player, adjNode.intValue(), null);
                newPosSet.setNumberOfNecessaryRoads(0);
                possibleSettlements.put(adjNode, newPosSet);
                updateSettlementConflicts(newPosSet, trackers);
            }
        }
    }
    // D.ebugPrintln("$$$ checking roads adjacent to "+Integer.toHexString(road.getCoordinates()));
    // 
    // see if this road adds any new possible roads
    // 
    ArrayList<SOCPossibleRoad> newPossibleRoads = new ArrayList<SOCPossibleRoad>();
    ArrayList<SOCPossibleRoad> roadsToExpand = new ArrayList<SOCPossibleRoad>();
    // 
    for (Integer adjEdge : board.getAdjacentEdgesToEdge(road.getCoordinates())) {
        final int edge = adjEdge.intValue();
        // D.ebugPrintln("$$$ edge "+Integer.toHexString(adjEdge.intValue())+" is legal:"+player.isPotentialRoad(adjEdge.intValue()));
        // 
        // see if edge is a potential road
        // or ship to continue this route
        // 
        boolean edgeIsPotentialRoute = (road.isRoadNotShip()) ? player.isPotentialRoad(edge) : player.isPotentialShip(edge);
        // If true, this edge transitions
        // between ships <-> roads, at a
        // coastal settlement
        boolean edgeRequiresCoastalSettlement = false;
        if ((!edgeIsPotentialRoute) && game.hasSeaBoard) {
            // Determine if can transition ship <-> road
            // at a coastal settlement
            final int nodeBetween = ((SOCBoardLarge) board).getNodeBetweenAdjacentEdges(road.getCoordinates(), edge);
            if (player.canPlaceSettlement(nodeBetween)) {
                // check opposite type at transition
                edgeIsPotentialRoute = (road.isRoadNotShip()) ? player.isPotentialShip(edge) : player.isPotentialRoad(edge);
                if (edgeIsPotentialRoute)
                    edgeRequiresCoastalSettlement = true;
            }
        }
        if (edgeIsPotentialRoute) {
            // 
            // see if possible road is already in the list
            // 
            SOCPossibleRoad pr = possibleRoads.get(adjEdge);
            if (pr != null) {
                // For now, can't differ along a coastal route.
                if (edgeRequiresCoastalSettlement && (pr.isRoadNotShip() != road.isRoadNotShip())) {
                    // <--- road vs ship mismatch ---
                    continue;
                }
                // D.ebugPrintln("$$$ pr "+Integer.toHexString(pr.getCoordinates())+" already in list");
                if (!pr.getNecessaryRoads().isEmpty()) {
                    // D.ebugPrintln("$$$    clearing nr list");
                    removeFromNecessaryRoads(pr);
                    pr.getNecessaryRoads().clear();
                    pr.setNumberOfNecessaryRoads(0);
                }
                roadsToExpand.add(pr);
                pr.setExpandedFlag();
            } else {
                // 
                // else, add new possible road
                // 
                // D.ebugPrintln("$$$ adding new pr at "+Integer.toHexString(adjEdge.intValue()));
                SOCPossibleRoad newPR;
                // for effort if requires settlement
                final int roadsBetween;
                boolean isRoad = road.isRoadNotShip();
                if (edgeRequiresCoastalSettlement) {
                    isRoad = !isRoad;
                    // roughly account for effort & cost of new settlement
                    roadsBetween = 2;
                } else {
                    roadsBetween = 0;
                }
                // use coastal road/ship type (isCoastalRoadAndShip) only if we can
                // require a coastal settlement to switch from road-only or ship-only
                final boolean isCoastal = edgeRequiresCoastalSettlement && player.isPotentialRoad(edge) && player.isPotentialShip(edge);
                if (isRoad && !isCoastal) {
                    newPR = new SOCPossibleRoad(player, edge, null);
                } else {
                    newPR = new SOCPossibleShip(player, edge, isCoastal, null);
                    System.err.println("L793: " + toString() + ": new PossibleShip(" + isCoastal + ") at 0x" + Integer.toHexString(edge));
                }
                // 0 unless requires settlement
                newPR.setNumberOfNecessaryRoads(roadsBetween);
                newPossibleRoads.add(newPR);
                roadsToExpand.add(newPR);
                newPR.setExpandedFlag();
            }
        }
    }
    // 
    for (SOCPossibleRoad newPR : newPossibleRoads) {
        possibleRoads.put(Integer.valueOf(newPR.getCoordinates()), newPR);
    }
    // 
    // expand possible roads that we've touched or added
    // 
    SOCPlayer dummy = new SOCPlayer(player);
    for (SOCPossibleRoad expandPR : roadsToExpand) {
        expandRoadOrShip(expandPR, player, dummy, trackers, expandLevel);
    }
    dummy.destroyPlayer();
    // 
    if ((road instanceof SOCShip) && game.isGameOptionSet(SOCGameOption.K_SC_PIRI))
        updateScenario_SC_PIRI_closestShipToFortress((SOCShip) road, true);
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) SOCBoard(soc.game.SOCBoard) ArrayList(java.util.ArrayList) SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer)

Aggregations

SOCPlayer (soc.game.SOCPlayer)61 SOCGame (soc.game.SOCGame)17 SOCShip (soc.game.SOCShip)12 SOCSettlement (soc.game.SOCSettlement)11 SOCRoad (soc.game.SOCRoad)9 SOCResourceSet (soc.game.SOCResourceSet)8 SOCCity (soc.game.SOCCity)7 SOCBoardLarge (soc.game.SOCBoardLarge)6 SOCFortress (soc.game.SOCFortress)5 ArrayList (java.util.ArrayList)4 SOCBoard (soc.game.SOCBoard)4 Connection (soc.server.genericServer.Connection)4 SOCInventoryItem (soc.game.SOCInventoryItem)3 SOCVillage (soc.game.SOCVillage)3 SQLException (java.sql.SQLException)2 Iterator (java.util.Iterator)2 Stack (java.util.Stack)2 SOCLRPathData (soc.game.SOCLRPathData)2 SOCPlayingPiece (soc.game.SOCPlayingPiece)2 SOCSpecialItem (soc.game.SOCSpecialItem)2