001    /**
002     * 
003     */
004    package jagafa.ai;
005    
006    import jagafa.JassRound;
007    import jagafa.flags.TestingFlags;
008    import jagafa.object.Board;
009    import jagafa.object.Card;
010    import jagafa.object.CardList;
011    import jagafa.object.GoneCardHeap;
012    import jagafa.object.Hand;
013    import jagafa.object.Player;
014    import jagafa.rule.RuleSet;
015    import jagafa.stats.PlayerStats;
016    
017    /**
018     * A simple (quite stupid) AI implementation
019     * 
020     */
021    public class SimpleAI implements JassAI {
022    
023            private Player player_;
024    
025            private JassRound round_;
026    
027            private RuleSet rules_;
028    
029            private GoneCardHeap goneHeap_;
030    
031            private Hand hand_;
032    
033            private int trumpfColor_;
034    
035            private Board board_;
036    
037            private PlayerStats stats_;
038            private int turnNr = -1;
039            
040            
041            public Card computeCard() {
042                    this.hand_ = this.player_.getHand();
043                    this.stats_ = new PlayerStats(this.round_,this.player_);
044                    this.goneHeap_ = this.round_.getGoneHeap();
045                    Card c = getCard();
046                    if (TestingFlags.aiStrategyDump_)System.out.println(c);
047                    return c;
048    
049            }
050    
051            
052            /**
053             * @return
054             */
055            private Card getCard() {
056                    
057                    this.stats_.update();
058                    //this.stats_.printTree();
059                    this.hand_ = this.player_.getHand();
060    
061                    if (this.round_.activeBoard().get(0) != null) {
062                            Card firstCard = board_.get(0);
063                            
064                            CardList cardsOfFirst = stats_.getColorList()[firstCard.getColor()];
065    
066                            if (cardsOfFirst.size() == 0) {
067                                    if (TestingFlags.aiStrategyDump_)System.out.print("Throw: ");
068                                    return throwAway(); // Verrüärä
069                            } else {
070                                    if (TestingFlags.aiStrategyDump_)System.out.print("Color: ");
071                                    return sameColor(firstCard.getColor()); // Farben spielen
072                            }
073                    } else {
074                            if (hasBock(0)) {
075                                    if (TestingFlags.aiStrategyDump_)System.out.print("Bock: ");
076                                    return getBock(); // Böcke spielen
077                            }
078                            if (TestingFlags.aiStrategyDump_)System.out.print("Tear: ");
079                            return tearOut(); // Farbe Anziehen bzw. dem Partner bringen
080                    }
081                    
082            }
083    
084            /**
085             * @return
086             */
087            private Card tearOut() {
088                    int colorWithMost = getColorWithMost(stats_.getColorList());
089    
090                    for (int bockNth = 8; bockNth > 5; bockNth--) {
091                            if (hasBock(bockNth, colorWithMost)) {
092                                    return getBock(bockNth, colorWithMost);
093                            }
094                    }
095    
096                    for (int bockNth = 8; bockNth > 0; bockNth--) {
097                            if (hasBock(bockNth)) {
098                                    return getBock(bockNth);
099                            }
100                    }
101                    return null;
102            }
103    
104            /**
105             * @return
106             */
107            private Card getBock() {
108                    Card resultCard = null;
109                    int colorWithMost = getColorWithMost(stats_.getColorList());
110                    if (colorWithMost != -1) {
111                            resultCard = getBock(0, colorWithMost); 
112                            return resultCard;
113                    }
114                    int randomNr = (int) (Math.random() * 4);
115                    resultCard = stats_.getBockList()[randomNr].get(0);
116                    return resultCard;
117            }
118    
119            private Card getBock(int nth) {
120                    CardList bockI = stats_.getBockList()[nth];
121                    if (bockI.size() > 0) {
122                            for (int i = 0; i < bockI.size(); i++) {
123    
124                                    return bockI.get(i);
125    
126                            }
127    
128                    }
129                    return null;
130            }
131    
132            // Gibt einen bock der farbe color zurück
133            private Card getBock(int nth, int color) {
134                    Card resultCard = null;
135                    CardList bockI = stats_.getBockList()[nth];
136                    if (bockI.size() > 0) {
137                            for (int i = 0; i < bockI.size(); i++) {
138                                    if (bockI.get(i).getColor() == color) {
139                                            return bockI.get(i);
140                                    }
141                            }
142    
143                    }
144                    return resultCard;
145            }
146    
147            /**
148             * @return
149             */
150            private int getColorWithMost(CardList cardL[]) {
151                    int mostNrColor = -1;
152                    int colorWithMost = -1;
153    
154                    for (int i = 0; i < cardL.length; i++) {
155                            CardList colori = cardL[i];
156                            int nrColorI = colori.size();
157                            if (nrColorI >= mostNrColor && hasBock(0, i)) {
158                                    mostNrColor = nrColorI;
159                                    colorWithMost = i;
160    
161                            }
162                    }
163                    return colorWithMost;
164            }
165    
166            /**
167             * @return
168             */
169            private boolean hasBock(int nth) {
170                    for (int i = 0; i < 4; i++) {
171                            if (hasBock(nth, i)) {
172                                    return true;
173                            }
174    
175                    }
176                    return false;
177            }
178    
179            private boolean hasBock(int nth, int color) {
180                    CardList bockI = stats_.getBockList()[nth];
181                    if (bockI.size() > 0) {
182                            for (int i = 0; i < bockI.size(); i++) {
183                                    if (bockI.get(i).getColor() == color) {
184                                            return true;
185                                    }
186                            }
187                    }
188                    return false;
189            }
190    
191            /**
192             * @param cardsOfFirst
193             */
194            private Card sameColor(int color) {
195                    if (hasBock(0, color)) {
196                            return getBock(0, color);
197                    } else {
198                            for (int bockNth = 8; bockNth > 0; bockNth--) {
199                                    if (hasBock(bockNth, color)) {
200                                            return getBock(bockNth, color);
201                                    }
202                            }
203                    }
204                    return null;
205            }
206    
207            /**
208             * 
209             */
210            private Card throwAway() {
211                    int throwAwayColor = -1;
212                    int minColorValue = -1;
213                    for (int c = 0; c < 4; c++) {
214                            int colorValue = getColorValue(c);
215                            if (colorValue > minColorValue) {
216                                    minColorValue = colorValue;
217                                    throwAwayColor = c;
218                            }
219                    }
220    
221                    for (int bockNth = 8; bockNth >= 0; bockNth--) {
222                            if (hasBock(bockNth, throwAwayColor)) {
223                                    return getBock(bockNth, throwAwayColor);
224                            }
225                    }
226                    for (int c = 0; c < 4; c++) {
227                            for (int bockNth = 8; bockNth >= 0; bockNth--) {
228                                    if (hasBock(bockNth, c)) {
229                                            return getBock(bockNth, c);
230                                    }
231                            }
232                    }
233                    return null;
234    
235            }
236    
237            /**
238             * @param c
239             * @return
240             */
241            private int getColorValue(int c) {
242                    int value = 0;
243                    for (int i = 0; i < 8; i++) {
244                            if (hasBock(i, c)) {
245                                    value += (i) * (i);
246                            }
247                    }
248                    return value;
249            }
250    
251            /*
252             * (non-Javadoc)
253             * 
254             * @see jass.JassAI#init(jass.JassGame)
255             */
256            public void init(Player p, JassRound round) {
257                    this.player_ = p;
258                    this.round_ = round;
259                    this.rules_ = round.getRules();
260                    this.goneHeap_ = round.getGoneHeap();
261                    this.board_ = round_.activeBoard();
262    
263            }
264    
265    
266            public RuleSet chooseRuleSet() {
267                    return RuleSetChoiceAI.chooseRuleSet(this.player_,this.round_);
268            }
269    
270    }