/
alphabeta.cpp
154 lines (140 loc) · 4.12 KB
/
alphabeta.cpp
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
#include "task.h"
#include "agent.h"
#include "alphabeta.h"
#include "board_info.h"
Board_info Alphabeta::run_alphabeta(Board_info ¤t_board, int depth, int a, int b, char tile)
{
Board_info best_child, temp_child;
vector<Board_info> children;
vector<Board_info>::iterator child;
int break_flag=0;
if (depth == 0){
current_board.visited = 1;
if(tile == your_tile){
current_board.a=a;
current_board.b=current_board.weight;
}
else{
current_board.a=current_board.weight;
current_board.b=b;
}
(DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","<< current_board.weight<<",";
(DEBUG?cout:log) << ab2(a, b)<<endl;
}else{
if(current_board.visited==0){
current_board.visited = 1;
(DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<",";
(DEBUG?cout:log) << (tile == your_tile ?"-":"")<<"Infinity,";
(DEBUG?cout:log) <<ab2(a,b) <<endl;
}
}
if(depth == 0){
return current_board;
}
children = get_new_boards_vector(your_tile, current_board, tile);
// it's pocoutible get 0 child
if(children.size() == 0){
cout<<"no children"<<endl;
current_board.print();
exit(0);
}else{
sort(children.begin(), children.end(), compare_order);
}
best_child.a = a;
best_child.b = b;
if(tile == your_tile){
for(child=children.begin(); child != children.end(); ++child){
temp_child = run_alphabeta(*child, depth -1, best_child.a, best_child.b, other_tile);
best_child = max_a(best_child, temp_child);
(DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","<< best_child.weight<<",";
if(best_child.b<=best_child.a){
cout<<"prune form:"<<xy2(best_child.x, best_child.y)<<endl;
break_flag = 1;
(DEBUG?cout:log) <<ab2(current_board.a,best_child.b)<<endl;
break;
}else{
(DEBUG?cout:log) <<ab2(best_child.a,best_child.b)<<endl;
}
}
}else{
for(child=children.begin(); child != children.end(); ++child){
temp_child = run_alphabeta(*child, depth -1, best_child.a, best_child.b, your_tile);
best_child = min_b(best_child, temp_child);
(DEBUG?cout:log) << xy2(current_board.x, current_board.y)<<","<<this->depth - depth<<","<< best_child.weight<<",";
if(best_child.b<=best_child.a){
cout<<"prune form:"<<xy2(best_child.x, best_child.y)<<endl;
break_flag = 1;
(DEBUG?cout:log) <<ab2(best_child.a,current_board.b)<<endl;
break;
}else{
(DEBUG?cout:log) <<ab2(best_child.a,best_child.b)<<endl;
}
}
}
free_boards(children);
//weight is the only var to save/to callee
current_board.weight = best_child.weight;
current_board.best_child_x = best_child.x;
current_board.best_child_y = best_child.y;
if(break_flag==0){
if(tile == your_tile)
current_board.b = best_child.a;
else
current_board.a = best_child.b;
}
cout << xy2(current_board.x, current_board.y) <<":"<< xy2(current_board.best_child_x, current_board.best_child_y)<<endl;
return current_board;
}
Board_info Alphabeta::max_a(Board_info &board1, Board_info &board2)
{
if(compare_max_a(board1, board2)==1){
cout<<"give up:"<<xy2(board2.x, board2.y)<<"keep best_child:"<<xy2(board1.x, board1.y)<<endl;
return board1;
}
else
return board2;
}
Board_info Alphabeta::min_b(Board_info &board1, Board_info &board2)
{
if(compare_min_b(board1, board2)==1){
cout<<"give up:"<<xy2(board2.x, board2.y)<<"keep best_child:"<<xy2(board1.x, board1.y)<<endl;
return board1;
}
else
return board2;
}
int Alphabeta::compare_max_a(const Board_info &board1, const Board_info &board2)
{
if(board1.a > board2.a)
return 1;
else if(board1.a == board2.a)
return compare_order(board1, board2);
else
return 0;
}
int Alphabeta::compare_min_b(const Board_info &board1, const Board_info &board2)
{
if(board1.b < board2.b)
return 1;
else if(board1.b == board2.b)
return compare_order(board1, board2);
else
return 0;
}
string Alphabeta::ab2(int a, int b)
{
string result="";
if(a==-INFI)
result="-Infinity,";
else if(a==INFI)
result="Infinity,";
else
result=to_string(a)+",";
if(b==-INFI)
result+="-Infinity";
else if(b==INFI)
result+="Infinity";
else
result+=to_string(b);
return result;
}