001    /*
002     * Created on Feb 15, 2005
003     *
004     */
005    package aima.games;
006    
007    import java.util.ArrayList;
008    
009    import aima.util.Util;
010    
011    /**
012     * @author Ravi Mohan
013     * 
014     */
015    public abstract class Game {
016            protected GameState initialState = new GameState();
017    
018            protected GameState presentState = new GameState();
019    
020            public int getLevel(GameState g) {
021                    return (((Integer) g.get("level")).intValue());
022            }
023    
024            protected int level;
025    
026            public ArrayList getMoves(GameState state) {
027                    return (ArrayList) state.get("moves");
028            }
029    
030            public String getPlayerToMove(GameState state) {
031                    return (String) state.get("player");
032            }
033    
034            public int getUtility(GameState h) {
035                    return ((Integer) h.get("utility")).intValue();
036            }
037    
038            public GameState getState() {
039                    return presentState;
040            }
041    
042            protected abstract int computeUtility(GameState state);
043    
044            protected abstract boolean terminalTest(GameState state);
045    
046            public int maxValue(GameState state) {
047                    int v = Integer.MIN_VALUE;
048                    if (terminalTest(state)) {
049                            return computeUtility(state);
050                    } else {
051                            ArrayList successorList = getSuccessorStates(state);
052                            for (int i = 0; i < successorList.size(); i++) {
053                                    GameState successor = (GameState) successorList.get(i);
054                                    int minimumValueOfSuccessor = minValue(successor);
055                                    if (minimumValueOfSuccessor > v) {
056                                            v = minimumValueOfSuccessor;
057                                            state.put("next", successor);
058                                    }
059                            }
060                            return v;
061                    }
062    
063            }
064    
065            public int minValue(GameState state) {
066    
067                    int v = Integer.MAX_VALUE;
068    
069                    if (terminalTest(state)) {
070                            return computeUtility(state);
071    
072                    } else {
073                            ArrayList successorList = getSuccessorStates(state);
074                            for (int i = 0; i < successorList.size(); i++) {
075                                    GameState successor = (GameState) successorList.get(i);
076                                    int maximumValueOfSuccessors = maxValue(successor);
077                                    if (maximumValueOfSuccessors < v) {
078                                            v = maximumValueOfSuccessors;
079                                            state.put("next", successor);
080                                    }
081                            }
082                            return v;
083                    }
084    
085            }
086    
087            protected int maxValue(GameState state, AlphaBeta ab) {
088                    int v = Integer.MIN_VALUE;
089                    if (terminalTest(state)) {
090                            return computeUtility(state);
091                    } else {
092                            ArrayList successorList = getSuccessorStates(state);
093                            for (int i = 0; i < successorList.size(); i++) {
094                                    GameState successor = (GameState) successorList.get(i);
095                                    int minimumValueOfSuccessor = minValue(successor, ab.copy());
096                                    if (minimumValueOfSuccessor > v) {
097                                            v = minimumValueOfSuccessor;
098                                            state.put("next", successor);
099                                    }
100                                    if (v >= ab.beta()) {
101                                            // System.out.println("pruning from max");
102                                            return v;
103                                    }
104                                    ab.setAlpha(Util.max(ab.alpha(), v));
105                            }
106                            return v;
107                    }
108    
109            }
110    
111            public int minValue(GameState state, AlphaBeta ab) {
112                    int v = Integer.MAX_VALUE;
113    
114                    if (terminalTest(state)) {
115                            return (computeUtility(state));
116    
117                    } else {
118                            ArrayList successorList = getSuccessorStates(state);
119                            for (int i = 0; i < successorList.size(); i++) {
120                                    GameState successor = (GameState) successorList.get(i);
121                                    int maximumValueOfSuccessor = maxValue(successor, ab.copy());
122                                    if (maximumValueOfSuccessor < v) {
123                                            v = maximumValueOfSuccessor;
124                                            state.put("next", successor);
125                                    }
126                                    if (v <= ab.alpha()) {
127                                            // System.out.println("pruning from min");
128                                            return v;
129                                    }
130                                    ab.setBeta(Util.min(ab.beta(), v));
131    
132                            }
133                            return v;
134                    }
135    
136            }
137    
138            public void makeMiniMaxMove() {
139                    getMiniMaxValue(presentState);
140                    GameState nextState = (GameState) presentState.get("next");
141                    if (nextState == null) {
142                            throw new RuntimeException("Mini Max Move failed");
143    
144                    }
145                    makeMove(presentState, nextState.get("moveMade"));
146    
147            }
148    
149            public void makeAlphaBetaMove() {
150                    getAlphaBetaValue(presentState);
151    
152                    GameState nextState = (GameState) presentState.get("next");
153                    if (nextState == null) {
154                            throw new RuntimeException("Alpha Beta Move failed");
155                    }
156                    makeMove(presentState, nextState.get("moveMade"));
157    
158            }
159    
160            public abstract ArrayList getSuccessorStates(GameState state);
161    
162            public abstract GameState makeMove(GameState state, Object o);
163    
164            public boolean hasEnded() {
165                    return (terminalTest(getState()));
166            }
167    
168            public Game() {
169            }
170    
171            public abstract int getMiniMaxValue(GameState state);
172    
173            public abstract int getAlphaBetaValue(GameState state);
174    }