001 package jagafa.ai;
002
003 import jagafa.JassRound;
004 import jagafa.flags.AIFlags;
005 import jagafa.flags.TestingFlags;
006 import jagafa.object.CardList;
007 import jagafa.object.Hand;
008 import jagafa.object.Player;
009 import jagafa.rule.ObenRules;
010 import jagafa.rule.RuleSet;
011 import jagafa.rule.UntenRules;
012 import jagafa.scores.ScoreTable;
013 import jagafa.stats.CardTool;
014 import jagafa.stats.PlayerStats;
015
016 import java.util.List;
017
018 public abstract class RuleSetChoiceAI {
019
020 private static final int COLORS = 4;
021
022 private static Player player_;
023
024 private static ScoreTable scoreTable_;
025
026 private static JassRound round_;
027
028 public static RuleSet chooseRuleSet(Player p, JassRound round) {
029
030 player_ = p;
031 scoreTable_ = round.getScoreTable();
032 round_ = round;
033
034 List<RuleSet> rules_ = scoreTable_.getRules();
035
036 RuleSet rule = null;
037
038 double estimates[] = new double[rules_.size()];
039 Hand h = player_.getHand();
040 if (TestingFlags.ruleSetChoiceDump_) {
041 //System.out.println("Player's hand: " + h);
042 }
043 int highest = -10;
044 double highestEstimate = -100;
045 double gradeWeight = AIFlags.GRADE_WEIGHT;
046
047 for (int i = 0; i < rules_.size(); i++) {
048
049 estimates[i] = gradeWeight * gradeRuleSet(rules_.get(i));
050 if (rules_.get(i).getName().startsWith("Slalom")) {
051 estimates[i] = gradeSlalom(rules_.get(i));
052 }
053
054 //estimates[i] += (1 - gradeWeight) * estimateScore(rules_.get(i));
055 if (estimates[i] > highestEstimate) {
056 highest = i;
057 highestEstimate = estimates[i];
058 }
059 }
060
061 if (TestingFlags.ruleSetChoiceDump_) {
062 System.out.println("\nStrength estimates: ");
063 for (int i = 0; i < rules_.size(); i++) {
064 System.out.println(rules_.get(i).getName() + " \t" + estimates[i]);
065
066 }
067 }
068 if (highestEstimate < AIFlags.CHANGE_TRESHOLD) {
069
070 if (scoreTable_.canChangeChoosingPlayer()) {
071 return null;
072 }
073 }
074
075 rule = rules_.get(highest);
076
077 return rule;
078
079 }
080
081 private static double gradeSlalom(RuleSet set) {
082 ObenRules oben = new ObenRules();
083 UntenRules unten = new UntenRules();
084
085 double obenEst = gradeRuleSet(oben);
086 double untenEst = gradeRuleSet(unten);
087
088 JassRound round = new JassRound(oben);
089
090 int secureOben = 0;
091 int addOben = 0;
092 PlayerStats stats_ = new PlayerStats(round, player_);
093 CardList bockList[] = stats_.getBockList();
094
095 for (int i = 0; i < COLORS; i++) {
096 secureOben += bocksOfColorInRow(bockList, i);
097 CardList colorList = stats_.getColorList()[i];
098
099 int addOfColor = (colorList.size() - secureOben);
100 if (addOfColor > 2) {
101 addOben += addOfColor;
102 }
103
104 }
105
106 round = new JassRound(oben);
107
108 int secureUnten = 0;
109 int addUnten = 0;
110 stats_ = new PlayerStats(round, player_);
111 bockList = stats_.getBockList();
112
113 for (int i = 0; i < COLORS; i++) {
114 secureUnten += bocksOfColorInRow(bockList, i);
115
116 CardList colorList = stats_.getColorList()[i];
117
118 int addOfColor = (colorList.size() - secureUnten);
119 if (addOfColor > 2) {
120 addUnten += addOfColor;
121 }
122
123 }
124
125 int diff = Math.abs(secureOben - secureUnten);
126 double xxx = 1/(diff+0.5);
127
128 return xxx*(secureOben+secureUnten);
129 }
130
131 public static double gradeRuleSet(RuleSet rule) {
132 double scoreEstimate = 0;
133
134 Hand h = player_.getHand();
135
136 round_.setRules(rule);
137 PlayerStats stats_ = new PlayerStats(round_, player_);
138
139 CardList bockList[] = stats_.getBockList();
140 for (int i = 0; i < bockList.length; i++) {
141 CardList nthBock = bockList[i];
142 int nrOfNth = nthBock.size();
143
144 scoreEstimate += (double) ((1 / ((double) i + 1)) * (double) nrOfNth);
145 //System.out.print(nrOfNth + ";"+ scoreEstimate + " " );
146 }
147
148 int numberOfColors = 0;
149
150 for (int i = 0; i < COLORS; i++) {
151 CardList ofCol = CardTool.getAllOfColor(h, i);
152
153 int nrOfCol = ofCol.size();
154 if (nrOfCol > 0) {
155 numberOfColors++;
156 }
157 scoreEstimate += (double) (nrOfCol - 2 > 0 ? nrOfCol - 2 : 1)
158 * (double) bocksOfColorInRow(bockList, i);
159 }
160 scoreEstimate += numberOfColors;
161 return (double) (Math.round(scoreEstimate * 1000.0) / 1000.0);
162
163 }
164
165 private static int bocksOfColorInRow(CardList bockList[], int color) {
166 int inarow = 0;
167 boolean fail = false;
168 for (int i = 0; i < bockList.length; i++) {
169 CardList nthBock = bockList[i];
170 CardList bockColor = CardTool.getAllOfColor(nthBock, color);
171
172 if (bockColor.size() == 0) {
173 /*if (fail) {
174 return inarow;
175 }
176 fail = true;
177 inarow++;*/
178 return inarow;
179 } else {
180 inarow++;
181 }
182
183 }
184
185 return inarow;
186 }
187
188 public static int estimateScore(RuleSet rule) {
189 int strikesEstimate = 0;
190
191 Hand h = player_.getHand();
192
193 round_.setRules(rule);
194 PlayerStats stats_ = new PlayerStats(round_, player_);
195
196 CardList bockList[] = stats_.getBockList();
197
198 for (int i = 0; i < bockList.length; i++) {
199 CardList nthBock = bockList[i];
200 int nrOfNth = nthBock.size();
201
202 }
203 int directStrikes = 0;
204 int additionalEstimate = 0;
205 for (int i = 0; i < COLORS; i++) {
206 int secureStrikes = bocksOfColorInRow(bockList, i);
207 directStrikes += secureStrikes;
208 CardList colorList = stats_.getColorList()[i];
209
210 int addOfColor = (colorList.size() - secureStrikes);
211 if (addOfColor > 2) {
212 additionalEstimate += addOfColor;
213 }
214
215 }
216
217 double directWeight = 22.0;
218 double addWeight = 10.0;
219 double mult = addWeight / directWeight;
220
221 strikesEstimate = directStrikes + (int) Math.round(mult * additionalEstimate);
222
223 double scoreEst = directStrikes * directWeight + additionalEstimate * addWeight;
224
225 /*
226 System.out.print("For " + rule.getName().toUpperCase() + "\t");
227 System.out.println("Estimated Score: " + scoreEst);
228 System.out.println("Where:\tdirect: " + directStrikes + "\tadditional: " + additionalEstimate);
229 System.out.println("Weighted:\t" + strikesEstimate + "\n");
230 */
231
232 return strikesEstimate;
233 }
234 }