All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
checkmate-kisen.cc
Go to the documentation of this file.
2 #include "osl/hash/hashKey.h"
5 #include "osl/record/kisen.h"
6 #include "osl/record/csaRecord.h"
8 #include "osl/eval/see.h"
9 #include "osl/misc/filePath.h"
10 
11 #include <boost/accumulators/accumulators.hpp>
12 #include <boost/accumulators/statistics/mean.hpp>
13 #include <boost/accumulators/statistics/max.hpp>
14 #include <boost/scoped_ptr.hpp>
15 #include <boost/program_options.hpp>
16 #include <boost/filesystem/convenience.hpp>
17 #include <boost/foreach.hpp>
18 #include <boost/format.hpp>
19 #include <iostream>
20 #include <fstream>
21 
22 static void
23 convert_from_first(const osl::NumEffectState& initial,
24  const osl::vector<osl::Move> &in,
25  osl::vector<osl::Move> &out, size_t checkmate_limit)
26 {
27  osl::DualDfpn dfpn;
28  osl::NumEffectState state(initial);
29  BOOST_FOREACH(osl::Move move, in)
30  {
31  const int see = osl::See::see
32  (state, move, state.pin(state.turn()), state.pin(alt(state.turn())));
33  out.push_back(move);
34  state.makeMove(move);
35  if (state.inCheck() && see < 0
36  && dfpn.isLosingState(checkmate_limit, state,
37  osl::HashKey(state), osl::PathEncoding(state.turn())))
38  break;
39  }
40 }
41 
42 static void
43 trim_last(const osl::NumEffectState& initial,
44  const osl::vector<osl::Move> &in,
45  osl::vector<osl::Move> &out, size_t checkmate_limit)
46 {
47  if (in.empty())
48  return;
49  osl::DualDfpn dfpn;
50  osl::HistoryState history(initial);
51  BOOST_FOREACH(osl::Move move, in)
52  history.makeMove(move);
53  const osl::Player last_played = in.back().player();
54  int length = in.size();
55  for (; length > 0; length -= 2)
56  {
57  osl::NumEffectState current = history.state();
58  assert(current.turn() == alt(last_played));
59  if (! current.inCheck())
60  break;
61  if (! dfpn.isLosingState(checkmate_limit, current,
62  osl::HashKey(current), osl::PathEncoding(last_played)))
63  break;
64  history.unmakeMove();
65  history.unmakeMove();
66  }
67  out = in;
68  out.resize(length);
69 }
70 
71 static void convert(const std::vector<std::string> &input_filename,
72  const std::string &output_kisen_filename,
73  size_t checkmate_limit, bool output_ipx, bool trim)
74 {
75  namespace acc = boost::accumulators;
76  acc::accumulator_set<double, acc::features<acc::tag::max, acc::tag::mean> > accumulator;
77  std::ofstream ofs(output_kisen_filename.c_str());
79 
80  boost::scoped_ptr<osl::record::KisenIpxWriter> ipx_writer;
81  boost::scoped_ptr<std::ofstream> ipx_ofs;
82  if (output_ipx)
83  {
84  const boost::filesystem::path ipx_path =
85  boost::filesystem::change_extension(boost::filesystem::path(output_kisen_filename), ".ipx");
86  const std::string ipx = osl::misc::file_string(ipx_path);
87  ipx_ofs.reset(new std::ofstream(ipx.c_str()));
88  ipx_writer.reset(new osl::record::KisenIpxWriter(*ipx_ofs));
89  }
90 
91  for (size_t i = 0; i < input_filename.size(); ++i)
92  {
93  osl::KisenFile kisen(input_filename[i]);
94  osl::KisenIpxFile ipx(kisen.ipxFileName());
95  for (size_t j=0; j<kisen.size(); ++j)
96  {
97  osl::NumEffectState state = kisen.getInitialState();
98  osl::vector<osl::Move> moves = kisen.getMoves(j);
99  osl::vector<osl::Move> new_moves;
100  if (trim)
101  trim_last(state, moves, new_moves, checkmate_limit);
102  else
103  convert_from_first(state, moves, new_moves, checkmate_limit);
104 
105  osl::record::Record new_record;
106  new_record.setPlayer(osl::BLACK, ipx.getPlayer(j, osl::BLACK));
107  new_record.setPlayer(osl::WHITE, ipx.getPlayer(j, osl::WHITE));
108  new_record.setDate(ipx.getStartDate(j));
109  osl::SimpleState record_state = state;
111  visitor.setState(&record_state);
112  visitor.setRecord(&new_record);
113  for (size_t k=0; k<new_moves.size(); ++k)
114  {
115  visitor.addMoveAndAdvance(new_moves[k]);
116  state.makeMove(new_moves[k]);
117  }
118  new_record.setResult(state.turn() == osl::BLACK
120  accumulator(moves.size() - new_moves.size());
121  if (new_moves.size() >= 256)
122  std::cerr << "long record " << j << ' ' << new_moves.size() << "\n";
123  ks.save(&new_record);
124  if (output_ipx)
125  {
126  ipx_writer->save(new_record,
127  ipx.getRating(j, osl::BLACK),ipx.getRating(j, osl::WHITE),
128  ipx.getTitle(j, osl::BLACK), ipx.getTitle(j, osl::WHITE));
129  }
130  if ((j % 1000) == 999)
131  std::cerr << input_filename[i] << " " << j
132  << " max " << acc::max(accumulator)
133  << " mean " << acc::mean(accumulator) << "\n";
134  }
135  std::cerr << input_filename[i]
136  << " max " << acc::max(accumulator)
137  << " mean " << acc::mean(accumulator) << "\n";
138  }
139 }
140 
141 int main(int argc, char **argv)
142 {
143  bool output_ipx, trim;
144  std::string kisen_filename;
145  size_t checkmate_limit;
146  boost::program_options::options_description command_line_options;
147  command_line_options.add_options()
148  ("trim-from-last",
149  boost::program_options::value<bool>(&trim)->default_value(true),
150  "trim last checkmate sequence")
151  ("output-ipx",
152  boost::program_options::value<bool>(&output_ipx)->default_value(true),
153  "Whether output IPX file in addition to KIF file")
154  ("output-kisen-filename,o",
155  boost::program_options::value<std::string>(&kisen_filename)->
156  default_value("test.kif"),
157  "Output filename of Kisen file")
158  ("checkmate-limit,l",
159  boost::program_options::value<size_t>(&checkmate_limit)->default_value(1000),
160  "Whether output IPX file in addition to KIF file")
161  ("input-file", boost::program_options::value< std::vector<std::string> >(),
162  "input files in kisen format")
163  ("help", "Show help message");
164  boost::program_options::variables_map vm;
165  boost::program_options::positional_options_description p;
166  p.add("input-file", -1);
167 
168  try
169  {
171  boost::program_options::command_line_parser(
172  argc, argv).options(command_line_options).positional(p).run(), vm);
173  boost::program_options::notify(vm);
174  if (vm.count("help"))
175  {
176  std::cerr << "Usage: " << argv[0] << " [options] kisen-files\n";
177  std::cerr << " " << argv[0] << " [options]\n";
178  std::cout << command_line_options << std::endl;
179  return 0;
180  }
181  }
182  catch (std::exception &e)
183  {
184  std::cerr << "error in parsing options" << std::endl
185  << e.what() << std::endl;
186  std::cerr << "Usage: " << argv[0] << " [options] kisen-files\n";
187  std::cerr << " " << argv[0] << " [options]\n";
188  std::cerr << command_line_options << std::endl;
189  return 1;
190  }
191 
192  std::vector<std::string> files;
193  if (vm.count("input-file"))
194  files = vm["input-file"].as<std::vector<std::string> >();
195 
196  convert(files, kisen_filename, checkmate_limit, output_ipx, trim);
197  return 0;
198 }
199 // ;;; Local Variables:
200 // ;;; mode:c++
201 // ;;; c-basic-offset:2
202 // ;;; End: