My Project
csaRecord.cc
Go to the documentation of this file.
1 #include "osl/record/csaRecord.h"
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 
70 CsaFile::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)
124  record.result = Record::Sennnichite;
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 
141 CsaFile::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 
153 CsaFile::CsaFile(std::istream& is)
154 {
155  read(is);
156 }
157 
160 {
161 }
162 
164 read(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:
osl::record::SearchInfo::value
int value
Definition: searchInfo.h:16
osl::NumEffectState::makeMove
void makeMove(Move move)
Definition: numEffectState.cc:201
osl::record::Record::WhiteWin
@ WhiteWin
Definition: record.h:20
osl::alt
constexpr Player alt(Player player)
Definition: basic_type.h:13
osl::OslConfig::inUnitTest
static int inUnitTest()
Definition: oslConfig.h:87
osl::record::CsaFile::makeInfo
static SearchInfo makeInfo(const SimpleState &initial, const std::string &line, Move last_move)
Definition: csaRecord.cc:18
osl::record::CsaFile::~CsaFile
~CsaFile()
Definition: csaRecord.cc:159
osl::Move
圧縮していない moveの表現 .
Definition: basic_type.h:1052
osl::record::CsaFile::read
void read(std::istream &)
Definition: csaRecord.cc:164
osl::SimpleState
Definition: simpleState.h:35
osl::Move::INVALID
static const Move INVALID()
Definition: basic_type.h:1095
osl::csa::show
const std::string show(Move)
Definition: csa.cc:133
osl::record::Record::Sennnichite
@ Sennnichite
Definition: record.h:21
osl::record::Record::setMoveComment
void setMoveComment(const std::string &)
Definition: record.cc:17
osl::record::Record::BlackWin
@ BlackWin
Definition: record.h:19
osl::NumEffectState::inCheck
bool inCheck(Player P) const
Pの玉が王手状態
Definition: numEffectState.h:88
osl::usi::show
const std::string show(Move)
Definition: usi.cc:146
osl::usi::ParseError
Definition: usi.h:24
osl::record::Record::version
std::string version
Definition: record.h:28
osl::record::Record::initial_comment
std::string initial_comment
Definition: record.h:28
csaRecord.h
osl::CArray::end
iterator end()
Definition: container.h:65
osl::csa::strToMove
const Move strToMove(const std::string &s, const SimpleState &st)
Definition: csa.cc:48
oslConfig.h
osl::Move::isNormal
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
osl::record::Record::JiShogi
@ JiShogi
Definition: record.h:22
osl::record::SearchInfo::moves
std::vector< Move > moves
Definition: searchInfo.h:17
usi.h
osl::csa::CsaIOError
Definition: csa.h:18
osl::NumEffectState
利きを持つ局面
Definition: numEffectState.h:34
osl::csa::CsaFileMinimal::parseLine
static bool parseLine(SimpleState &, RecordMinimal &, std::string element, CArray< bool, 9 > &)
Definition: csa.cc:247
osl::SimpleState::isValidMove
bool isValidMove(Move move, bool show_error=true) const
合法手かどうかを検査する. isValidMoveByRule, isAlmostValidMove をおこなう. 玉の素抜きや王手を防いでいるか, 千日手,打歩詰かどうかは検査しない.
Definition: simpleState.cc:435
osl::record::Record::result
ResultType result
Definition: record.h:30
osl::record::Record::lastMove
Move lastMove() const
Definition: record.h:47
osl::record::Record::setMoveInfo
void setMoveInfo(const SearchInfo &)
Definition: record.cc:26
osl::record::CsaFile::CsaFile
CsaFile(std::istream &is)
Definition: csaRecord.cc:153
osl::csa::charToPlayer
Player charToPlayer(char c)
Definition: csa.cc:18
osl::CArray::begin
iterator begin()
Definition: container.h:64
osl::Move::PASS
static const Move PASS(Player P)
Definition: basic_type.h:1094
osl::usi::strToMove
const Move strToMove(const std::string &, const NumEffectState &)
Definition: usi.cc:226
osl::Move::isPass
bool isPass() const
Definition: basic_type.h:1092
osl::BLACK
@ BLACK
Definition: basic_type.h:9
osl::record::Record::player
CArray< std::string, 2 > player
Definition: record.h:29
osl::SimpleState::turn
Player turn() const
Definition: simpleState.h:220
osl::record::Record::addWithNewLine
static void addWithNewLine(std::string &a, const std::string &b)
Definition: record.h:35
simpleState.h
osl::SimpleState::init
void init()
盤面が空の状態に初期化
Definition: simpleState.cc:44
osl::CArray
Definition: container.h:20
osl::record::SearchInfo
Definition: searchInfo.h:15
osl::record::CsaFile::parseLine
static void parseLine(SimpleState &, Record &, std::string element, bool parse_move_comment=true)
Definition: csaRecord.cc:70
osl::record::Record::setMoveTime
void setMoveTime(int)
Definition: record.cc:33
osl::record::Record
Definition: record.h:15
osl::record::Record::setDate
void setDate(const std::string &date_str)
Definition: record.cc:39