001    package ai;
002    import rules.Board;
003    import rules.GameState;
004    import rules.Pawn;
005    import core.Color;
006    import core.Piece;
007    
008    /**
009     * The PieceHeuristic maximizes the number of pieces controlled.
010     */
011    public class NegativePieceHeuristic implements Heuristic {
012    
013        public static final int BLOCKED_WEIGHT = -2;
014        public static final int ISOLATED_WEIGHT = -1;
015    
016        /**
017         * @see Heuristic
018         */
019        public int heuristic(GameState currentState) {
020            int total = 0;
021            Board board = currentState.getBoard();
022            Color c = currentState.getCurrentColor();
023            int numMoves = currentState.legalMoves().size();
024            if (numMoves == 1){
025                total -= 4;
026            } else if (numMoves < 5){
027                total -= 2;
028            } else {
029                total += 0;
030            }
031            int lastMyPawnX = -2;
032            int lastOtherPawnX = -2;
033            int numMyPawns = 0;
034            int numMyPieces = 0;
035            int numHisPawns = 0;
036            int numHisPieces = 0; //not pawns;
037            int numBlockedPawns = 0;
038            int numIsolatedPawns = 0;
039            boolean wasIsolated = false;
040            boolean wasBlocked = false;
041            //XXX support #pieces >= numIsolated
042            for(int x = 0; x < 8; x++){
043                for(int y = 0; y < 8; y++){
044                    Piece p = board.get(x, y);
045                    if (p instanceof Pawn){
046                        if (p.getColor() == c){
047                            numMyPawns++;
048                            if (lastMyPawnX < x-1) {
049                                if (wasIsolated) {
050                                    if (wasBlocked) {
051                                        numBlockedPawns++;
052                                    } else {
053                                        numIsolatedPawns++;
054                                    }
055                                }
056                                wasIsolated = true;
057                            } else if (lastMyPawnX == x-1) {
058                                wasIsolated = false;
059                            }
060                            lastMyPawnX = x;
061                            if (lastOtherPawnX == x)
062                                wasBlocked = true;
063                            else
064                                wasBlocked = false;
065                        } else {
066                            numHisPawns++;
067                            lastOtherPawnX = x;
068                            if (lastMyPawnX == x)
069                                wasBlocked = true;
070                        }
071                    } else {
072                        if (p.getColor() == c){
073                            numMyPieces++;
074                        } else if (p.getColor() == c.otherColor()) {
075                            numHisPieces++;
076                        }
077                    }
078                }
079            }
080    
081            if (wasIsolated) {
082                if (wasBlocked) {
083                    numBlockedPawns++;
084                } else {
085                    numIsolatedPawns++;
086                }
087            }
088            total += (numBlockedPawns * BLOCKED_WEIGHT  +
089                      numIsolatedPawns * ISOLATED_WEIGHT + 
090                      (numMyPawns - numHisPawns) * 1 +
091                      (numMyPieces - numHisPieces) * 2);
092            //if (numMyPieces < numMyPawns) {
093            //    total -= 4;
094            //}
095            //total = (numMyPawns + numMyPieces - numHisPawns - numHisPieces);
096            return total;
097        }
098    }