-
Notifications
You must be signed in to change notification settings - Fork 2
/
solverpns_tt.h
131 lines (101 loc) · 3.05 KB
/
solverpns_tt.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
#pragma once
//A single-threaded, transposition table based, proof number search solver.
#include "solver.h"
#include "zobrist.h"
class SolverPNSTT : public Solver {
static const uint32_t LOSS = (1<<30)-1;
static const uint32_t DRAW = (1<<30)-2;
static const uint32_t INF32 = (1<<30)-3;
public:
struct PNSNode {
hash_t hash;
uint32_t phi, delta;
PNSNode() : hash(0), phi(0), delta(0) { }
PNSNode(hash_t h, int v = 1) : hash(h), phi(v), delta(v) { }
PNSNode(hash_t h, int p, int d) : hash(h), phi(p), delta(d) { }
PNSNode & abval(int outcome, int toplay, int assign, int value = 1){
if(assign && (outcome == 1 || outcome == -1))
outcome = (toplay == assign ? 2 : -2);
if( outcome == 0) { phi = value; delta = value; } //unknown
else if(outcome == 2) { phi = LOSS; delta = 0; } //win
else if(outcome == -2) { phi = 0; delta = LOSS; } //loss
else /*(outcome 1||-1)*/ { phi = 0; delta = DRAW; } //draw
return *this;
}
PNSNode & outcome(int outcome, int toplay, int assign, int value = 1){
if(assign && outcome == 0)
outcome = assign;
if( outcome == -3) { phi = value; delta = value; }
else if(outcome == toplay) { phi = LOSS; delta = 0; }
else if(outcome == 3-toplay) { phi = 0; delta = LOSS; }
else /*(outcome == 0)*/ { phi = 0; delta = DRAW; }
return *this;
}
bool terminal(){ return (phi == 0 || delta == 0); }
};
PNSNode root;
PNSNode * TT;
uint64_t maxnodes, memlimit;
int ab; // how deep of an alpha-beta search to run at each leaf node
bool df; // go depth first?
float epsilon; //if depth first, how wide should the threshold be?
int ties; //which player to assign ties to: 0 handle ties, 1 assign p1, 2 assign p2
int copyproof; //how many siblings to try to copy a proof to
SolverPNSTT() {
ab = 2;
df = true;
epsilon = 0.25;
ties = 0;
copyproof = 0;
TT = NULL;
reset();
set_memlimit(100*1024*1024);
}
~SolverPNSTT(){
if(TT){
delete[] TT;
TT = NULL;
}
}
void reset(){
outcome = -3;
maxdepth = 0;
nodes_seen = 0;
time_used = 0;
bestmove = Move(M_UNKNOWN);
timeout = false;
root = PNSNode(rootboard.gethash(), 1);
}
void set_board(const Board & board, bool clear = true){
rootboard = board;
rootboard.setswap(false);
reset();
if(clear)
clear_mem();
}
void move(const Move & m){
rootboard.move(m, true, true);
reset();
}
void set_memlimit(uint64_t lim){
memlimit = lim;
maxnodes = memlimit/sizeof(PNSNode);
clear_mem();
}
void clear_mem(){
reset();
if(TT){
delete[] TT;
TT = NULL;
}
}
void solve(double time);
//basic proof number search building a tree
void run_pns();
void pns(const Board & board, PNSNode * node, int depth, uint32_t tp, uint32_t td);
void copy_proof(const Board & source, const Board & dest, Move smove, Move dmove);
//update the phi and delta for the node
bool updatePDnum(const Board & board, PNSNode * node = NULL);
PNSNode * tt(const Board & board);
PNSNode * tt(const Board & board, Move move);
};