Skip to content

Commit 3720a40

Browse files
committed
v1.0 It can play properly
1 parent 0e79279 commit 3720a40

File tree

1 file changed

+99
-70
lines changed

1 file changed

+99
-70
lines changed

main.cpp

Lines changed: 99 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ using namespace std;
1616
#define OFFSET 1
1717
#define RATIO 1
1818

19+
int nodeCnt = 0;
20+
int evaCnt = 0;
21+
1922
//four directions
2023
int direction[4][2] = {{0, 1}, {1, 0}, {1, -1}, {1, 1}};
2124

@@ -97,24 +100,31 @@ void initModel(int nth, string model, int value){
97100

98101
//initiate the table of models
99102
void initTable(){
100-
initModel(modelCnt++, "ooooo", 100000);
101-
initModel(modelCnt++, "+oooo+", 30000);
102-
initModel(modelCnt++, "++ooo++", 10000);
103-
initModel(modelCnt++, "+ooo++", 6500);
104-
initModel(modelCnt++, "++ooo+", 6500);
105-
initModel(modelCnt++, "oooo+", 6000);
106-
initModel(modelCnt++, "+oooo", 6000);
107-
initModel(modelCnt++, "+++oo+++", 1000);
108-
initModel(modelCnt++, "+++oo++", 500);
109-
initModel(modelCnt++, "++oo+++", 500);
110-
initModel(modelCnt++, "++oo++", 200);
111-
initModel(modelCnt++, "oo", 100);
112-
initModel(modelCnt++, "++++o++++", 50);
113-
sort(modelTable, modelTable + modelCnt + 1, compare);
103+
initModel(modelCnt++, "ooooo", 900000);
104+
initModel(modelCnt++, "+oooo+", 300000);
105+
initModel(modelCnt++, "oooo+", 2500);
106+
initModel(modelCnt++, "+oooo", 2500);
107+
initModel(modelCnt++, "ooo+o", 3000);
108+
initModel(modelCnt++, "o+ooo", 3000);
109+
initModel(modelCnt++, "oo+oo", 2600);
110+
initModel(modelCnt++, "++ooo++", 3000);
111+
initModel(modelCnt++, "ooo++", 500);
112+
initModel(modelCnt++, "++ooo", 500);
113+
initModel(modelCnt++, "+o+oo+", 800);
114+
initModel(modelCnt++, "+oo+o+", 800);
115+
initModel(modelCnt++, "o++oo", 600);
116+
initModel(modelCnt++, "oo++o", 600);
117+
initModel(modelCnt++, "o+o+o", 550);
118+
initModel(modelCnt++, "+++oo+++", 650);
119+
initModel(modelCnt++, "oo+++", 150);
120+
initModel(modelCnt++, "+++oo", 150);
121+
initModel(modelCnt++, "++o+o++", 250);
122+
initModel(modelCnt++, "+o++o+", 200);
123+
sort(modelTable, modelTable + modelCnt, compare);
114124
}
115125

116126
int getScore(string shape){
117-
for (int i = 0; i <= modelCnt; i++){
127+
for (int i = 0; i < modelCnt; i++){
118128
if(shape.find(modelTable[i].shape) != string::npos){
119129
return modelTable[i].value;
120130
}
@@ -123,9 +133,14 @@ int getScore(string shape){
123133
return 0;
124134
}
125135

136+
bool inBoundary(int row, int col){
137+
return row >= 1 && row <= 15 && col >= 1 && col <= 15;
138+
}
139+
126140
vector<Position> pieceOnBoard;
127141

128142
int evaluator(){
143+
evaCnt++;
129144
int totalScore = 0;
130145
memset(chessNumOnDrct, 0, sizeof(chessNumOnDrct));
131146

@@ -137,25 +152,25 @@ int evaluator(){
137152
int enemy = AI + MAN - player;
138153

139154
for (int drct = 0; drct < 4; drct++){
140-
if(chessNumOnDrct[row][col][drct] == -2){
155+
if(chessNumOnDrct[row][col][drct] == -1){
141156
continue;
142157
}
143158

144159
string shape;
145160
int i = row, j = col;
146-
while(i >= 1 && j >= 1 && chessboard[i][j] != enemy){
161+
while(inBoundary(i, j) && chessboard[i][j] != enemy){
147162
i -= direction[drct][0];
148163
j -= direction[drct][1];
149164
}
150165
i += direction[drct][0];
151166
j += direction[drct][1];
152-
while(i <= 15 && j <= 15 && chessboard[i][j] != enemy){
167+
while(inBoundary(i, j) && chessboard[i][j] != enemy){
153168
if(chessboard[i][j] == 0){
154169
shape.append("+");
155170
}
156171
else if(chessboard[i][j] != 0){
157172
shape.append("o");
158-
chessNumOnDrct[i][j][drct] = -2;
173+
chessNumOnDrct[i][j][drct] = -1;
159174
}
160175
i += direction[drct][0];
161176
j += direction[drct][1];
@@ -179,20 +194,20 @@ bool isOver(){
179194
for(vector<Position>::iterator iter = pieceOnBoard.begin(); iter != pieceOnBoard.end(); iter++){
180195
int row = iter->row;
181196
int col = iter->col;
182-
197+
183198
int player = chessboard[row][col];
184199
int enemy = AI + MAN - player;
185200

186201
for (int drct = 0; drct < 4; drct++){
187-
if(chessNumOnDrct[row][col][drct] == -2){
202+
if(chessNumOnDrct[row][col][drct] == -1){
188203
continue;
189204
}
190205

191206
int count = 1; //itself is the one
192207

193208
string shape;
194209
int i = row, j = col;
195-
while(i >= 1 && j >= 1 && chessboard[i][j] == player){
210+
while(inBoundary(i, j) && chessboard[i][j] == player){
196211
count++;
197212
i -= direction[drct][0];
198213
j -= direction[drct][1];
@@ -201,9 +216,9 @@ bool isOver(){
201216

202217
i = row;
203218
j = col;
204-
while(i <= 15 && j <= 15 && chessboard[i][j] == player){
219+
while(inBoundary(i, j) && chessboard[i][j] == player){
205220
count++;
206-
chessNumOnDrct[i][j][drct] = -2;
221+
chessNumOnDrct[i][j][drct] = -1;
207222
i += direction[drct][0];
208223
j += direction[drct][1];
209224
}
@@ -219,7 +234,7 @@ bool isOver(){
219234
}
220235

221236
void setPiece(int row, int col, int player){
222-
chessboard[row][col] = player;
237+
chessboard[row][col] = player;
223238
pieceOnBoard.push_back(Position(row, col));
224239
}
225240

@@ -228,24 +243,36 @@ void delPiece(int row, int col){
228243
pieceOnBoard.pop_back();
229244
}
230245

231-
void getNewPos(vector<Position>& q2, int row, int col, set<Position>& s2){
232-
int u1 = row-1, u2 = row-2, d1 = row+1, d2 = row+2, l1 = col-1, l2 = col-2, r1 = col+1, r2 = col+2;
233-
int row_Arr[24] = {u1,u1,u1,row,row,d1,d1,d1, u2,u2,u2,u2,u2,u1,u1,row,row,d1,d1,d2,d2,d2,d2,d2};
234-
int col_Arr[24] = {l1,col,r1,l1,r1,l1,col,r1, l2,l1,col,r1,r2,l2,r2,l2,r2,l2,r2,l2,l1,col,r1,r2};
235-
236-
for(int i = 0; i < 20; i++){
237-
if(!chessboard[row_Arr[i]][col_Arr[i]]){
246+
void getNewPos(vector<Position>& q2, set<Position>& s2, vector<Position>& q1, int row, int col){
247+
int cnt = 8;
248+
int u1 = row - 1, u2 = row - 2, d1 = row + 1, d2 = row + 2, l1 = col - 1, l2 = col - 2, r1 = col + 1, r2 = col + 2;
249+
// int row_Arr[24] = {u1,u1,u1,row,row,d1,d1,d1, u2,u2,u2,u2,u2,u1,u1,row,row,d1,d1,d2,d2,d2,d2,d2};
250+
// int col_Arr[24] = {l1,col,r1,l1,r1,l1,col,r1, l2,l1,col,r1,r2,l2,r2,l2,r2,l2,r2,l2,l1,col,r1,r2};
251+
252+
int row_Arr[24] = {u1, u1, u1, row, row, d1, d1, d1};
253+
int col_Arr[24] = {l1, col, r1, l1, r1, l1, col, r1};
254+
for (int i = 0; i < cnt; i++)
255+
{
256+
if(!chessboard[row_Arr[i]][col_Arr[i]] && inBoundary(row_Arr[i], col_Arr[i])){
238257
q2.push_back(Position(row_Arr[i], col_Arr[i]));
239258
s2.insert(Position(row_Arr[i], col_Arr[i]));
240259
}
241260
}
261+
262+
for(vector<Position>::iterator it1 = q1.begin(); it1 != q1.end(); it1++){
263+
if(s2.count(*it1) || (it1->row == row && it1->col == col)){
264+
continue;
265+
}
266+
q2.push_back(*it1);
267+
}
268+
269+
242270
}
243271

244272
int alphaBeta(int depth, int alpha, int beta, int player, vector<Position> q1){
245-
if(isOver()){
246-
return 100000;
247-
}
248-
if(depth == 0){
273+
nodeCnt++;
274+
if (depth == 0 || isOver())
275+
{
249276
return evaluator();
250277
}
251278

@@ -261,19 +288,15 @@ int alphaBeta(int depth, int alpha, int beta, int player, vector<Position> q1){
261288
for (vector<Position>::iterator it = q1.begin(); it != q1.end(); it++){
262289
vector<Position> q2;
263290
set<Position> s2;
264-
getNewPos(q2, it->row, it->col, s2);
265-
for(vector<Position>::iterator it1 = q1.begin(); it1 != q1.end(); it1++){
266-
if(s2.count(*it1) || *it1 == *it){
267-
continue;
268-
}
269-
q2.push_back(*it1);
270-
}
291+
getNewPos(q2, s2, q1, it->row, it->col);
271292
setPiece(it->row, it->col, AI);
272293
v = max(v, alphaBeta(depth - 1, alpha, beta, MAN, q2));
273294
delPiece(it->row, it->col);
274295
if(alpha < v){
275-
predictRow = it->row;
276-
predictCol = it->col;
296+
if(depth == DEPTH){
297+
predictRow = it->row;
298+
predictCol = it->col;
299+
}
277300
alpha = v;
278301
}
279302
if(alpha >= beta){
@@ -288,13 +311,7 @@ int alphaBeta(int depth, int alpha, int beta, int player, vector<Position> q1){
288311
for (vector<Position>::iterator it = q1.begin(); it != q1.end(); it++){
289312
vector<Position> q2;
290313
set<Position> s2;
291-
getNewPos(q2, it->row, it->col, s2);
292-
for(vector<Position>::iterator it1 = q1.begin(); it1 != q1.end(); it1++){
293-
if(s2.count(*it1) || *it1 == *it){
294-
continue;
295-
}
296-
q2.push_back(*it1);
297-
}
314+
getNewPos(q2, s2, q1, it->row, it->col);
298315
setPiece(it->row, it->col, MAN);
299316
v = min(v, alphaBeta(depth - 1, alpha, beta, AI, q2));
300317
delPiece(it->row, it->col);
@@ -319,39 +336,51 @@ int main(){
319336
initTable();
320337

321338
setPiece(8, 8, AI);
322-
vector<Position> q1;
339+
vector<Position> q1, t;
323340
set<Position> s1;
324-
getNewPos(q1, 8, 8, s1);
341+
getNewPos(q1, s1, t, 8, 8);
325342
print();
326343
while(1){
327344
int row, col;
328345
cin >> row >> col;
346+
329347
setPiece(row, col, MAN);
348+
330349
vector<Position> q2;
331350
set<Position> s2;
332-
getNewPos(q2, row, col, s2);
333-
for(vector<Position>::iterator it1 = q1.begin(); it1 != q1.end(); it1++){
334-
if(s2.count(*it1) || *it1 == Position(row, col)){
335-
continue;
336-
}
337-
q2.push_back(*it1);
338-
}
351+
getNewPos(q2, s2, q1, row, col);
352+
339353
print();
340-
alphaBeta(DEPTH, MINVALUE, MAXVALUE, AI, q2);
354+
355+
if(isOver()){
356+
cout << "You win!\n";
357+
getchar();
358+
getchar();
359+
break;
360+
}
361+
362+
int value = alphaBeta(DEPTH, MINVALUE, MAXVALUE, AI, q2);
363+
341364
setPiece(predictRow, predictCol, AI);
365+
342366
vector<Position> q3;
343367
set<Position> s3;
344-
getNewPos(q3, predictRow, predictCol, s3);
345-
for(vector<Position>::iterator it1 = q2.begin(); it1 != q2.end(); it1++){
346-
if(s3.count(*it1) || *it1 == Position(predictRow, predictCol)){
347-
continue;
348-
}
349-
q3.push_back(*it1);
350-
}
368+
getNewPos(q3, s3, q2, predictRow, predictCol);
369+
351370
q1 = q3;
371+
352372
print();
373+
374+
if(isOver()){
375+
cout << "AI win!\n";
376+
getchar();
377+
getchar();
378+
break;
379+
}
380+
353381
printf("AI: row=%d, col=%d\n", predictRow, predictCol);
382+
printf("Value=%d, %d nodes, %d evaluations\n", value, nodeCnt, evaCnt);
354383
}
355384

356385
return 0;
357-
}
386+
}

0 commit comments

Comments
 (0)