-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTicTacGeniusBot.java
181 lines (156 loc) · 6.66 KB
/
TicTacGeniusBot.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
/* the genius bot always wins or ties */
public class TicTacGeniusBot implements TicTacToeBot{
int next_move_xcor, next_move_ycor, team, numcalcs;
TicTacBoard infoBoard;
/* makes a new ai with access to the gameboard*/
public TicTacGeniusBot(TicTacBoard newboard, int n){
infoBoard = newboard;
team = n;
}
/*gets best possible move*/
public void getNextMove(){
int[] next_move_array = nextBestMove();
next_move_xcor = next_move_array[0];
next_move_ycor = next_move_array[1];
}
private boolean isWinner(int x,int y){
int[][] tempinfoBoard = infoBoard.getIntArray();
tempinfoBoard[x][y] = team;
return diagonalWinner(tempinfoBoard) ||
row1Winner(tempinfoBoard) || row2Winner(tempinfoBoard) || row3Winner(tempinfoBoard) ||
vert1Winner(tempinfoBoard) || vert2Winner(tempinfoBoard) || vert3Winner(tempinfoBoard);
}
private boolean isWinner(int x,int y, int[][] tempinfoBoard){
tempinfoBoard[x][y] = team;
return diagonalWinner(tempinfoBoard) ||
row1Winner(tempinfoBoard) || row2Winner(tempinfoBoard) || row3Winner(tempinfoBoard) ||
vert1Winner(tempinfoBoard) || vert2Winner(tempinfoBoard) || vert3Winner(tempinfoBoard);
}
private boolean isWinner(int[][] tempinfoBoard, int player){
return diagonalWinner(tempinfoBoard) ||
row1Winner(tempinfoBoard) || row2Winner(tempinfoBoard) || row3Winner(tempinfoBoard) ||
vert1Winner(tempinfoBoard) || vert2Winner(tempinfoBoard) || vert3Winner(tempinfoBoard);
}
private boolean isBlocker(int x, int y) {
int newteam = 1;
if (team == 1)
newteam = 2;
int[][] tempinfoBoard = infoBoard.getIntArray();
tempinfoBoard[x][y] = newteam;
return diagonalWinner(tempinfoBoard)
|| row1Winner(tempinfoBoard) || row2Winner(tempinfoBoard) || row3Winner(tempinfoBoard)
|| vert1Winner(tempinfoBoard) || vert2Winner(tempinfoBoard) || vert3Winner(tempinfoBoard);
}
private boolean diagonalWinner(int[][] tempinfoBoard){
return ((tempinfoBoard[0][0] == tempinfoBoard[1][1] && tempinfoBoard[1][1] == tempinfoBoard[2][2]) ||
(tempinfoBoard[2][0] == tempinfoBoard[1][1] && tempinfoBoard[1][1] == tempinfoBoard[0][2])) &&
tempinfoBoard[1][1] != 0;
}
/*@return true if winner on row1*/
private boolean row1Winner(int[][] tempinfoBoard){
return tempinfoBoard[0][0] == tempinfoBoard[0][1] && tempinfoBoard[0][1] == tempinfoBoard[0][2] && tempinfoBoard[0][1] != 0;
}
/*@return true if winner on row2*/
private boolean row2Winner(int[][] tempinfoBoard){
return tempinfoBoard[1][0] == tempinfoBoard[1][1] && tempinfoBoard[1][1] == tempinfoBoard[1][2] && tempinfoBoard[1][1] != 0;
}
/*@return true if winner on row3*/
private boolean row3Winner(int[][] tempinfoBoard){
return tempinfoBoard[2][0] == tempinfoBoard[2][1] && tempinfoBoard[2][1] == tempinfoBoard[2][2] && tempinfoBoard[2][1] != 0;
}
/*@return true if winner on vert1*/
private boolean vert1Winner(int[][] tempinfoBoard){
return tempinfoBoard[0][0] == tempinfoBoard[1][0] && tempinfoBoard[1][0] == tempinfoBoard[2][0] && tempinfoBoard[1][0] != 0;
}
/*@return true if winner on vert2*/
private boolean vert2Winner(int[][] tempinfoBoard){
return tempinfoBoard[0][1] == tempinfoBoard[1][1] && tempinfoBoard[1][1] == tempinfoBoard[2][1] && tempinfoBoard[1][1] != 0;
}
/*@return true if winner on vert3*/
private boolean vert3Winner(int[][] tempinfoBoard){
return tempinfoBoard[0][2] == tempinfoBoard[1][2] && tempinfoBoard[1][2] == tempinfoBoard[2][2] && tempinfoBoard[1][2] != 0;
}
/* calls getNextMove then makes the move*/
public void makeNextMove(){
if (!infoBoard.isFilled()){
getNextMove();
infoBoard.makeMove(next_move_xcor, next_move_ycor);
}
}
/* generates a list of possible moves */
public int[][] getPossibleMoves(int[][] tempInfoBoard) {
int num_moves = 0;
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if (tempInfoBoard[r][c] == 0) {
num_moves++;
}
}
}
int[][] ans = new int[num_moves][2];
int temp = 0;
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if (tempInfoBoard[r][c] == 0) {
ans[temp][0] = r;
ans[temp++][1] = c;
}
}
}
return ans;
}
/* returns the max of 2 moves. move1[0] = r position move1[1] = c position move1[2] = value */
private int max(int move1, int move2){
if (move1 > move2) {
return move1;
}
return move2;
}
private int[] nextBestMove(){
int[][] next_possible_moves = getPossibleMoves(infoBoard.getIntArray());
int[] ans = new int[2];
ans[0] = -1;
ans[1] = -1;
int bestValue = -1000;
int other_player = (team % 2 ) + 1;
for (int[] move : next_possible_moves){
int[][] tempInfoBoard = infoBoard.getIntArray();;
tempInfoBoard[move[0]][move[1]] = team;
if (isWinner(tempInfoBoard, team)){
ans = move;
break;
}
if (0 - nextBestMoveHelper(other_player, tempInfoBoard) >= bestValue){
bestValue = 0 - nextBestMoveHelper(other_player, tempInfoBoard);
ans = move;
}
}
return ans;
}
public int[][] getCopy(int[][] original){
int[][] ans = new int[original.length][original.length];
for (int r = 0; r < original.length; r++){
for (int c = 0 ; c < original.length; c++){
ans[r][c] = original[r][c];
}
}
return ans;
}
private int nextBestMoveHelper(int player, int[][] tempBoard){
numcalcs++;
int[][] next_possible_moves = getPossibleMoves(tempBoard);
if (next_possible_moves.length == 0)
return 0;
int bestValue = -1000;
int other_player = (player % 2) + 1;
for (int[] move : next_possible_moves){
int[][] tempInfoBoard = getCopy(tempBoard);
tempInfoBoard[move[0]][move[1]] = player;
if (isWinner(tempInfoBoard, player)){
return 1000;
}
bestValue = max(bestValue, 0 - nextBestMoveHelper(other_player, tempInfoBoard));
}
return bestValue;
}
}