-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTeamAM.java
380 lines (308 loc) · 13.8 KB
/
TeamAM.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
public class TeamAM extends Player {
// for DoubleAgent
private Handshaker shaker;
boolean opponentHadWinningPosition; //set to true if opponent can force a win at any point in the match.
int trust;
// TODO BY ZOE: REMEMBER TO TURN THIS OFF
public final boolean DEBUG_MODE = false;
public final boolean CHECK_MODE = false;
public byte[] bestMoveBytesRealist, scoreWhiteBytesRealist, scoreBlackBytesRealist;
public byte[] bestMoveBytesCooperative, scoreWhiteBytesCooperative, scoreBlackBytesCooperative;
public int BETRAYAL_DELTA = 1;
public int COOPERATION_DELTA = 1;
public int IRRATIONALITY_DELTA = 2;
public int SUBOPTIMALITY_DELTA = 1;
int monkeyScore;
boolean isDetectMonkeyModeOn;
boolean isOpponentMonkey;
boolean isOpponentNihilist = false;
boolean isOpponentOptimist = false;
boolean isOpponentPessimist = false;
boolean isOpponentQueller = false;
boolean isOpponentRealist = false;
boolean isOpponentScrapper = false;
boolean isOpponentTruster = false;
boolean isOpponentUtilitarian = false;
boolean opponentCanCaptureKingThisRound;
boolean opponentCanCaptureRookThisRound;
int matchNum;
public TeamAM(int maxNumMoves) {
TeamRational teamRationalRealist = TeamRational.createRealist(maxNumMoves);
// Take the data that we need from teamRationalRealist:
bestMoveBytesRealist = teamRationalRealist.bestMoveBytes;
scoreWhiteBytesRealist = teamRationalRealist.scoreWhiteBytes;
scoreBlackBytesRealist = teamRationalRealist.scoreBlackBytes;
// then teamRationalRealist will be deconstructed.
TeamRational teamRationalCooperative = TeamRational.createCooperative(maxNumMoves);
// Take the data that we need from teamRationalCooperative:
bestMoveBytesCooperative = teamRationalCooperative.bestMoveBytes;
scoreWhiteBytesCooperative = teamRationalCooperative.scoreWhiteBytes;
scoreBlackBytesCooperative = teamRationalCooperative.scoreBlackBytes;
// then teamRationalCooperative will be deconstructed.
shaker = Handshaker.createHandshakeAccepter();
}
public void prepareForSeries() {
trust = 1;
monkeyScore = 0;
matchNum = 0;
isDetectMonkeyModeOn = true;
isOpponentMonkey = true;
opponentCanCaptureKingThisRound = false;
opponentCanCaptureRookThisRound = false;
shaker.handshakePrepareForSeries();
}
public String parseThreatenBy(String input) {
try{
return input.substring(input.lastIndexOf('/') + 1);
} catch(Exception e) {
if(DEBUG_MODE) {
System.out.println("THERE IS A FUCKING STRING ERROR!!!!");
}
// let's just swing it
return "EXCEPTION";
}
}
public void prepareForMatch() {
BoardPosition boardPosition;
opponentHadWinningPosition = false;
matchNum += 1;
// Start in second : record the gameboard config?
if (myColour == BLACK) {
//System.out.println("\n**************[prepareForMatch] Match "+matchNum+" We are BLACK");
boardPosition = toBoardPosition();
if (scoreBlackBytesRealist[boardPosition.toInt()] == 0) {
opponentHadWinningPosition = true;
}
String kingRes = checkNextThreaten(myKingRow, myKingColumn, "king", "InsidePrepareForMatch");
String rookRes = checkNextThreaten(myRookRow, myRookColumn, "rook", "InsidePrepareForMatch");
String myKingThreatenBy = parseThreatenBy(kingRes);
String myRookThreatenBy = parseThreatenBy(rookRes);
opponentCanCaptureKingThisRound = !myKingThreatenBy.equals("safe");
opponentCanCaptureRookThisRound = !myRookThreatenBy.equals("safe");
if(DEBUG_MODE) {
System.out.println("===");
System.out.println("[prepareForMatch] isMyTurn: " + (myColour == numMovesPlayed%2));
System.out.println("[prepareForMatch] kingRes: "+kingRes);
System.out.println("[prepareForMatch] rookRes: "+rookRes);
if(opponentCanCaptureRookThisRound) System.out.println("[prepareForMatch] Opponent can capture our rook ");
if(opponentCanCaptureKingThisRound) System.out.println("[prepareForMatch] Opponent can capture our king");
System.out.println("===");
}
} else {
if(DEBUG_MODE) System.out.println("\n**************[prepareForMatch] Match "+matchNum+" We are WHITE");
}
shaker.handshakePrepareForMatch(toBoardPosition());
}
public void receiveMatchOutcome(int matchOutcome) {
//Convert to a more reasonable format first:
int myMatchPayoff = outcomeToPayoff(matchOutcome);
trust = updateTrust(trust, myMatchPayoff);
//System.out.println("Match "+matchNum+" This is a monkey: "+isOpponentMonkey+" Monkey score is "+monkeyScore);
shaker.handshakeReceiveMatchOutcome(matchOutcome, toBoardPosition());
}
public int updateTrust(int trust, int myMatchPayoff) {
if (trust>0) { // I trusted you! Let's see how you did:
if (myMatchPayoff < 2) {
// I didn't take your king? I trust you less now.
return trust - BETRAYAL_DELTA;
} else if (myMatchPayoff == 3) {
// I tried to tie, but I won!!! I don't trust that you know what you're doing.
//isOpponentMonkey += 2;
return trust - IRRATIONALITY_DELTA;
}
} else if (opponentHadWinningPosition && myMatchPayoff == 2) {
// I didn't trust you. I'm very picky about restoring trust!
// You gave up a win for a tie? I trust you more now.
return trust + COOPERATION_DELTA;
} else if (opponentHadWinningPosition && myMatchPayoff != 2) {
// I don't believe that you needed to let me win.
//isOpponentMonkey += 4;
return trust - SUBOPTIMALITY_DELTA;
}
return trust;
}
public boolean isBlocked(int src, int dest, int curr) {
return (src <= curr && curr <= dest) ||
(dest <= curr && curr <= src);
}
// can be used to check current threaten as well
public String checkNextThreaten(int myNextRow, int myNextCol, String myNextPieceType, String state) {
if(DEBUG_MODE) {
System.out.println("*********Check Next Threaten******* Move Num is "+numMovesPlayed+"*****");
}
if(myNextPieceType.equals("king")) {
myKingRow = myNextRow;
myKingColumn = myNextCol;
} else {
myRookRow = myNextRow;
myRookColumn = myNextCol;
}
// those two statements shouldn't be printed at any cases!
if (myNextPieceType.equals("king") && !myKingIsAlive) return "delete non-existing king /error";
if (myNextPieceType.equals("rook") && !myRookIsAlive) return "delete non-existing rook /error";
boolean doesMoveCaptureTheirKing = myNextRow==theirKingRow && myNextCol==theirKingColumn;
boolean doesMoveCaptureTheirRook = myNextRow==theirRookRow && myNextCol==theirRookColumn;
boolean isThreatenByTheirKing = (!doesMoveCaptureTheirKing && theirKingIsAlive && Math.abs(theirKingRow - myNextRow) <= 1 && Math.abs(theirKingColumn - myNextCol) <= 1);
if(DEBUG_MODE && isThreatenByTheirKing) {
System.out.println("[check next threat] "+myNextPieceType+" is threatened by their king");
}
// isThreatenByTheirRook: two directions
boolean threatenHorizon;
boolean threatenVertical;
// if(myColour != 1 && numMovesPlayed != 0) {
// same row
if (myNextPieceType.equals("king")) {
threatenHorizon = (theirRookRow == myKingRow) &&
// blocked if their king is on the same row and blocks the column
!(isBlocked(theirRookColumn, myKingColumn, theirKingColumn)&& theirKingRow==theirRookRow) &&
// blocked if their rook is on the same row and blocks the column
!(isBlocked(theirRookColumn, myKingColumn, myRookColumn) && myRookRow==theirRookRow);
// same column
threatenVertical = (theirRookColumn == myKingColumn) &&
// blocked if their king is on the same column and blocks the row
!(isBlocked(theirRookRow, myKingRow, theirKingRow) && theirKingColumn == theirRookColumn) &&
!(isBlocked(theirRookRow, myKingRow, myRookRow) && myRookColumn==theirRookColumn);;
} else {
threatenHorizon = (theirRookRow == myRookRow) &&
// blocked if their king is on the same row and blocks the column
!(isBlocked(theirRookColumn, myRookColumn, theirKingColumn) && theirKingRow==theirRookRow) &&
// blocked if their rook is on the same row and blocks the column
!(isBlocked(theirRookColumn, myRookColumn, myKingColumn) && myKingRow==theirRookRow);
// same column
threatenVertical = (theirRookColumn == myRookColumn) &&
// blocked if their king is on the same column and blocks the row
!(isBlocked(theirRookRow, myRookRow, theirKingRow) && theirKingColumn == theirRookColumn) &&
!(isBlocked(theirRookRow, myRookRow, myKingRow) && myKingColumn == theirRookColumn);;
}
/*
} else {
threatenHorizon = (theirRookRow == myNextRow) && !isBlocked(theirRookColumn, myNextCol, theirKingColumn);
threatenVertical = (theirRookColumn == myNextCol) && !isBlocked(theirRookRow, myNextRow, theirKingRow);
}
*/
boolean isThreatenByTheirRook = (!doesMoveCaptureTheirRook && theirRookIsAlive && (threatenHorizon || threatenVertical));
if(DEBUG_MODE && isThreatenByTheirRook) {
System.out.println("[check next threat] "+myNextPieceType+" is threatened by their rook");
}
boolean isThreaten = isThreatenByTheirKing || isThreatenByTheirRook;
if (myNextPieceType.equals("king")) {
opponentCanCaptureKingThisRound = isThreaten;
} else if (myNextPieceType.equals("rook")) {
opponentCanCaptureRookThisRound = isThreaten;
}
String res = myNextPieceType;
if(isThreatenByTheirKing && isThreatenByTheirRook) {
res += " threaten by /both";
} else if(isThreatenByTheirKing) {
res += " threaten by /theirKing";
} else if(isThreatenByTheirRook) {
res += " threaten by /theirRook";
} else {
res = "/safe";
}
if(DEBUG_MODE) {
System.out.println("STATE = XXXX "+state);
System.out.println("Current numMovesPlayed "+ numMovesPlayed);
System.out.println("My next "+myNextPieceType+": [" + myNextRow + ", " + myNextCol + "]");
System.out.println("My current king: ["+myKingRow+", "+myKingColumn+"]");
System.out.println("My current rook: ["+myRookRow+", "+myRookColumn+"]");
System.out.println("Their current king: ["+theirKingRow+", "+theirKingColumn+"]");
System.out.println("Their current rook: ["+theirRookRow+", "+theirRookColumn+"]");
}
return res;
}
// Against DoubleAgent ONLY!!!
public MoveDescription chooseMove() {
BoardPosition currentBoardPosition = toBoardPosition();
// update shaker with opponent move
shaker.updateTheirMove(currentBoardPosition);
MoveDescription myMove;
if (shaker.shouldSendHandshakeMove()) {
myMove=Handshaker.getHandshakeMove(currentBoardPosition);
} else {
myMove = internalChooseMove();
}
shaker.receiveMyMove(myMove);
return myMove;
}
// the original chooseMove: now this is for all the non-doubleAgent player
public MoveDescription internalChooseMove() {
BoardPosition boardPosition = toBoardPosition();
int currentPlayerColour = (boardPosition.numMovesPlayed % 2 == 0) ? WHITE : BLACK;
opponentHadWinningPosition = updateOpponentHadWinningPosition(boardPosition, currentPlayerColour);
return bestMoveFromTrust(boardPosition, currentPlayerColour);
}
// check if king/rook will be eaten in the next round
public boolean kingOrRookCanBeCapturedNextRound(MoveDescription nextMove) {
int myNextRow = nextMove.getDestinationRow();
int myNextCol = nextMove.getDestinationColumn();
String piece = nextMove.getPieceToMove();
return (checkNextThreaten(myNextRow, myNextCol, piece, "CHECKBOTH").equals("safe"));
}
// core function to detect monkey
public boolean isAgainstMonkey(int bestScoreCooperative, int bestScoreRealist) {
// boolean isMyTurn = (numMovesPlayed % 2 == 0 && myColour == 0) || (numMovesPlayed%2!=0 && myColour == 1);
boolean isMyTurn = (numMovesPlayed%2 == myColour);
if(isDetectMonkeyModeOn) {
if (opponentCanCaptureKingThisRound && numMovesPlayed != 0 && myKingIsAlive) {
isOpponentMonkey = false;
isDetectMonkeyModeOn = false;
}
if (opponentCanCaptureRookThisRound && numMovesPlayed != 0 && myRookIsAlive) {
isOpponentMonkey = false;
isDetectMonkeyModeOn = false;
}
}
return isOpponentMonkey;
}
public MoveDescription bestMoveFromTrust(BoardPosition boardPosition, int currentPlayerColour) {
TeamRational.Node nodeRealist = new TeamRational.Node(
bestMoveBytesRealist[boardPosition.toInt()],
scoreWhiteBytesRealist[boardPosition.toInt()],
scoreBlackBytesRealist[boardPosition.toInt()]);
int bestScoreRealist = nodeRealist.getScore(currentPlayerColour);
TeamRational.Node nodeCooperative = new TeamRational.Node(
bestMoveBytesCooperative[boardPosition.toInt()],
scoreWhiteBytesCooperative[boardPosition.toInt()],
scoreBlackBytesCooperative[boardPosition.toInt()]);
int bestScoreCooperative = nodeCooperative.getScore(currentPlayerColour);
isOpponentMonkey = isAgainstMonkey(bestScoreCooperative, bestScoreRealist);
MoveDescription move;
//if (bestScoreRealist==2 || (isMonkey == true && matchNum <= 12)) {
if (bestScoreRealist==2) {
//System.out.println("Monkey score is "+isOpponentMonkey);
// If the move forces a tie, play it in all cases (to be safe):
move = nodeRealist.bestMove;
} else if (trust > 0 && bestScoreCooperative == 3) {
// If trust remains, play cooperatively for a tie:
move = nodeCooperative.bestMove;
} else {
// In all other cases, play realistically:
move = nodeRealist.bestMove;
}
// TODO: change the logic for this one
if(isOpponentMonkey) {
//if(CHECK_MODE) System.out.println("Activating Monkey Code...");
int iteration = 40;
while(iteration>0) {
move = nodeRealist.bestMove;
if(!kingOrRookCanBeCapturedNextRound(move)){
break;
}
iteration -= 1;
}
}
return move;
}
public boolean updateOpponentHadWinningPosition(BoardPosition boardPosition, int currentPlayerColour) {
TeamRational.Node nodeRealist = new TeamRational.Node(
bestMoveBytesRealist[boardPosition.toInt()],
scoreWhiteBytesRealist[boardPosition.toInt()],
scoreBlackBytesRealist[boardPosition.toInt()]);
int bestScoreRealist = nodeRealist.getScore(currentPlayerColour);
if (opponentHadWinningPosition || bestScoreRealist == 0) {
return true;
}
return false;
}
}