-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDecisionTree.cpp
178 lines (160 loc) · 5.28 KB
/
DecisionTree.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
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
#include <assert.h>
#include "DecisionTree.h"
RESULT DecisionTree::check_node(state a[M][N], state player_this, int i_this, int j_this) const
{
//------------------------------------------------
// find dead stones
//------------------------------------------------
bool marker_dead_this[M][N];
bool marker_dead_that[M][N];
bool exist_dead_this = theCapture. find_xblock_captured(a, i_this, j_this, player_this, marker_dead_this);
bool exist_dead_that = theCapture.find_yblocks_captured(a, i_this, j_this, player_this, marker_dead_that);
if (exist_dead_this == true &&
exist_dead_that == false)
return LAW_VIOLATED;
//------------------------------------------------
// remove dead stones
//------------------------------------------------
if (exist_dead_that)
{
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
if (marker_dead_that[i][j])
a[i][j] = EMPTY;
if (exist_dead_this)
exist_dead_this = false;
}
if (exist_dead_that && marker_dead_that[iObj][jObj]) return THAT_DEAD;
if (exist_dead_this && marker_dead_this[iObj][jObj]) return THIS_DEAD;
//------------------------------------------------
// find unconditionally alive stones
//------------------------------------------------
bool marker_alive_this[M][N];
int exist_alive_this = theBension.find_unconditionally_alive_blocks(a, player_this, marker_alive_this);
if (exist_alive_this>0 && marker_alive_this[iObj][jObj])
return THIS_ALIVE;
//------------------------------------------------
// neither dead nor alive
//------------------------------------------------
return INCONCLUSIVE;
}
RESULT DecisionTree::check_node_recursive(state a[M][N], state player_this, int i_this, int j_this) const
{
//------------------------------------------------------------
// 현상태에서 판단완료
//------------------------------------------------------------
RESULT result = check_node(a, player_this, i_this, j_this);
if (result != INCONCLUSIVE) return result;
//------------------------------------------------------------
// 상대편 입장에서 생각함
//------------------------------------------------------------
else
{
state player_that = (player_this == BLACK) ? WHITE : BLACK;
RESULT result_best_for_that = LAW_VIOLATED;
for(int i=imin_BG;i<=imax_BG;i++)
for(int j=jmin_BG;j<=jmax_BG;j++)
{
if (a[i][j] == EMPTY)
{
state a_next[M][N]; copy(a, a_next);
a_next[i][j] = player_that;
RESULT result_that = check_node_recursive(a_next, player_that, i, j);
//------------------------------------------------------------
// 상대편 입장에서 최상의 결과
//------------------------------------------------------------
if (result_that == THIS_ALIVE||
result_that == THAT_DEAD )
return reverse_result(result_that);
//------------------------------------------------------------
// 상대편 입장에서 그나마 제일 나은 것을 선택
//------------------------------------------------------------
else
{
if (value(result_that) > value(result_best_for_that))
result_best_for_that = result_that;
}
}
}
return reverse_result(result_best_for_that);
}
}
RESULT DecisionTree::reverse_result(RESULT result) const
{
switch(result)
{
case THIS_ALIVE: return THAT_ALIVE;
case THAT_ALIVE: return THIS_ALIVE;
case THIS_DEAD : return THAT_DEAD ;
case THAT_DEAD : return THIS_DEAD ;
default:
return result;
};
}
void DecisionTree::copy(const state a[M][N], state a_copy[M][N]) const
{
for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
a_copy[i][j] = a[i][j];
}
int DecisionTree::value(RESULT res) const
{
switch (res)
{
case THIS_ALIVE : return 3;
case THAT_DEAD : return 3;
case INCONCLUSIVE: return 2;
case THIS_DEAD :return 1;
case THAT_ALIVE :return 1;
case LAW_VIOLATED:return 0;
default:return 0;
}
}
RESULT DecisionTree::find_best_move(state a[M][N], state player_this, int iObj, int jObj,
int imin_BG, int imax_BG, int jmin_BG, int jmax_BG, int& i_this, int& j_this)
{
Benson::print_state(a);
this->iObj = iObj;
this->jObj = jObj;
this->imin_BG = imin_BG;
this->imax_BG = imax_BG;
this->jmin_BG = jmin_BG;
this->jmax_BG = jmax_BG;
//------------------------------------------------------------
// 현재 상태에서 다음 수를 생각함
//------------------------------------------------------------
RESULT result_best = LAW_VIOLATED;
for (int i = imin_BG; i <= imax_BG; i++)
for (int j = jmin_BG; j <= jmax_BG; j++)
{
if (a[i][j] == EMPTY)
{
state a_next[M][N]; copy(a, a_next);
a_next[i][j] = player_this;
RESULT result = check_node_recursive(a_next, player_this, i, j);
//------------------------------------------------------------
// 최상의 결과
//------------------------------------------------------------
if (result == THIS_ALIVE ||
result == THAT_DEAD)
{
i_this = i;
j_this = j;
return result;
}
//------------------------------------------------------------
// 최상이 아니면 그나마 제일 나은 것을 선택
//------------------------------------------------------------
else
{
if (value(result) > value(result_best))
{
i_this = i;
j_this = j;
result_best = result;
}
}
}
}
return result_best;
}