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 }