My Project
ki2.cc
Go to the documentation of this file.
1 #include "osl/record/ki2.h"
2 #include "osl/record/kanjiCode.h"
5 #include "osl/misc/sjis2euc.h"
6 #include "osl/bits/ptypeTable.h"
7 #include <boost/algorithm/string/trim.hpp>
8 #include <fstream>
9 #include <iostream>
10 
13  std::string line)
14 {
15  boost::algorithm::trim(line);
16 
17  if (line.empty() || line.at(0) == '*')
18  return OK;
19  else if (line.size() > 10 && line.substr(0,10) == (K_KAISHI K_NICHIJI K_COLON))
20  {
21  std::string date_str(line.substr(10)); // this may or may not include HH:MM
23  const static std::string spaces[] = {" ", K_SPACE};
24  for (const auto& space: spaces) {
25  const std::string::size_type pos_space = date_str.find(space);
26  if (pos_space != std::string::npos)
27  date_str = date_str.substr(0, pos_space);
28  }
29  record.setDate(date_str);
30  // an invalid date_str results in an invalid boost::gregorian::date value
31  // you can check it date.is_special()
32  return OK;
33  }
34  else if (line.size() > 6 && line.substr(0,6) == (K_BLACK K_COLON))
35  {
36  const std::string player_name(line.substr(6));
37  record.player[BLACK] = player_name;
38  return OK;
39  }
40  else if (line.size() > 6 && line.substr(0,6) == (K_WHITE K_COLON))
41  {
42  const std::string player_name(line.substr(6));
43  record.player[WHITE] = player_name;
44  return OK;
45  }
46  else if (line.size() > 6 && line.substr(0,6) == (K_KISEN K_COLON))
47  {
48  record.tournament_name = line.substr(6);
49  return OK;
50  }
51  else if (line.size() > 8 && line.substr(0,8) == (K_TEAIWARI K_COLON))
52  return Komaochi;
53  else if (line.substr(0,2) != K_BLACK_SIGN && line.substr(0,2) != K_WHITE_SIGN)
54  return OK;
55 
56  std::string move_str;
57  for (size_t i = 0; ; ) {
58  if (i < line.size() &&
59  (line.at(i) == ' ' || line.at(i) == '\t'))
60  {
61  ++i;
62  continue;
63  }
64 
65  if ( (line.substr(i,2) == K_BLACK_SIGN ||
66  line.substr(i,2) == K_WHITE_SIGN ||
67  i+1 >= line.size())
68  && !move_str.empty())
69  {
70  // apply move_str
71  Move last_move;
72  if (record.moves().size() > 0)
73  last_move = record.moves().back();
74  const Move move = kmove.strToMove(move_str, state, last_move);
75  if (!move.isValid()) {
76  if (move_str.find(K_RESIGN) != move_str.npos)
77  return OK;
78  return Illegal;
79  }
80  record.record.moves.push_back(move);
81  state.makeMove(move);
82  move_str.clear();
83  }
84  if (i+1 >= line.size())
85  return OK;
86  move_str.append(line.substr(i,2));
87  i += 2;
88  } // for
89 }
90 
92 Ki2File::Ki2File(const std::string& filename, bool v)
93  : verbose(v)
94 {
95  std::ifstream is(filename);
96  if (! is)
97  {
98  const std::string msg = "Ki2File::Ki2File file cannot read ";
99  std::cerr << msg << filename << "\n";
100  throw Ki2IOError(msg + filename);
101  }
102  KanjiMove kmove;
103  kmove.setVerbose(verbose);
104 
105  NumEffectState work;
106  record.record.initial_state = work;
107  std::string line;
108  while (std::getline(is, line))
109  {
110  line = misc::sjis2euc(line);
111  const ParseResult result = parseLine(work, record, kmove, line);
112  switch (result)
113  {
114  case OK:
115  continue;
116  case Komaochi:
117  {
118  const std::string msg = "ERROR: Komaochi (handicapped game) records are not available: ";
119  std::cerr << msg << "\n";
120  throw Ki2IOError(msg);
121  }
122  case Illegal:
123  {
124  const std::string msg = "ERROR: An illegal move found in a record.";
125  throw Ki2IOError(msg);
126  }
127  default:
128  assert(false);
129  }
130  }
131 }
132 
133 const std::string osl::ki2::show(Square position)
134 {
135  using namespace record;
136  if (position.isPieceStand())
137  return "";
138  const int x = position.x(), y = position.y();
139  return StandardCharacters::suji[x] + StandardCharacters::dan[y];
140 }
141 
142 const std::string osl::ki2::show(Ptype ptype)
143 {
144  using namespace record;
145  switch (ptype)
146  {
147  case PSILVER: case PKNIGHT: case PLANCE:
148  return K_NARU + StandardCharacters().kanji(unpromote(ptype));
149  default:
150  ;
151  }
152  return StandardCharacters().kanji(ptype);
153 }
154 
155 const std::string osl::ki2::showPromote(bool promote)
156 {
157  return promote ? K_NARU : K_FUNARI;
158 }
159 
160 const std::string osl::ki2::show(Square cur, Square prev)
161 {
162  if (cur == prev)
163  return K_ONAZI;
164  return show(cur);
165 }
166 
167 const std::string osl::ki2::show(Move m, const NumEffectState& state,
168  Move prev)
169 {
170  std::string ret = (m.player() == BLACK) ? K_BLACK_SIGN : K_WHITE_SIGN;
171  if (m.isPass()) {
172  ret += K_PASS;
173  return ret;
174  }
175  const Square from = m.from(), to = m.to();
176  const Ptype ptype = m.oldPtype();
177  const Player player = m.player();
178  mask_t pieces = state.allEffectAt(player, ptype, to);
179  const mask_t promoted = state.promotedPieces().getMask(Ptype_Table.getIndex(ptype));
180  if (isPromoted(ptype))
181  pieces &= promoted;
182  else
183  pieces &= ~promoted;
184  if (from.isPieceStand()) {
185  ret += show(to) + show(ptype);
186  int has_effect = 0;
187  while (pieces.any()) {
188  const Piece p = state.pieceOf(pieces.takeOneBit());
189  if (p.ptype() == ptype)
190  ++has_effect;
191  }
192  if (has_effect)
193  ret += K_UTSU;
194  return ret;
195  }
196  ret += prev.isNormal() && (to == prev.to())
197  ? K_ONAZI : show(to);
198  ret += show(m.oldPtype());
199  const int count = pieces.countBit();
200  if (count >= 2) {
201  CArray<int,3> x_count = {{ 0 }}, y_count = {{ 0 }};
202  int my_x = 0, my_y = 0;
203  while (pieces.any()) {
204  const int n = pieces.takeOneBit() + Ptype_Table.getIndex(ptype)*32;
205  const Piece p = state.pieceOf(n);
206  if (p.ptype() != ptype)
207  continue;
208  int index_x = 1, index_y = 1;
209  if (p.square().x() != to.x())
210  index_x = ((p.square().x() - to.x()) * sign(player) > 0)
211  ? 2 : 0;
212  if (p.square().y() != to.y())
213  index_y = ((p.square().y() - to.y()) * sign(player) > 0)
214  ? 2 : 0;
215  if (p.square() == from)
216  my_x = index_x, my_y = index_y;
217  x_count[index_x]++;
218  y_count[index_y]++;
219  }
220  if (y_count[my_y] == 1) {
221  if (from.y() == to.y())
222  ret += K_YORU;
223  else if ((to.y() - from.y())*sign(player) > 0)
224  ret += K_HIKU;
225  else
226  ret += K_UE;
227  }
228  else if (x_count[my_x] == 1) {
229  if (from.x() == to.x()) {
230  if (isPromoted(ptype) && isMajor(ptype)) {
231  const Piece l = state.pieceAt
232  (Square(from.x() - sign(player), from.y()));
233  if (l.isOnBoardByOwner(player) && l.ptype() == ptype)
234  ret += K_HIDARI;
235  else
236  ret += K_MIGI;
237  }
238  else
239  ret += K_SUGU;
240  }
241  else if ((to.x() - from.x())*sign(player) > 0)
242  ret += K_MIGI;
243  else
244  ret += K_HIDARI;
245  }
246  else if (from.x() == to.x()) {
247  if ((to.y() - from.y())*sign(player) > 0)
248  ret += K_HIKU;
249  else
250  ret += K_SUGU;
251  }
252  else {
253  if ((to.x() - from.x())*sign(player) > 0)
254  ret += K_MIGI;
255  else
256  ret += K_HIDARI;
257  if ((to.y() - from.y())*sign(player) > 0)
258  ret += K_HIKU;
259  else
260  ret += K_UE;
261  }
262  }
263  if (canPromote(m.oldPtype()))
264  if (m.isPromotion()
265  || to.canPromote(player) || from.canPromote(player)) {
266  ret += showPromote(m.isPromotion());
267  }
268  return ret;
269 }
270 
271 const std::string osl::
272 ki2::show(const Move *first, const Move *last,
273  const char *threatmate_first, const char *threatmate_last,
274  const NumEffectState& initial, Move prev)
275 {
276  if (first == last || first->isInvalid())
277  return "";
278  NumEffectState state(initial);
279  std::string ret = show(*first, state, prev);
280  if (threatmate_first != threatmate_last
281  && *threatmate_first++)
282  ret += "(" K_TSUMERO ")";
283  for (; first+1 != last; ++first) {
284  if (first->isInvalid())
285  break;
286  state.makeMove(*first);
287  ret += show(*(first+1), state, *first);
288  if (threatmate_first != threatmate_last
289  && *threatmate_first++)
290  ret += "(" K_TSUMERO ")";
291  }
292  return ret;
293 }
294 
295 const std::string osl::
296 ki2::show(const Move *first, const Move *last, const NumEffectState& initial, Move prev)
297 {
298  std::vector<char> threatmate(last-first, false);
299  return show(first, last, &*threatmate.begin(), &*threatmate.end(), initial, prev);
300 }
301 
302 // ;;; Local Variables:
303 // ;;; mode:c++
304 // ;;; c-basic-offset:2
305 // ;;; End:
osl::PieceMask::getMask
const mask_t getMask(int num) const
Definition: pieceMask.h:59
K_UTSU
#define K_UTSU
Definition: kanjiCode.h:56
osl::SimpleState::pieceAt
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
kanjiCode.h
osl::Square
Definition: basic_type.h:532
osl::NumEffectState::makeMove
void makeMove(Move move)
Definition: numEffectState.cc:201
osl::isMajor
bool isMajor(Ptype ptype)
Definition: basic_type.h:185
K_WHITE
#define K_WHITE
Definition: kanjiCode.h:93
osl::Move::isInvalid
bool isInvalid() const
state に apply 可能でない場合にtrue
Definition: basic_type.h:1202
K_MIGI
#define K_MIGI
Definition: kanjiCode.h:45
osl::record::Record::tournament_name
std::string tournament_name
Definition: record.h:28
osl::ki2::Ki2File::parseLine
static ParseResult parseLine(NumEffectState &, Record &, KanjiMove &, std::string element)
Definition: ki2.cc:12
K_PASS
#define K_PASS
Definition: kanjiCode.h:98
osl::WHITE
@ WHITE
Definition: basic_type.h:10
osl::ki2::Ki2File::ParseResult
ParseResult
Definition: ki2.h:28
ptypeTable.h
K_UE
#define K_UE
Definition: kanjiCode.h:47
osl::ki2::showPromote
const std::string showPromote(bool)
Definition: ki2.cc:155
K_COLON
#define K_COLON
Definition: kanjiCode.h:17
K_KAISHI
#define K_KAISHI
Definition: kanjiCode.h:106
osl::PLANCE
@ PLANCE
Definition: basic_type.h:88
osl::RecordMinimal::initial_state
NumEffectState initial_state
Definition: csa.h:44
osl::promote
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない.
Definition: basic_type.h:173
osl::ki2::Ki2File::verbose
bool verbose
Definition: ki2.h:24
osl::Move::isValid
bool isValid() const
Definition: basic_type.cc:246
osl::record::KanjiMove
Parse kanji records such as "7六歩", the style of which is generally used to write Shogi records in Jap...
Definition: kanjiMove.h:20
osl::PSILVER
@ PSILVER
Definition: basic_type.h:90
K_TEAIWARI
#define K_TEAIWARI
Definition: kanjiCode.h:97
osl::Move
圧縮していない moveの表現 .
Definition: basic_type.h:1052
osl::ki2::show
const std::string show(Square)
Definition: ki2.cc:133
osl::NumEffectState::allEffectAt
const mask_t allEffectAt(Player P, Square target) const
Definition: numEffectState.h:293
K_TSUMERO
#define K_TSUMERO
Definition: kanjiCode.h:105
osl::record::Record::record
RecordMinimal record
Definition: record.h:16
osl::misc::mask_t
GeneralMask< mask_int_t > mask_t
Definition: mask.h:351
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:84
K_RESIGN
#define K_RESIGN
Definition: kanjiCode.h:118
osl::RecordMinimal::moves
std::vector< Move > moves
Definition: csa.h:45
K_NICHIJI
#define K_NICHIJI
Definition: kanjiCode.h:107
osl::Ptype_Table
const PtypeTable Ptype_Table
Definition: tables.cc:97
ki2IOError.h
osl::Piece
駒.
Definition: basic_type.h:788
osl::SimpleState::pieceOf
const Piece pieceOf(int num) const
Definition: simpleState.h:76
osl::Move::oldPtype
Ptype oldPtype() const
移動前のPtype, i.e., 成る手だった場合成る前
Definition: basic_type.h:1174
osl::Square::isPieceStand
bool isPieceStand() const
Definition: basic_type.h:576
K_BLACK_SIGN
#define K_BLACK_SIGN
Define Kanji characters by using EUC-JP codes.
Definition: kanjiCode.h:13
osl::record::KanjiMove::setVerbose
void setVerbose(bool verbose)
Definition: kanjiMove.h:31
K_KISEN
#define K_KISEN
Definition: kanjiCode.h:103
osl::ki2::Ki2File::Komaochi
@ Komaochi
Definition: ki2.h:29
osl::PKNIGHT
@ PKNIGHT
Definition: basic_type.h:89
osl::PtypeTable::getIndex
int getIndex(Ptype) const
Definition: ptypeTable.h:50
osl::Piece::isOnBoardByOwner
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition: basic_type.h:852
K_SPACE
#define K_SPACE
Definition: kanjiCode.h:15
ki2.h
K_ONAZI
#define K_ONAZI
Definition: kanjiCode.h:53
osl::NumEffectState::promotedPieces
const PieceMask promotedPieces() const
Definition: numEffectState.h:64
osl::Move::isNormal
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
osl::Move::from
const Square from() const
Definition: basic_type.h:1125
osl::Square::x
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
K_FUNARI
#define K_FUNARI
Definition: kanjiCode.h:55
osl::ki2::Ki2File::OK
@ OK
Definition: ki2.h:29
osl::NumEffectState
利きを持つ局面
Definition: numEffectState.h:34
osl::record::RecordFile::record
Record record
Definition: record.h:66
K_NARU
#define K_NARU
Definition: kanjiCode.h:54
K_HIDARI
#define K_HIDARI
Definition: kanjiCode.h:46
osl::Square::canPromote
bool canPromote() const
Definition: basic_type.h:659
osl::Square::y
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
K_WHITE_SIGN
#define K_WHITE_SIGN
Definition: kanjiCode.h:14
osl::sign
constexpr int sign(Player player)
Definition: basic_type.h:23
osl::isPromoted
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
Definition: basic_type.h:137
osl::Piece::square
const Square square() const
Definition: basic_type.h:832
osl::Piece::ptype
Ptype ptype() const
Definition: basic_type.h:821
osl::record::KanjiMove::strToMove
const Move strToMove(const std::string &, const NumEffectState &state, const Move &last_move) const
Convert a Japanese string (one token) to a move object.
Definition: kanjiMove.cc:361
osl::Move::isPass
bool isPass() const
Definition: basic_type.h:1092
osl::ki2::Ki2File::Illegal
@ Illegal
Definition: ki2.h:29
K_YORU
#define K_YORU
Definition: kanjiCode.h:50
osl::BLACK
@ BLACK
Definition: basic_type.h:9
osl::canPromote
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
Definition: basic_type.h:147
kanjiPrint.h
osl::record::Record::player
CArray< std::string, 2 > player
Definition: record.h:29
K_HIKU
#define K_HIKU
Definition: kanjiCode.h:51
osl::misc::sjis2euc
std::string sjis2euc(const std::string &str)
Convert character encoding from Shift_JIS to EUC-JP.
Definition: sjis2euc.cc:9
sjis2euc.h
osl::record::ki2::Ki2IOError
Definition: ki2IOError.h:16
osl::Player
Player
Definition: basic_type.h:8
K_SUGU
#define K_SUGU
Definition: kanjiCode.h:49
osl::CArray
Definition: container.h:20
osl::Move::to
const Square to() const
Definition: basic_type.h:1132
osl::Move::isPromotion
bool isPromotion() const
Definition: basic_type.h:1147
K_BLACK
#define K_BLACK
Definition: kanjiCode.h:92
osl::record::Record::moves
std::vector< Move > moves() const
Definition: record.h:41
osl::Move::player
Player player() const
Definition: basic_type.h:1195
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition: basic_type.h:157
osl::record::Record
Definition: record.h:15
osl::record::Record::setDate
void setDate(const std::string &date_str)
Definition: record.cc:39
osl::ki2::Ki2File::Ki2File
Ki2File(const std::string &filename, bool verbose=false)
Definition: ki2.cc:92