csa-to-kifu.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
csa-to-kifu.cc
Go to the documentation of this file.
1 /* csa-to-kifu.cc
2 */
3 #include "osl/record/kanjiPrint.h"
4 #include "osl/record/kanjiCode.h"
5 #include "osl/record/ki2.h"
6 #include "osl/record/csa.h"
7 #include "osl/record/csaRecord.h"
8 #include "osl/record/csaIOError.h"
9 #include "osl/misc/iconvConvert.h"
10 #include <boost/program_options.hpp>
11 #include <boost/lambda/lambda.hpp>
12 #include <boost/lambda/bind.hpp>
13 #include <sstream>
14 #include <iostream>
15 #include <iomanip>
16 #include <fstream>
17 #include <string>
18 #include <vector>
19 #include <algorithm>
20
21 namespace po = boost::program_options;
22 using namespace osl;
23
24 std::string header;
25 std::vector<std::string> files;
26
27 void run(const std::string& filename);
28
29 int main(int argc, char **argv)
30 {
31 boost::program_options::options_description command_line_options;
32 command_line_options.add_options()
33 ("header,h", boost::program_options::value<std::string>(&header)->default_value(""),
34 "header for kifu-file")
35 ("input-file", boost::program_options::value< std::vector<std::string> >(),
36 "input files in csa format (.csa)")
37 ("help,h", "Show help message");
38 boost::program_options::variables_map vm;
39 boost::program_options::positional_options_description p;
40 p.add("input-file", -1);
41
42 try
43 {
44 boost::program_options::store(
45 boost::program_options::command_line_parser(
46 argc, argv).options(command_line_options).positional(p).run(), vm);
47 boost::program_options::notify(vm);
48 files = vm["input-file"].as< std::vector<std::string> >();
49 if (vm.count("help"))
50 {
51 std::cout << command_line_options << std::endl;
52 return 0;
53 }
54 }
55 catch (std::exception &e)
56 {
57 std::cerr << "error in parsing options" << std::endl
58 << e.what() << std::endl;
59 std::cerr << command_line_options << std::endl;
60 return 1;
61 }
62
63 try
64 {
65 for (size_t i=0; i<files.size(); ++i)
66 run(files[i]);
67 }
68 catch (...)
69 {
70 return 1;
71 }
72 return 0;
73 }
74
75 void run(const std::string& filename)
76 {
77 if (header != "") {
78 std::ifstream is(header.c_str()); // sjis, \r\n?
79 std::string line;
80 while (std::getline(is, line))
81 std::cout << line << "\n";
82 }
83 else {
84 std::cout << "# "
85 << IconvConvert::convert("EUC-JP", "SHIFT_JIS", K_KIFU)
86 << "\r\n";
87 }
88 try {
89 CsaFile file(filename.c_str());
90 record::Record record = file.getRecord();
91 vector<Move> moves;
92 vector<int> time;
93 vector<record::SearchInfo> search_info;
94 vector<std::string> raw_comments;
95 record.getMoves(moves, time, raw_comments, search_info);
96
97 NumEffectState state(file.getInitialState());
98 CArray<int,2> total = {{0,0}};
99 for (size_t i=0; i<moves.size(); ++i) {
100 if (! moves[i].isNormal() || ! state.isValidMove(moves[i]))
101 break;
102 const Square to = moves[i].to();
103 std::ostringstream ss;
104 ss << std::setw(4) << std::setfill(' ') << i+1 << ' '
105 << record::StandardCharacters::suji[to.x()]
106 << record::StandardCharacters::dan[to.y()];
107 ss << record::ki2::show(moves[i].oldPtype());
108 if (moves[i].isPromotion())
109 ss << K_NARU;
110 const Square from = moves[i].from();
111 if (from.isPieceStand())
112 ss << K_UTSU;
113 else
114 ss << "(" << from.x() << from.y() << ")";
115 ss << " ";
116 if (time.size() > i) {
117 total[i%2] += time[i];
118 ss << "(" << std::setw(2) << std::setfill(' ') << time[i]/60
119 << ':' << std::setw(2) << std::setfill('0') << time[i]%60
120 << "/" << std::setw(2) << total[i%2]/60/60
121 << ':' << std::setw(2) << total[i%2]/60%60
122 << ':' << std::setw(2) << total[i%2]%60
123 << ")";
124 }
125 ss << "\r\n";
126
127 state.makeMove(moves[i]);
128
129 if (search_info.size() > i && ! search_info[i].moves.empty()) {
130 ss << IconvConvert::convert("UTF-8", "EUC-JP", "*読筋 ")
131 << search_info[i].value << " ";
132 NumEffectState copy(state);
133 for (size_t j=0; j<search_info[i].moves.size(); ++j) {
134 const Move move = search_info[i].moves[j];
135 if (move.isInvalid()
136 || (! move.isPass() && ! copy.isValidMove(move)))
137 break;
138 ss << record::ki2::show(move, copy, j ? search_info[i].moves[j-1] : moves[i]);
139 copy.makeMove(move);
140 }
141 ss << "\r\n";
142 }
143 std::cout << IconvConvert::convert("EUC-JP", "SHIFT_JIS", ss.str()) << std::flush;
144 }
145 }
146 catch (CsaIOError&) {
147 std::cerr << "parse error\n";
148 throw;
149 }
150 }
151
152 // ;;; Local Variables:
153 // ;;; mode:c++
154 // ;;; c-basic-offset:2
155 // ;;; End: