Search in sources :

Example 1 with SOCPlayerNumbers

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

the class SOCPlayerTracker method recalcWinGameETA.

/**
 * Recalculate the tracked player's ETA for winning the game (WGETA) by making and simulating with a copy
 * of our current potential settlement/city locations, building speed estimates (BSEs), and dice numbers,
 * looping from player's current {@link SOCPlayer#getTotalVP()} to {@link SOCGame#vp_winner}.
 *<P>
 * Calculates the fields for {@link #getWinGameETA()}, {@link #needsLA()}, {@link #needsLR()}.
 *<P>
 * Each time through the loop, given potential locations and available pieces, pick the fastest ETA
 * among each of these 2-VP combinations:
 *<UL>
 * <LI> 2 settlements (including necessary roads' ETA)
 * <LI> 2 cities
 * <LI> 1 city, 1 settlement (+ roads)
 * <LI> 1 settlement (+ roads), 1 city
 * <LI> Buy enough cards for Largest Army
 * <LI> Build enough roads for Longest Road
 *</UL>
 * The temporary potential sets, port trade flags, BSEs and dice numbers are updated with the picked pieces.
 * The loop body doesn't add new potential roads/ships or potential settlements to its copy of those sets,
 * or call {@link #expandRoadOrShip(SOCPossibleRoad, SOCPlayer, SOCPlayer, HashMap, int)}, so it may run out
 * of potential locations before {@code vp_winner} is reached.  If the loop doesn't have the locations or
 * pieces to do anything, 500 ETA and 2 VP are added to the totals to keep things moving.
 *<P>
 * If the loop reaches {@link SOCGame#vp_winner} - 1, it calculates ETAs for 1 city or settlement (+ roads)
 * instead of 2, and Largest Army and Longest Road, to make its choice.
 */
public void recalcWinGameETA() {
    int oldWGETA = winGameETA;
    try {
        needLR = false;
        needLA = false;
        winGameETA = 0;
        SOCPlayerNumbers tempPlayerNumbers = new SOCPlayerNumbers(player.getNumbers());
        boolean[] tempPortFlags = new boolean[SOCBoard.WOOD_PORT + 1];
        for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
            tempPortFlags[portType] = player.getPortFlag(portType);
        }
        SOCBuildingSpeedEstimate[] tempSetBSE = new SOCBuildingSpeedEstimate[2];
        SOCBuildingSpeedEstimate[] tempCityBSE = new SOCBuildingSpeedEstimate[2];
        tempCityBSE[0] = new SOCBuildingSpeedEstimate();
        tempCityBSE[1] = new SOCBuildingSpeedEstimate();
        tempSetBSE[0] = new SOCBuildingSpeedEstimate();
        tempSetBSE[1] = new SOCBuildingSpeedEstimate();
        int[][] chosenSetBuildingSpeed = new int[2][SOCBuildingSpeedEstimate.MAXPLUSONE];
        int[][] chosenCityBuildingSpeed = new int[2][SOCBuildingSpeedEstimate.MAXPLUSONE];
        SOCBuildingSpeedEstimate tempBSE = new SOCBuildingSpeedEstimate();
        SOCBuildingSpeedEstimate ourBSE = new SOCBuildingSpeedEstimate(player.getNumbers());
        int[] ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
        int cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
        int settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
        int roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
        int cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
        // TODO shipETA, when ready
        int settlementPiecesLeft = player.getNumPieces(SOCPlayingPiece.SETTLEMENT);
        int cityPiecesLeft = player.getNumPieces(SOCPlayingPiece.CITY);
        int citySpotsLeft = possibleCities.size();
        boolean haveLA = false;
        boolean haveLR = false;
        int tempLargestArmyETA = largestArmyETA;
        int tempLongestRoadETA = longestRoadETA;
        SOCPlayer laPlayer = game.getPlayerWithLargestArmy();
        SOCPlayer lrPlayer = game.getPlayerWithLongestRoad();
        final SOCBoard board = game.getBoard();
        if (D.ebugOn) {
            if (laPlayer != null) {
                D.ebugPrintln("laPlayer # = " + laPlayer.getPlayerNumber());
            } else {
                D.ebugPrintln("laPlayer = null");
            }
            if (lrPlayer != null) {
                D.ebugPrintln("lrPlayer # = " + lrPlayer.getPlayerNumber());
            } else {
                D.ebugPrintln("lrPlayer = null");
            }
        }
        if ((laPlayer != null) && (playerNumber == laPlayer.getPlayerNumber())) {
            haveLA = true;
        }
        if ((lrPlayer != null) && (playerNumber == lrPlayer.getPlayerNumber())) {
            haveLR = true;
        }
        TreeMap<Integer, SOCPossibleSettlement> posSetsCopy = new TreeMap<Integer, SOCPossibleSettlement>(possibleSettlements);
        TreeMap<Integer, SOCPossibleCity> posCitiesCopy = new TreeMap<Integer, SOCPossibleCity>(possibleCities);
        int points = player.getTotalVP();
        int fastestETA;
        final int vp_winner = game.vp_winner;
        while (points < vp_winner) {
            D.ebugPrintln("WWW points = " + points);
            D.ebugPrintln("WWW settlementPiecesLeft = " + settlementPiecesLeft);
            D.ebugPrintln("WWW cityPiecesLeft = " + cityPiecesLeft);
            D.ebugPrintln("WWW settlementSpotsLeft = " + posSetsCopy.size());
            D.ebugPrintln("WWW citySpotsLeft = " + posCitiesCopy.size());
            if (D.ebugOn) {
                D.ebugPrint("WWW tempPortFlags: ");
                for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                    D.ebugPrint(tempPortFlags[portType] + " ");
                }
                D.ebugPrintln();
            }
            D.ebugPrintln("WWW settlementETA = " + settlementETA);
            D.ebugPrintln("WWW cityETA = " + cityETA);
            D.ebugPrintln("WWW roadETA = " + roadETA);
            D.ebugPrintln("WWW cardETA = " + cardETA);
            if (points == (vp_winner - 1)) {
                fastestETA = 500;
                SOCPossibleSettlement chosenSet = null;
                if ((settlementPiecesLeft > 0) && (!posSetsCopy.isEmpty())) {
                    Iterator<SOCPossibleSettlement> posSetsIter = posSetsCopy.values().iterator();
                    while (posSetsIter.hasNext()) {
                        SOCPossibleSettlement posSet = posSetsIter.next();
                        int posSetETA = settlementETA + (posSet.getNumberOfNecessaryRoads() * roadETA);
                        if (posSetETA < fastestETA) {
                            fastestETA = posSetETA;
                            chosenSet = posSet;
                        }
                    }
                    // /
                    if (chosenSet != null) {
                        final int totalNecRoads = calcTotalNecessaryRoads(chosenSet);
                        fastestETA = (settlementETA + (totalNecRoads * roadETA));
                        D.ebugPrintln("WWW # necesesary roads = " + totalNecRoads);
                        D.ebugPrintln("WWW this settlement eta = " + (settlementETA + (totalNecRoads * roadETA)));
                        D.ebugPrintln("WWW settlement is " + chosenSet);
                        D.ebugPrintln("WWW settlement eta = " + fastestETA);
                    } else {
                        fastestETA = 500;
                    }
                }
                if ((cityPiecesLeft > 0) && (citySpotsLeft > 0) && (cityETA <= fastestETA)) {
                    D.ebugPrintln("WWW city eta = " + cityETA);
                    fastestETA = cityETA;
                }
                if (!haveLA && !needLA && (tempLargestArmyETA < fastestETA)) {
                    D.ebugPrintln("WWW LA eta = " + tempLargestArmyETA);
                    fastestETA = tempLargestArmyETA;
                }
                if (!haveLR && !needLR && (tempLongestRoadETA < fastestETA)) {
                    D.ebugPrintln("WWW LR eta = " + tempLongestRoadETA);
                    fastestETA = tempLongestRoadETA;
                }
                if (!haveLR && !needLR && (fastestETA == tempLongestRoadETA)) {
                    needLR = true;
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": Longest Road");
                    }
                } else if (!haveLA && !needLA && (fastestETA == tempLargestArmyETA)) {
                    needLA = true;
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": Largest Army");
                    }
                } else if ((cityPiecesLeft > 0) && (citySpotsLeft > 0) && (cityETA == fastestETA)) {
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": City");
                    }
                } else if (chosenSet != null) {
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": Stlmt at " + board.nodeCoordToString(chosenSet.getCoordinates()));
                    }
                }
                D.ebugPrintln("WWW Adding " + fastestETA + " to win eta");
                winGameETA += fastestETA;
                points += 2;
            } else {
                // 
                // This is for < 9 vp (not about to win with VP_WINNER points)
                // 
                // System.out.println("Old Player Numbers = "+tempPlayerNumbers);
                // System.out.print("Old Ports = ");
                // for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
                // System.out.print(tempPortFlags[i]+",");
                // }
                // System.out.println();
                fastestETA = 500;
                SOCPossibleSettlement[] chosenSet = new SOCPossibleSettlement[2];
                boolean[][] tempPortFlagsSet = new boolean[2][SOCBoard.WOOD_PORT + 1];
                SOCPossibleCity[] chosenCity = new SOCPossibleCity[2];
                chosenSet[0] = null;
                chosenSet[1] = null;
                chosenCity[0] = null;
                chosenCity[1] = null;
                int twoSettlements = 0;
                int twoCities = 500;
                int oneOfEach = 0;
                int cityBeforeSettlement = 500;
                int settlementBeforeCity = 500;
                // /
                if ((cityPiecesLeft > 1) && (citySpotsLeft > 1)) {
                    // 
                    // get a more accurate estimate by taking the
                    // effect on building speed into account
                    // 
                    twoCities = 500;
                    Iterator<SOCPossibleCity> posCities0Iter = posCitiesCopy.values().iterator();
                    while (posCities0Iter.hasNext()) {
                        SOCPossibleCity posCity0 = posCities0Iter.next();
                        // 
                        // update our building speed estimate
                        // 
                        tempPlayerNumbers.updateNumbers(posCity0.getCoordinates(), board);
                        tempCityBSE[0].recalculateEstimates(tempPlayerNumbers);
                        chosenCityBuildingSpeed[0] = tempCityBSE[0].getEstimatesFromNothingFast(tempPortFlags);
                        int tempCityETA = chosenCityBuildingSpeed[0][SOCBuildingSpeedEstimate.CITY];
                        // 
                        if ((cityETA + tempCityETA) < twoCities) {
                            chosenCity[0] = posCity0;
                            twoCities = (cityETA + tempCityETA);
                        }
                        tempPlayerNumbers.undoUpdateNumbers(posCity0.getCoordinates(), board);
                    }
                    if (twoCities <= fastestETA) {
                        D.ebugPrintln("WWW twoCities = " + twoCities);
                        fastestETA = twoCities;
                    }
                }
                // /
                // / two settlements
                // /
                boolean canBuild2Settlements = false;
                if ((settlementPiecesLeft > 1) && (posSetsCopy.size() > 1)) {
                    canBuild2Settlements = true;
                    ArrayList<SOCPossibleSettlement> posSetsToPutBack = new ArrayList<SOCPossibleSettlement>();
                    for (int i = 0; i < 2; i++) {
                        int fastestSetETA = 500;
                        int bestSpeedupTotal = 0;
                        if (posSetsCopy.isEmpty()) {
                            canBuild2Settlements = false;
                        } else {
                            Iterator<SOCPossibleSettlement> posSetsIter = posSetsCopy.values().iterator();
                            while (posSetsIter.hasNext()) {
                                SOCPossibleSettlement posSet = posSetsIter.next();
                                int posSetETA = settlementETA + (posSet.getNumberOfNecessaryRoads() * roadETA);
                                final int posSetCoord = posSet.getCoordinates();
                                if (posSetETA < fastestSetETA) {
                                    fastestSetETA = posSetETA;
                                    tempPlayerNumbers.updateNumbers(posSetCoord, board);
                                    for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                                        tempPortFlagsSet[i][portType] = tempPortFlags[portType];
                                    }
                                    int portType = board.getPortTypeFromNodeCoord(posSetCoord);
                                    if (portType != -1)
                                        tempPortFlagsSet[i][portType] = true;
                                    tempSetBSE[i].recalculateEstimates(tempPlayerNumbers);
                                    chosenSetBuildingSpeed[i] = tempSetBSE[i].getEstimatesFromNothingFast(tempPortFlagsSet[i]);
                                    for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                        if ((ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[i][buildingType]) > 0) {
                                            bestSpeedupTotal += (ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[i][buildingType]);
                                        }
                                    }
                                    tempPlayerNumbers.undoUpdateNumbers(posSetCoord, board);
                                    chosenSet[i] = posSet;
                                } else if (posSetETA == fastestSetETA) {
                                    boolean[] veryTempPortFlags = new boolean[SOCBoard.WOOD_PORT + 1];
                                    tempPlayerNumbers.updateNumbers(posSetCoord, board);
                                    for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                                        veryTempPortFlags[portType] = tempPortFlags[portType];
                                    }
                                    int portType = board.getPortTypeFromNodeCoord(posSetCoord);
                                    if (portType != -1)
                                        veryTempPortFlags[portType] = true;
                                    tempBSE.recalculateEstimates(tempPlayerNumbers);
                                    int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(veryTempPortFlags);
                                    int tempSpeedupTotal = 0;
                                    // boolean ok = true;
                                    for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                        if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
                                            tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
                                        } else {
                                        // ok = false;
                                        }
                                    }
                                    // if (ok) {
                                    // good++;
                                    // } else {
                                    // bad++;
                                    // //
                                    // // output the player number data
                                    // //
                                    // System.out.println("New Player Numbers = "+tempPlayerNumbers);
                                    // System.out.print("New Ports = ");
                                    // for (int k = 0; k <= SOCBoard.WOOD_PORT; k++) {
                                    // System.out.print(veryTempPortFlags[k]+",");
                                    // }
                                    // System.out.println();
                                    // }
                                    tempPlayerNumbers.undoUpdateNumbers(posSetCoord, board);
                                    if (tempSpeedupTotal > bestSpeedupTotal) {
                                        fastestSetETA = posSetETA;
                                        bestSpeedupTotal = tempSpeedupTotal;
                                        for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                            chosenSetBuildingSpeed[i][buildingType] = tempBuildingSpeed[buildingType];
                                        }
                                        for (portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                                            tempPortFlagsSet[i][portType] = veryTempPortFlags[portType];
                                        }
                                        chosenSet[i] = posSet;
                                    }
                                }
                            }
                            // /
                            // /  estimate setETA using building speed
                            // /  for settlements and roads from nothing
                            // /
                            // /  as long as this settlement needs roads
                            // /  add a roadETA to the ETA for this settlement
                            // /
                            int totalNecRoads = calcTotalNecessaryRoads(chosenSet[i]);
                            D.ebugPrintln("WWW # necesesary roads = " + totalNecRoads);
                            D.ebugPrintln("WWW this settlement eta = " + (settlementETA + (totalNecRoads * roadETA)));
                            if ((i == 0) && (chosenSet[0] != null)) {
                                posSetsCopy.remove(Integer.valueOf(chosenSet[0].getCoordinates()));
                                for (SOCPossibleSettlement conflict : chosenSet[0].getConflicts()) {
                                    Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
                                    SOCPossibleSettlement possibleConflict = posSetsCopy.get(conflictInt);
                                    if (possibleConflict != null) {
                                        posSetsToPutBack.add(possibleConflict);
                                        posSetsCopy.remove(conflictInt);
                                    }
                                }
                                twoSettlements += (settlementETA + (totalNecRoads * roadETA));
                            }
                            if ((i == 1) && (chosenSet[1] != null)) {
                                // 
                                // get a more accurate estimate by taking the
                                // effect on building speed into account
                                // 
                                int tempSettlementETA = chosenSetBuildingSpeed[0][SOCBuildingSpeedEstimate.SETTLEMENT];
                                int tempRoadETA = chosenSetBuildingSpeed[0][SOCBuildingSpeedEstimate.ROAD];
                                twoSettlements += (tempSettlementETA + (totalNecRoads * tempRoadETA));
                            }
                        }
                    }
                    posSetsCopy.put(Integer.valueOf(chosenSet[0].getCoordinates()), chosenSet[0]);
                    for (SOCPossibleSettlement tmpPosSet : posSetsToPutBack) {
                        posSetsCopy.put(Integer.valueOf(tmpPosSet.getCoordinates()), tmpPosSet);
                    }
                    if (canBuild2Settlements && (twoSettlements <= fastestETA)) {
                        D.ebugPrintln("WWW 2 * settlement = " + twoSettlements);
                        fastestETA = twoSettlements;
                    }
                }
                // /
                if ((cityPiecesLeft > 0) && (((settlementPiecesLeft > 0) && (citySpotsLeft >= 0)) || ((settlementPiecesLeft >= 0) && (citySpotsLeft > 0))) && !posSetsCopy.isEmpty()) {
                    // 
                    if ((chosenCity[0] == null) && (citySpotsLeft > 0)) {
                        int bestCitySpeedupTotal = 0;
                        Iterator<SOCPossibleCity> posCities0Iter = posCitiesCopy.values().iterator();
                        while (posCities0Iter.hasNext()) {
                            SOCPossibleCity posCity0 = posCities0Iter.next();
                            tempPlayerNumbers.updateNumbers(posCity0.getCoordinates(), board);
                            tempBSE.recalculateEstimates(tempPlayerNumbers);
                            int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(tempPortFlags);
                            int tempSpeedupTotal = 0;
                            // boolean ok = true;
                            for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
                                    tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
                                } else {
                                // ok = false;
                                }
                            }
                            // if (ok) {
                            // good++;
                            // } else {
                            // bad++;
                            // //
                            // // output the player number data
                            // //
                            // System.out.println("New Player Numbers = "+tempPlayerNumbers);
                            // System.out.print("New Ports = ");
                            // for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
                            // System.out.print(tempPortFlags[i]+",");
                            // }
                            // System.out.println();
                            // }
                            tempPlayerNumbers.undoUpdateNumbers(posCity0.getCoordinates(), board);
                            if (tempSpeedupTotal >= bestCitySpeedupTotal) {
                                bestCitySpeedupTotal = tempSpeedupTotal;
                                for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                    chosenCityBuildingSpeed[0][buildingType] = tempBuildingSpeed[buildingType];
                                }
                                chosenCity[0] = posCity0;
                            }
                        }
                    }
                    // 
                    if (chosenSet[0] == null) {
                        int fastestSetETA = 500;
                        int bestSpeedupTotal = 0;
                        Iterator<SOCPossibleSettlement> posSetsIter = posSetsCopy.values().iterator();
                        while (posSetsIter.hasNext()) {
                            SOCPossibleSettlement posSet = posSetsIter.next();
                            int posSetETA = settlementETA + (posSet.getNumberOfNecessaryRoads() * roadETA);
                            if (posSetETA < fastestSetETA) {
                                fastestSetETA = posSetETA;
                                tempPlayerNumbers.updateNumbers(posSet.getCoordinates(), board);
                                for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                                    tempPortFlagsSet[0][portType] = tempPortFlags[portType];
                                }
                                int portType = board.getPortTypeFromNodeCoord(posSet.getCoordinates());
                                if (portType != -1)
                                    tempPortFlagsSet[0][portType] = true;
                                tempSetBSE[0].recalculateEstimates(tempPlayerNumbers);
                                chosenSetBuildingSpeed[0] = tempSetBSE[0].getEstimatesFromNothingFast(tempPortFlagsSet[0]);
                                for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                    if ((ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[0][buildingType]) > 0) {
                                        bestSpeedupTotal += (ourBuildingSpeed[buildingType] - chosenSetBuildingSpeed[0][buildingType]);
                                    }
                                }
                                tempPlayerNumbers.undoUpdateNumbers(posSet.getCoordinates(), board);
                                chosenSet[0] = posSet;
                            } else if (posSetETA == fastestSetETA) {
                                boolean[] veryTempPortFlags = new boolean[SOCBoard.WOOD_PORT + 1];
                                tempPlayerNumbers.updateNumbers(posSet.getCoordinates(), board);
                                for (int portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                                    veryTempPortFlags[portType] = tempPortFlags[portType];
                                }
                                int portType = board.getPortTypeFromNodeCoord(posSet.getCoordinates());
                                if (portType != -1)
                                    veryTempPortFlags[portType] = true;
                                tempBSE.recalculateEstimates(tempPlayerNumbers);
                                int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(veryTempPortFlags);
                                int tempSpeedupTotal = 0;
                                // boolean ok = true;
                                for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                    if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
                                        tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
                                    } else {
                                    // ok = false;
                                    }
                                }
                                // if (ok) {
                                // good++;
                                // } else {
                                // bad++;
                                // //
                                // // output the player number data
                                // //
                                // System.out.println("New Player Numbers = "+tempPlayerNumbers);
                                // System.out.print("New Ports = ");
                                // for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
                                // System.out.print(tempPortFlags[i]+",");
                                // }
                                // System.out.println();
                                // }
                                tempPlayerNumbers.undoUpdateNumbers(posSet.getCoordinates(), board);
                                if (tempSpeedupTotal > bestSpeedupTotal) {
                                    fastestSetETA = posSetETA;
                                    bestSpeedupTotal = tempSpeedupTotal;
                                    for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                                        chosenSetBuildingSpeed[0][buildingType] = tempBuildingSpeed[buildingType];
                                    }
                                    for (portType = SOCBoard.MISC_PORT; portType <= SOCBoard.WOOD_PORT; portType++) {
                                        tempPortFlagsSet[0][portType] = veryTempPortFlags[portType];
                                    }
                                    chosenSet[0] = posSet;
                                }
                            }
                        }
                    }
                    if (citySpotsLeft == 0) {
                        chosenCity[0] = new SOCPossibleCity(player, chosenSet[0].getCoordinates());
                    }
                    // /
                    // /  estimate setETA using building speed
                    // /  for settlements and roads from nothing
                    // /
                    // /  as long as this settlement needs roads
                    // /  add a roadETA to the ETA for this settlement
                    // /
                    int totalNecRoads = calcTotalNecessaryRoads(chosenSet[0]);
                    D.ebugPrintln("WWW # necesesary roads = " + totalNecRoads);
                    D.ebugPrintln("WWW this settlement eta = " + (settlementETA + (totalNecRoads * roadETA)));
                    // 
                    if ((settlementPiecesLeft > 0) && (citySpotsLeft >= 0)) {
                        int tempCityETA = chosenSetBuildingSpeed[0][SOCBuildingSpeedEstimate.CITY];
                        settlementBeforeCity = tempCityETA + (settlementETA + (totalNecRoads * roadETA));
                    }
                    if ((settlementPiecesLeft >= 0) && (citySpotsLeft > 0)) {
                        int tempSettlementETA = chosenCityBuildingSpeed[0][SOCBuildingSpeedEstimate.SETTLEMENT];
                        int tempRoadETA = chosenCityBuildingSpeed[0][SOCBuildingSpeedEstimate.ROAD];
                        cityBeforeSettlement = cityETA + (tempSettlementETA + (totalNecRoads * tempRoadETA));
                    }
                    if (settlementBeforeCity < cityBeforeSettlement) {
                        oneOfEach = settlementBeforeCity;
                    } else {
                        oneOfEach = cityBeforeSettlement;
                    }
                    if (oneOfEach <= fastestETA) {
                        D.ebugPrintln("WWW one of each = " + oneOfEach);
                        fastestETA = oneOfEach;
                    }
                }
                // /
                if (!haveLA && !needLA && (points > 5)) {
                    // 
                    // recalc LA eta given our new building speed
                    // 
                    int laSize = 0;
                    if (laPlayer == null) {
                        // /
                        // / no one has largest army
                        // /
                        laSize = 3;
                    } else if (laPlayer.getPlayerNumber() == playerNumber) {
                        // /
                        // / we have largest army
                        // /
                        D.ebugPrintln("WWW ERROR CALCULATING LA ETA");
                    } else {
                        laSize = laPlayer.getNumKnights() + 1;
                    }
                    // /
                    // / figure out how many knights we need to buy
                    // /
                    knightsToBuy = 0;
                    if ((player.getNumKnights() + player.getInventory().getAmount(SOCDevCardConstants.KNIGHT)) < // OLD + NEW knights
                    laSize) {
                        knightsToBuy = laSize - (player.getNumKnights() + player.getInventory().getAmount(SOCInventory.OLD, SOCDevCardConstants.KNIGHT));
                    }
                    // /
                    if (game.getNumDevCards() >= knightsToBuy) {
                        tempLargestArmyETA = (cardETA + 1) * knightsToBuy;
                    } else {
                        tempLargestArmyETA = 500;
                    }
                    D.ebugPrintln("WWW LA eta = " + tempLargestArmyETA);
                    if (tempLargestArmyETA < fastestETA) {
                        fastestETA = tempLargestArmyETA;
                    }
                }
                // 
                if (!haveLR && !needLR && (points > 5)) {
                    tempLongestRoadETA = roadETA * roadsToGo;
                    D.ebugPrintln("WWW LR eta = " + tempLongestRoadETA);
                    if (tempLongestRoadETA < fastestETA) {
                        fastestETA = tempLongestRoadETA;
                    }
                }
                // /
                // / implement the fastest scenario
                // /
                D.ebugPrintln("WWW Adding " + fastestETA + " to win eta");
                points += 2;
                winGameETA += fastestETA;
                D.ebugPrintln("WWW WGETA SO FAR FOR PLAYER " + playerNumber + " = " + winGameETA);
                if ((settlementPiecesLeft > 1) && (posSetsCopy.size() > 1) && canBuild2Settlements && (fastestETA == twoSettlements)) {
                    Integer chosenSet0Int = Integer.valueOf(chosenSet[0].getCoordinates());
                    Integer chosenSet1Int = Integer.valueOf(chosenSet[1].getCoordinates());
                    posSetsCopy.remove(chosenSet0Int);
                    posSetsCopy.remove(chosenSet1Int);
                    posCitiesCopy.put(chosenSet0Int, new SOCPossibleCity(player, chosenSet[0].getCoordinates()));
                    posCitiesCopy.put(chosenSet1Int, new SOCPossibleCity(player, chosenSet[1].getCoordinates()));
                    // 
                    for (SOCPossibleSettlement conflict : chosenSet[0].getConflicts()) {
                        Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
                        posSetsCopy.remove(conflictInt);
                    }
                    for (SOCPossibleSettlement conflict : chosenSet[1].getConflicts()) {
                        Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
                        posSetsCopy.remove(conflictInt);
                    }
                    settlementPiecesLeft -= 2;
                    citySpotsLeft += 2;
                    // 
                    // update our building speed estimate
                    // 
                    tempPlayerNumbers.updateNumbers(chosenSet[0].getCoordinates(), board);
                    tempPlayerNumbers.updateNumbers(chosenSet[1].getCoordinates(), board);
                    int portType = board.getPortTypeFromNodeCoord(chosenSet[0].getCoordinates());
                    if (portType != -1)
                        tempPortFlags[portType] = true;
                    portType = board.getPortTypeFromNodeCoord(chosenSet[1].getCoordinates());
                    if (portType != -1)
                        tempPortFlags[portType] = true;
                    ourBSE.recalculateEstimates(tempPlayerNumbers);
                    ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
                    settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
                    roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
                    cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
                    cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
                    D.ebugPrintln("WWW  * build two settlements");
                    D.ebugPrintln("WWW    settlement 1: " + board.nodeCoordToString(chosenSet[0].getCoordinates()));
                    D.ebugPrintln("WWW    settlement 2: " + board.nodeCoordToString(chosenSet[1].getCoordinates()));
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": Stlmt at " + board.nodeCoordToString(chosenSet[0].getCoordinates()) + "; Stlmt at " + board.nodeCoordToString(chosenSet[1].getCoordinates()));
                    }
                } else if (((cityPiecesLeft > 0) && (((settlementPiecesLeft > 0) && (citySpotsLeft >= 0)) || ((settlementPiecesLeft >= 0) && (citySpotsLeft > 0))) && !posSetsCopy.isEmpty()) && (fastestETA == oneOfEach)) {
                    Integer chosenSet0Int = Integer.valueOf(chosenSet[0].getCoordinates());
                    posSetsCopy.remove(chosenSet0Int);
                    if (chosenSet[0].getCoordinates() != chosenCity[0].getCoordinates()) {
                        posCitiesCopy.put(chosenSet0Int, new SOCPossibleCity(player, chosenSet[0].getCoordinates()));
                    }
                    posCitiesCopy.remove(Integer.valueOf(chosenCity[0].getCoordinates()));
                    cityPiecesLeft -= 1;
                    // 
                    for (SOCPossibleSettlement conflict : chosenSet[0].getConflicts()) {
                        Integer conflictInt = Integer.valueOf(conflict.getCoordinates());
                        posSetsCopy.remove(conflictInt);
                    }
                    // 
                    // update our building speed estimate
                    // 
                    tempPlayerNumbers.updateNumbers(chosenSet[0].getCoordinates(), board);
                    int portType = board.getPortTypeFromNodeCoord(chosenSet[0].getCoordinates());
                    if (portType != -1)
                        tempPortFlags[portType] = true;
                    tempPlayerNumbers.updateNumbers(chosenCity[0].getCoordinates(), board);
                    ourBSE.recalculateEstimates(tempPlayerNumbers);
                    ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
                    settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
                    roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
                    cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
                    cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
                    D.ebugPrintln("WWW  * build a settlement and a city");
                    D.ebugPrintln("WWW    settlement at " + board.nodeCoordToString(chosenSet[0].getCoordinates()));
                    D.ebugPrintln("WWW    city at " + board.nodeCoordToString(chosenCity[0].getCoordinates()));
                    if (brain.getDRecorder().isOn()) {
                        if (fastestETA == settlementBeforeCity) {
                            brain.getDRecorder().record(fastestETA + ": Stlmt at " + board.nodeCoordToString(chosenSet[0].getCoordinates()) + "; City at " + board.nodeCoordToString(chosenCity[0].getCoordinates()));
                        } else {
                            brain.getDRecorder().record(fastestETA + ": City at " + board.nodeCoordToString(chosenCity[0].getCoordinates()) + "; Stlmt at " + board.nodeCoordToString(chosenSet[0].getCoordinates()));
                        }
                    }
                } else if ((cityPiecesLeft > 1) && (citySpotsLeft > 1) && (fastestETA == twoCities)) {
                    posCitiesCopy.remove(Integer.valueOf(chosenCity[0].getCoordinates()));
                    // 
                    // update our building speed estimate
                    // 
                    tempPlayerNumbers.updateNumbers(chosenCity[0].getCoordinates(), board);
                    // 
                    // pick the second city to build
                    // 
                    int bestCitySpeedupTotal = 0;
                    Iterator<SOCPossibleCity> posCities1Iter = posCitiesCopy.values().iterator();
                    while (posCities1Iter.hasNext()) {
                        SOCPossibleCity posCity1 = posCities1Iter.next();
                        tempPlayerNumbers.updateNumbers(posCity1.getCoordinates(), board);
                        D.ebugPrintln("tempPlayerNumbers = " + tempPlayerNumbers);
                        tempBSE.recalculateEstimates(tempPlayerNumbers);
                        int[] tempBuildingSpeed = tempBSE.getEstimatesFromNothingFast(tempPortFlags);
                        int tempSpeedupTotal = 0;
                        // boolean ok = true;
                        for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
                            D.ebugPrintln("ourBuildingSpeed[" + buildingType + "] = " + ourBuildingSpeed[buildingType]);
                            D.ebugPrintln("tempBuildingSpeed[" + buildingType + "] = " + tempBuildingSpeed[buildingType]);
                            if ((ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]) >= 0) {
                                tempSpeedupTotal += (ourBuildingSpeed[buildingType] - tempBuildingSpeed[buildingType]);
                            } else {
                            // ok = false;
                            }
                        }
                        // if (ok) {
                        // good++;
                        // } else {
                        // bad++;
                        // //
                        // // output the player number data
                        // //
                        // System.out.println("New Player Numbers = "+tempPlayerNumbers);
                        // System.out.print("New Ports = ");
                        // for (int i = 0; i <= SOCBoard.WOOD_PORT; i++) {
                        // System.out.print(tempPortFlags[i]+",");
                        // }
                        // System.out.println();
                        // }
                        tempPlayerNumbers.undoUpdateNumbers(posCity1.getCoordinates(), board);
                        D.ebugPrintln("tempPlayerNumbers = " + tempPlayerNumbers);
                        D.ebugPrintln("WWW City at " + board.nodeCoordToString(posCity1.getCoordinates()) + " has tempSpeedupTotal = " + tempSpeedupTotal);
                        if (tempSpeedupTotal >= bestCitySpeedupTotal) {
                            bestCitySpeedupTotal = tempSpeedupTotal;
                            chosenCity[1] = posCity1;
                        }
                    }
                    if (chosenCity[1] == null) {
                        System.out.println("OOPS!!!");
                    } else {
                        posCitiesCopy.remove(Integer.valueOf(chosenCity[1].getCoordinates()));
                    }
                    settlementPiecesLeft += 2;
                    cityPiecesLeft -= 2;
                    citySpotsLeft -= 2;
                    tempPlayerNumbers.updateNumbers(chosenCity[1].getCoordinates(), board);
                    ourBSE.recalculateEstimates(tempPlayerNumbers);
                    ourBuildingSpeed = ourBSE.getEstimatesFromNothingFast(tempPortFlags);
                    settlementETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.SETTLEMENT];
                    roadETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.ROAD];
                    cityETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CITY];
                    cardETA = ourBuildingSpeed[SOCBuildingSpeedEstimate.CARD];
                    D.ebugPrintln("WWW  * build 2 cities");
                    D.ebugPrintln("WWW    city 1: " + board.nodeCoordToString(chosenCity[0].getCoordinates()));
                    D.ebugPrintln("WWW    city 2: " + board.nodeCoordToString(chosenCity[1].getCoordinates()));
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": City at " + board.nodeCoordToString(chosenCity[0].getCoordinates()) + "; City at " + board.nodeCoordToString(chosenCity[1].getCoordinates()));
                    }
                } else if (!haveLR && !needLR && (points > 5) && (fastestETA == tempLongestRoadETA)) {
                    needLR = true;
                    D.ebugPrintln("WWW  * take longest road");
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": Longest Road");
                    }
                } else if (!haveLA && !needLA && (points > 5) && (fastestETA == tempLargestArmyETA)) {
                    needLA = true;
                    D.ebugPrintln("WWW  * take largest army");
                    if (brain.getDRecorder().isOn()) {
                        brain.getDRecorder().record(fastestETA + ": Largest Army");
                    }
                }
            }
        }
        D.ebugPrintln("WWW TOTAL WGETA FOR PLAYER " + playerNumber + " = " + winGameETA);
        if (brain.getDRecorder().isOn()) {
            brain.getDRecorder().record("Total WGETA for " + player.getName() + " = " + winGameETA);
            brain.getDRecorder().record("--------------------");
        }
    } catch (Exception e) {
        winGameETA = oldWGETA;
        System.out.println("Exception in recalcWinGameETA - " + e);
        e.printStackTrace();
    }
