001    package ai;
002    import java.util.*;
003    
004    import core.*;
005    import rules.*;
006    
007    /**
008     * The PawnWeightedHeuristic computes a bunch of values to consider,
009     * then ignores most of them because they don't actually help.
010     */
011    public class PawnWeightedPieceHeuristic implements Heuristic {
012    
013        public final int PAWN_WEIGHT;
014        public final int PIECE_WEIGHT;
015        public final int ENDING_WEIGHT;
016        public final int PUSH_WEIGHT;
017    
018        public PawnWeightedPieceHeuristic() {
019            this(-100, 0, 0, 1);
020        }
021    
022        public PawnWeightedPieceHeuristic(int pawn_weight, int piece_weight,
023                                          int ending_weight, int push_weight) {
024            PAWN_WEIGHT = pawn_weight;
025            PIECE_WEIGHT = piece_weight;
026            ENDING_WEIGHT = ending_weight;
027            PUSH_WEIGHT = push_weight;
028        }
029    
030        /**
031         * @see Heuristic
032         */
033        public int heuristic(GameState currentState) {
034            int total = 0;
035            Board board = currentState.getBoard();
036            Color c = currentState.getCurrentColor();
037            Map<Color, Integer> numPawns = new EnumMap<Color, Integer>(Color.class);
038            Map<Color, Integer> numPieces = new EnumMap<Color, Integer>(Color.class);
039            Map<Color, Integer> totalPawnPush = new EnumMap<Color, Integer>(Color.class);
040            for(Color pc: Color.colors){
041                numPawns.put(pc, 0);
042                numPieces.put(pc, 0);
043                totalPawnPush.put(pc, 0);
044            }
045            for(int x = 0; x < 8; x++){
046                for(int y = 0; y < 8; y++){
047                    Piece p = board.get(x, y);
048                    Color pc = p.getColor();
049                    if (p instanceof Pawn){
050                        numPawns.put(pc, numPawns.get(pc)+1);
051                        totalPawnPush.put(pc, totalPawnPush.get(pc) + y);
052                    } else if (pc != Color.NONE) {
053                        numPieces.put(pc, numPieces.get(pc)+1);
054                    }
055                }
056            }
057            totalPawnPush.put(Color.WHITE, 7*numPawns.get(Color.WHITE) - 
058                              totalPawnPush.get(Color.WHITE));
059    
060            for(Color pc: Color.colors) {
061                int colorValue = (numPawns.get(pc) * PAWN_WEIGHT +
062                                  numPieces.get(pc) * PIECE_WEIGHT);
063                if (numPieces.get(pc) <= 3 && 
064                    numPieces.get(pc) <= numPawns.get(pc)) {
065                    colorValue += (numPawns.get(pc) - numPieces.get(pc) + 1) * ENDING_WEIGHT;
066                }
067                colorValue = colorValue - totalPawnPush.get(pc) * PUSH_WEIGHT;
068                total += (c == pc ? 1 : -1) * colorValue;
069    
070            }
071            return total;
072        }
073    }