-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpgn.h
150 lines (110 loc) · 3.66 KB
/
pgn.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
#ifndef PGN_H
#define PGN_H
#include <fstream>
#include <algorithm>
#include <sstream>
#include <string>
#include <iostream>
#include <cmath>
#include "move.h"
#include "position.h"
#include "types.h"
#include "utils.h"
#include "uci.h"
enum Result { pgn_draw, pgn_wwin, pgn_bwin, pgn_none };
//const std::string START_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
struct game {
Result result;
unsigned white_elo, black_elo;
std::vector<Move> moves;
game() { clear(); }
bool finished() { return result != Result::pgn_none; }
void clear() { moves.clear(); result = Result::pgn_none; white_elo = 0; black_elo = 0; }
inline unsigned rating_diff() const { return fabs(white_elo - black_elo); }
};
class pgn {
private:
std::vector<game> games;
std::vector<std::string> pgn_files;
bool parse_files();
bool parse_moves(position& p, const std::string& line, game& g);
inline bool is_header(const std::string& line);
inline bool is_elo(const std::string& line);
inline bool is_empty(const std::string& line);
inline void parse_elo(game& g, const std::string& line);
inline void strip(std::string& token);
inline Square get_square(const std::string& s, int start);
template<Piece piece>
bool find_move(position& p, const Square& to, Move& m, int row = -1, int col = -1);
public:
pgn() {}
pgn(const std::vector<std::string>& files);
~pgn() { }
pgn(const pgn& o) = delete;
pgn(const pgn&& o) = delete;
pgn& operator=(const pgn& o) = delete;
pgn& operator=(const pgn&& o) = delete;
std::vector<game>& parsed_games() { return games; }
bool move_from_san(position& p, std::string& s, Move& m);
};
inline bool pgn::is_elo(const std::string& line) {
return (line.find("[WhiteElo") != std::string::npos ||
line.find("[BlackElo") != std::string::npos);
}
inline void pgn::parse_elo(game& g, const std::string& line) {
// assume this is a valid elo-tag from a pgn file (!!)
bool white = line.find("[WhiteElo") != std::string::npos;
std::string segment;
std::stringstream tmp(line);
std::getline(tmp, segment, ' ');
std::getline(tmp, segment, ' ');
strip(segment);
if (white) { g.white_elo = std::stoi(segment); }
else { g.black_elo = std::stoi(segment); }
}
inline bool pgn::is_header(const std::string& line) {
return (line.find("[") != std::string::npos ||
line.find("]") != std::string::npos);
}
inline bool pgn::is_empty(const std::string& line) {
return (line.size() <= 0 || line == "\n");
}
inline void pgn::strip(std::string& token) {
std::string skip = "!?+#[]\"{}";
std::string result = "";
for (const auto& c : token) {
if (skip.find(c) != std::string::npos) { continue; }
else result += c;
}
token = result;
}
template<Piece piece>
bool pgn::find_move(position& p, const Square& to, Move& m, int row, int col) {
Movegen mvs(p);
mvs.generate<piece>();
bool promotion = (m.type != Movetype::no_type);
for (int j = 0; j < mvs.size(); ++j) {
if (!p.is_legal(mvs[j])) continue;
if (promotion && m.type == mvs[j].type && mvs[j].t == to) {
if (row >= 0 && row == util::row(mvs[j].f)) { m = mvs[j]; return true; }
if (col >= 0 && col == util::col(mvs[j].f)) { m = mvs[j]; return true; }
if (col < 0 && row < 0) { m = mvs[j]; return true; }
}
else if (!promotion && mvs[j].t == to) {
if (row >= 0 && row == util::row(mvs[j].f)) { m = mvs[j]; return true; }
if (col >= 0 && col == util::col(mvs[j].f)) { m = mvs[j]; return true; }
if (col < 0 && row < 0) { m = mvs[j]; return true; }
}
}
return false;
}
inline Square pgn::get_square(const std::string& s, int start) {
std::string str = s.substr(start - 1, 2);
int i = 0;
for (const auto& sq : SanSquares) {
if (sq == str) break;
++i;
}
return Square(i);
}
#endif