// System.out.println("good = "+good+" bad = "+bad);
// System.out.println();
}
Also used : SOCBoard(soc.game.SOCBoard) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) SOCPlayerNumbers(soc.game.SOCPlayerNumbers) SOCPlayer(soc.game.SOCPlayer)

Example 2 with SOCPlayerNumbers

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

the class SOCPossibleCity method updateSpeedup.

/**
 * calculate the speedup that this city gives.
 * Call when any player's new city or settlement is added to the board.
 * @see #getSpeedup()
 */
public void updateSpeedup() {
    // D.ebugPrintln("****************************** (CITY) updateSpeedup at "+Integer.toHexString(coord));
    SOCBuildingSpeedEstimate bse1 = new SOCBuildingSpeedEstimate(player.getNumbers());
    int[] ourBuildingSpeed = bse1.getEstimatesFromNothingFast(player.getPortFlags());
    SOCPlayerNumbers newNumbers = new SOCPlayerNumbers(player.getNumbers());
    newNumbers.updateNumbers(new SOCCity(player, coord, null), player.getGame().getBoard());
    SOCBuildingSpeedEstimate bse2 = new SOCBuildingSpeedEstimate(newNumbers);
    int[] speed = bse2.getEstimatesFromNothingFast(player.getPortFlags());
    for (int buildingType = SOCBuildingSpeedEstimate.MIN; buildingType < SOCBuildingSpeedEstimate.MAXPLUSONE; buildingType++) {
        // D.ebugPrintln("!@#$% ourBuildingSpeed[buildingType]="+ourBuildingSpeed[buildingType]+" speed[buildingType]="+speed[buildingType]);
        speedup[buildingType] = ourBuildingSpeed[buildingType] - speed[buildingType];
    }
}
Also used : SOCCity(soc.game.SOCCity) SOCPlayerNumbers(soc.game.SOCPlayerNumbers)

Aggregations

SOCPlayerNumbers (soc.game.SOCPlayerNumbers)2 ArrayList (java.util.ArrayList)1 TreeMap (java.util.TreeMap)1 SOCBoard (soc.game.SOCBoard)1 SOCCity (soc.game.SOCCity)1 SOCPlayer (soc.game.SOCPlayer)1