forked from jinjiebang/wine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.h
162 lines (147 loc) · 4.64 KB
/
Board.h
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
#ifndef _BOARD
#define _BOARD
typedef unsigned long long U64;
const int win = 7; // 连五
const int flex4 = 6; // 活四
const int block4 = 5; // 冲四
const int flex3 = 4; // 活三
const int block3 = 3; // 眠三
const int flex2 = 2; // 活二
const int block2 = 1; // 眠二
const int Ntype = 8; // 棋型个数
const int MaxSize = 20; // 棋盘最大尺寸
const int MaxMoves = 40; // 最大着法数
const int hashSize = 1 << 22; // 普通置换表尺寸
const int pvsSize = 1 << 20; // pvs置换表尺寸
const int MaxDepth = 20; // 最大搜索深度
// hash表相关
const int hash_exact = 0;
const int hash_alpha = 1;
const int hash_beta = 2;
const int unknown = -20000;
// 点的状态
const int Outside = 3;
const int Empty = 2;
const int Black = 1;
const int White = 0;
// 方向向量
const int dx[4] = { 1, 0, 1, 1 };
const int dy[4] = { 0, 1, 1, -1 };
// 坐标
struct Pos {
int x;
int y;
};
// 带评价的点
struct Point {
Pos p;
int val;
};
// 棋盘单点结构
struct Cell {
int piece;
int IsCand;
int pattern[2][4];
};
// 哈希表结构
struct Hashe {
U64 key;
int depth;
int hashf;
int val;
};
struct Pv {
U64 key;
Pos best;
};
// 走法路线
struct Line {
int n;
Pos moves[MaxDepth];
};
struct MoveList {
int phase,n,index;
bool first;
Pos hashMove;
Pos moves[64];
};
class Board {
public:
int step = 0; // 棋盘落子数
int size = 15; // 棋盘当前尺寸
int b_start, b_end; // 棋盘坐标索引
U64 zobristKey = 0; // 表示当前局面的zobristKey
U64 zobrist[2][MaxSize + 4][MaxSize + 4]; // zobrist键值表
Hashe hashTable[hashSize]; // 哈希表
Pv pvsTable[pvsSize]; // pvs置换表
int typeTable[10][6][6][3]; // 初级棋型表
int patternTable[65536][2]; // 完整棋型表
int pval[8][8][8][8]; // 棋形分值表
Cell cell[MaxSize + 8][MaxSize + 8]; // 棋盘
Pos remMove[MaxSize * MaxSize]; // 记录落子
Point cand[256]; // 临时存储合理着法(两格内有子)
bool IsLose[MaxSize + 4][MaxSize + 4]; // 记录根节点的必败点
int who = Black; // 下子方
int opp = White; // 另一方
Point rootMove[64]; // 根节点着法
int rootCount; // 根节点着法个数
int ply = 0; // 当前搜索的层数
Board();
~Board();
void InitType();
void InitPval();
void InitPattern();
void InitZobrist();
void SetSize(int _size);
void MakeMove(Pos next);
void DelMove();
void Undo();
void ReStart();
void UpdateType(int x, int y);
U64 Rand64();
int GetKey(int x, int y, int i);
int GetPval(int a, int b, int c, int d);
int LineType(int role, int key);
int ShortLine(int *line);
int CheckFlex3(int *line);
int CheckFlex4(int *line);
int GetType(int len, int len2, int count, int block);
Pos MoveNext(MoveList &MoveList);
/* 可内联成员函数 */
// 返回第step步棋的颜色,先手黑棋,后手白棋
int color(int step) {
return step & 1;
}
// 检查坐标x,y是否越界
bool CheckXy(int x, int y) {
return cell[x][y].piece != Outside;
}
// 返回最后一步棋的Cell指针
Cell * LastMove(){
return &cell[remMove[step - 1].x][remMove[step - 1].y];
}
// role:黑棋-1 白棋-0 type:统计棋形个数的数组 c:棋盘该位置的Cell指针
void TypeCount(Cell *c, int role, int *type) {
++type[c->pattern[role][0]];
++type[c->pattern[role][1]];
++type[c->pattern[role][2]];
++type[c->pattern[role][3]];
}
// role:黑棋-1 白棋-0 type:要判断的棋形 c:棋盘该位置的Cell指针
// 返回该位置4个方向是否存在棋形type
bool IsType(Cell *c, int role, int type) {
return c->pattern[role][0] == type
|| c->pattern[role][1] == type
|| c->pattern[role][2] == type
|| c->pattern[role][3] == type;
}
// 检查最后一步棋是否成连五
bool CheckWin() {
Cell *c = LastMove();
return c->pattern[opp][0] == win
|| c->pattern[opp][1] == win
|| c->pattern[opp][2] == win
|| c->pattern[opp][3] == win;
}
};
#endif