forked from chaozc/AI-Project-Computer-Go
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathUctSearch.cpp
More file actions
124 lines (109 loc) · 2.92 KB
/
Copy pathUctSearch.cpp
File metadata and controls
124 lines (109 loc) · 2.92 KB
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
#include "UctSearch.h"
#include <ctime>
#include <iostream>
#include <cmath>
void UctGameInfo::destroy() {
for (UctGameInfo* next = child; next != NULL;) {
next->destroy();
UctGameInfo* tmp = next->sibling;
delete next;
next = tmp;
}
}
UctSearch::UctSearch()
{
}
UctSearch::UctSearch(const GoBoard& board, int color)
{
initialBoard = board;
initialColor = color;
root = new UctGameInfo(-1);
}
UctSearch::~UctSearch()
{
root->destroy();
delete root;
}
UctGameInfo* UctSearch::decendByUCB1(UctGameInfo* current, GoBoard& board, int& color) {
UctGameInfo* res = NULL;
double best = -1000000;
for (UctGameInfo* next = current->child; next != NULL; next = next->sibling) {
double v = 100000 + rand();
if (next->visits > 0) {
v = 1.0 * next->wins / next->visits + 5 * sqrt(log(current->visits) / next->visits);
}
if (v > best) {
best = v;
res = next;
}
}
if (best >= 0) board.play_move(res->move, color);
color = GoBoard::other_color(color);
return res;
}
void UctSearch::creatChildren(UctGameInfo* current, GoBoard& board, const int& color) {
static bool next[169];
// board.generate_all_moves(color, next);
UctGameInfo* from = current;
for (int i = 0; i < 169; ++i){
if (next[i]) {
if (from == current) {
from->child = new UctGameInfo(i);
from = from->child;
}
else {
from->sibling = new UctGameInfo(i);
from = from->sibling;
}
}
}
}
void UctSearch::playOneSquence() {
GoBoard board = initialBoard;
int color = initialColor;
UctGameInfo* sequence[400];
sequence[0] = root;
int tail = 0;
while (sequence[tail] != NULL && sequence[tail]->visits > 0 && tail < 300) {
sequence[tail + 1] = decendByUCB1(sequence[tail], board, color);
++tail;
}
if (tail >= 300) return;
if (sequence[tail] == NULL) return;
creatChildren(sequence[tail], board, color);
int result = board.simulateRandomly(color)> 0 ? 1 : 0;
if (result > 1) result = 1;
if (result < 0) result = 0;
for (int i = tail; i >= 0; --i) {
sequence[i]->update(result);
result = 1 - result;
}
}
int UctSearch::selectBySearch(int timeLimit) {
int st = clock();
while (clock() - st < timeLimit * CLOCKS_PER_SEC) {
playOneSquence();
}
srand((unsigned int)time(0));
int res = -14;
double maxV = 1000000000;
int cnt = 0;
for (UctGameInfo* next = root->child; next != NULL; next = next->sibling) {
cnt += next->visits;
//printf("%d\n", next->visits);
double tmp = 1.0 * next->wins / next->visits;
if (tmp < maxV) {
maxV = tmp;
res = next->move;
}
}
if (maxV < 10) {
std::cerr << maxV << std::endl;
GoBoard test = initialBoard;
test.play_move(res, initialColor);
std::cerr << test.simulateRandomly(GoBoard::other_color(initialColor)) << std::endl;
//std::cerr << initialBoard.simulateRandomly(res) << std::endl;
}
printf("%d %d %d\n", cnt, res, maxV);
return res;
}