My Project
csaRecord.cc
Go to the documentation of this file.
2#include "osl/simpleState.h"
3#include "osl/oslConfig.h"
4#include "osl/usi.h"
5#include <boost/algorithm/string/classification.hpp>
6#include <boost/algorithm/string/split.hpp>
7#include <boost/algorithm/string/trim.hpp>
8#include <iostream>
9#include <fstream>
10#include <stdexcept>
11#include <cassert>
12#include <string>
13#include <sstream>
14
15/* ------------------------------------------------------------------------- */
16
19 const std::string& line,
20 Move last_move)
21{
22 std::istringstream is(line);
23 SearchInfo info;
24 is >> info.value;
25
26 NumEffectState state(initial);
27 std::string s;
28 while (is >> s)
29 {
30 if (s == csa::show(last_move) ||
31 s == usi::show(last_move)) // effective only if s is the first move in a comment
32 continue;
33 last_move = Move::INVALID();
34 try
35 {
36 Move move;
37 if (s == "%PASS" || /* gekisashi */ s == "<PASS>" || s == "PASS") {
38 move = Move::PASS(state.turn());
39 } else if (s[0] == '+' || s[0] == '-') {
40 move = csa::strToMove(s, state);
41 } else {
42 move = usi::strToMove(s, state);
43 }
44 if (move.isPass()
45 || (move.isNormal() && state.isValidMove(move,false)))
46 {
47 state.makeMove(move);
48 if (! state.inCheck(alt(state.turn()))) {
49 info.moves.push_back(move);
50 continue;
51 }
52 // fall through
53 }
54 }
55 catch(CsaIOError& e)
56 {
57 // fall through
58 }
59 catch(usi::ParseError &e)
60 {
61 // fall through
62 }
63 std::cerr << "drop illegal move in comment " << s << std::endl;
64 break;
65 }
66 return info;
67}
68
70CsaFile::parseLine(SimpleState& state, Record& record, std::string s,
71 bool parse_move_comment)
72{
73 switch(s.at(0)){
74 case '\'': /* コメント行 */
75 if (s.substr(1,2) == "* ")
76 {
77 record.setMoveComment(s.substr(3));
78 }
79 else if (s.substr(1,2) == "**" && parse_move_comment)
80 {
81 record.setMoveInfo(makeInfo(state, s.substr(3), record.lastMove()));
82 }
83 return;
84 case '$': /* コメント行 */
85 if (s.find("$START_TIME:") == 0) {
86 const std::string YYMMDD = s.substr(12,10);
87#if 0
88 std::vector<std::string> e;
89 boost::algorithm::split(e, YYMMDD, boost::algorithm::is_any_of("/"));
90 if (e.size() < 3)
91 throw CsaIOError("csa date fail "+YYMMDD);
92 start_date = boost::gregorian::date(stoi(e[0]), stoi(e[1]), stoi(e[2]));
93 assert(!start_date.is_special());
94#endif
95 record.setDate(YYMMDD);
96 return;
97 }
98 Record::addWithNewLine(record.initial_comment, s.substr(1));
99 return;
100 case 'V': /* バージョン番号 */
101 record.version = s.substr(1);
102 return;
103 case 'N': /* 対局者名 */
104 switch(s.at(1)){
105 case '+':
106 case '-':
107 record.player[csa::charToPlayer(s.at(1))] = s.substr(2);
108 break;
109 default:
110 std::cerr << "Illegal csa line " << s << std::endl;
111 throw CsaIOError("illegal csa line "+s);
112 }
113 break;
114 case 'T':
115 {
116 record.setMoveTime(atoi(s.c_str()+1));
117 return;
118 }
119 case '%':
120 if (s.find("%TORYO") == 0 || s.find("%ILLEGAL_MOVE") == 0)
121 record.result = ((state.turn() == BLACK)
123 else if (s.find("%SENNICHITE") == 0)
125 else if (s.find("%KACHI") == 0)
126 record.result = ((state.turn() == BLACK)
128 else if (s.find("%JISHOGI") == 0 || s.find("%HIKIWAKE") == 0)
129 record.result = Record::JiShogi;
130 else if (s.find("%+ILLEGAL_ACTION") == 0)
131 record.result = Record::WhiteWin;
132 else if (s.find("%-ILLEGAL_ACTION") == 0)
133 record.result = Record::BlackWin;
134 return;
135 default:
136 throw CsaIOError("unknown character in csaParseLine "+s);
137 }
138}
139
141CsaFile::CsaFile(const std::string& filename)
142{
143 std::ifstream ifs(filename);
144 if (! ifs) {
145 const std::string msg = "CsaFile::CsaFile file cannot read ";
146 std::cerr << msg << filename << "\n";
147 throw CsaIOError(msg + filename);
148 }
149 read(ifs);
150}
151
153CsaFile::CsaFile(std::istream& is)
154{
155 read(is);
156}
157
160{
161}
162
164read(std::istream& is)
165{
166 SimpleState work;
167 work.init();
168 std::string line;
169 CArray<bool, 9> board_parsed = {{ false }};
170 while (std::getline(is, line))
171 {
172 // quick hack for \r
173 if ((! line.empty())
174 && (line[line.size()-1] == 13))
175 line.erase(line.size()-1);
176
177 std::vector<std::string> elements;
178 boost::algorithm::split(elements, line, boost::algorithm::is_any_of(","));
179 for (auto& e: elements) {
180 boost::algorithm::trim(e);
181 boost::algorithm::trim_left(e);
182 if (! CsaFileMinimal::parseLine(work, record.record, e, board_parsed))
183 parseLine(work, record, e, !OslConfig::inUnitTest());
184 }
185 }
186 if (*std::min_element(board_parsed.begin(), board_parsed.end()) == false)
187 throw CsaIOError("incomplete position description in csaParseLine");
188 assert(record.record.initial_state.isConsistent());
189}
190
191/* ------------------------------------------------------------------------- */
192// ;;; Local Variables:
193// ;;; mode:c++
194// ;;; c-basic-offset:2
195// ;;; End:
iterator end()
Definition: container.h:65
iterator begin()
Definition: container.h:64
圧縮していない moveの表現 .
Definition: basic_type.h:1052
static const Move PASS(Player P)
Definition: basic_type.h:1094
static const Move INVALID()
Definition: basic_type.h:1095
bool isPass() const
Definition: basic_type.h:1092
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
利きを持つ局面
void makeMove(Move move)
bool inCheck(Player P) const
Pの玉が王手状態
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いでいるか, 千日手,打歩詰かどうかは検査しない.
Definition: simpleState.cc:435
void init()
盤面が空の状態に初期化
Definition: simpleState.cc:44
Player turn() const
Definition: simpleState.h:220
static bool parseLine(SimpleState &, RecordMinimal &, std::string element, CArray< bool, 9 > &)
Definition: csa.cc:247
CsaFile(std::istream &is)
Definition: csaRecord.cc:153
void read(std::istream &)
Definition: csaRecord.cc:164
static void parseLine(SimpleState &, Record &, std::string element, bool parse_move_comment=true)
Definition: csaRecord.cc:70
static SearchInfo makeInfo(const SimpleState &initial, const std::string &line, Move last_move)
Definition: csaRecord.cc:18
const std::string show(Move)
Definition: csa.cc:133
Player charToPlayer(char c)
Definition: csa.cc:18
const Move strToMove(const std::string &s, const SimpleState &st)
Definition: csa.cc:48
const Move strToMove(const std::string &, const NumEffectState &)
Definition: usi.cc:226
const std::string show(Move)
Definition: usi.cc:146
@ BLACK
Definition: basic_type.h:9
constexpr Player alt(Player player)
Definition: basic_type.h:13
static int inUnitTest()
Definition: oslConfig.h:87
ResultType result
Definition: record.h:30
std::string version
Definition: record.h:28
static void addWithNewLine(std::string &a, const std::string &b)
Definition: record.h:35
Move lastMove() const
Definition: record.h:47
std::string initial_comment
Definition: record.h:28
void setMoveInfo(const SearchInfo &)
Definition: record.cc:26
void setMoveTime(int)
Definition: record.cc:33
void setDate(const std::string &date_str)
Definition: record.cc:39
void setMoveComment(const std::string &)
Definition: record.cc:17
CArray< std::string, 2 > player
Definition: record.h:29
std::vector< Move > moves
Definition: searchInfo.h:17