-
Notifications
You must be signed in to change notification settings - Fork 1
/
move.cpp
74 lines (59 loc) · 1.92 KB
/
move.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
#include "move.h"
#include <iostream>
#include <thread>
#include <vector>
#include <atomic>
#define max(a, b) ((a) > (b) ? (a) : (b))
namespace move {
int bestMove(grid& g, int depth) {
std::vector<std::thread> threads;
int64_t scores[16];
for (int i = 0; i < 16; i++) scores[i] = -1;
for (int first : DIRECTIONS) {
for (int second : DIRECTIONS) {
threads.emplace_back([&](int dir) {
grid g1(g);
if (g1.move(dir / 4)) {
grid g2(g1);
if (g2.move(dir % 4)) {
int64_t score = -1;
bestScore(g2, depth - 2, score);
scores[dir] = score;
} else {
int64_t score = evaluate(g1) >> depth;
scores[dir] = score;
}
}
}, first * 4 + second);
}
}
for (auto& thread : threads) {
thread.join();
}
int bestDir = -1;
int64_t _bestScore = -1;
for (int i = 0; i < 16; i++) {
int64_t score = scores[i];
if (score > _bestScore) {
_bestScore = score;
bestDir = i / 4;
}
}
return bestDir;
}
inline int64_t evaluate(grid& g) { return (g.getEmpty() << 16) + g.getScore(); }
namespace {
void bestScore(grid& g, int depth, int64_t& currentBestScore) {
int64_t score = evaluate(g) >> depth;
currentBestScore = max(currentBestScore, score);
if (depth == 0)
return;
for (int dir : DIRECTIONS) {
grid g1(g);
if (g1.move(dir)) {
bestScore(g1, depth - 1, currentBestScore);
}
}
}
}
}