00001
00002
00003 #include "osl/record/kanjiPrint.h"
00004 #include "osl/record/kanjiCode.h"
00005 #include "osl/record/ki2.h"
00006 #include "osl/record/csa.h"
00007 #include "osl/record/csaRecord.h"
00008 #include "osl/record/csaIOError.h"
00009 #include "osl/apply_move/applyMove.h"
00010 #include "osl/misc/iconvConvert.h"
00011 #include <boost/program_options.hpp>
00012 #include <boost/lambda/lambda.hpp>
00013 #include <boost/lambda/bind.hpp>
00014 #include <sstream>
00015 #include <iostream>
00016 #include <iomanip>
00017 #include <fstream>
00018 #include <string>
00019 #include <vector>
00020 #include <algorithm>
00021
00022 namespace po = boost::program_options;
00023 using namespace osl;
00024
00025 std::string header;
00026 std::vector<std::string> files;
00027
00028 void run(const std::string& filename);
00029
00030 int main(int argc, char **argv)
00031 {
00032 boost::program_options::options_description command_line_options;
00033 command_line_options.add_options()
00034 ("header,h", boost::program_options::value<std::string>(&header)->default_value(""),
00035 "header for kifu-file")
00036 ("input-file", boost::program_options::value< std::vector<std::string> >(),
00037 "input files in csa format (.csa)")
00038 ("help,h", "Show help message");
00039 boost::program_options::variables_map vm;
00040 boost::program_options::positional_options_description p;
00041 p.add("input-file", -1);
00042
00043 try
00044 {
00045 boost::program_options::store(
00046 boost::program_options::command_line_parser(
00047 argc, argv).options(command_line_options).positional(p).run(), vm);
00048 boost::program_options::notify(vm);
00049 files = vm["input-file"].as< std::vector<std::string> >();
00050 if (vm.count("help"))
00051 {
00052 std::cout << command_line_options << std::endl;
00053 return 0;
00054 }
00055 }
00056 catch (std::exception &e)
00057 {
00058 std::cerr << "error in parsing options" << std::endl
00059 << e.what() << std::endl;
00060 std::cerr << command_line_options << std::endl;
00061 return 1;
00062 }
00063
00064 try
00065 {
00066 for (size_t i=0; i<files.size(); ++i)
00067 run(files[i]);
00068 }
00069 catch (...)
00070 {
00071 return 1;
00072 }
00073 return 0;
00074 }
00075
00076 void run(const std::string& filename)
00077 {
00078 if (header != "") {
00079 std::ifstream is(header.c_str());
00080 std::string line;
00081 while (std::getline(is, line))
00082 std::cout << line << "\n";
00083 }
00084 else {
00085 std::cout << "# "
00086 << IconvConvert::convert("EUC-JP", "SHIFT_JIS", record::K_KIFU)
00087 << "\r\n";
00088 }
00089 try {
00090 CsaFile file(filename.c_str());
00091 record::Record record = file.getRecord();
00092 vector<Move> moves;
00093 vector<int> time;
00094 vector<record::SearchInfo> search_info;
00095 vector<std::string> raw_comments;
00096 record.getMoves(moves, time, raw_comments, search_info);
00097
00098 NumEffectState state(file.getInitialState());
00099 CArray<int,2> total = {{0,0}};
00100 for (size_t i=0; i<moves.size(); ++i) {
00101 if (! moves[i].isNormal() || ! state.isValidMove(moves[i]))
00102 break;
00103 const Position to = moves[i].to();
00104 std::ostringstream ss;
00105 ss << std::setw(4) << std::setfill(' ') << i+1 << ' '
00106 << record::StandardCharacters::suji[to.x()]
00107 << record::StandardCharacters::dan[to.y()];
00108 ss << record::ki2::show(moves[i].oldPtype());
00109 if (moves[i].isPromote())
00110 ss << record::K_NARU;
00111 const Position from = moves[i].from();
00112 if (from.isPieceStand())
00113 ss << record::K_UTSU;
00114 else
00115 ss << "(" << from.x() << from.y() << ")";
00116 ss << " ";
00117 if (time.size() > i) {
00118 total[i%2] += time[i];
00119 ss << "(" << std::setw(2) << std::setfill(' ') << time[i]/60
00120 << ':' << std::setw(2) << std::setfill('0') << time[i]%60
00121 << "/" << std::setw(2) << total[i%2]/60/60
00122 << ':' << std::setw(2) << total[i%2]/60%60
00123 << ':' << std::setw(2) << total[i%2]%60
00124 << ")";
00125 }
00126 ss << "\r\n";
00127
00128 ApplyMoveOfTurn::doMove(state, moves[i]);
00129
00130 if (search_info.size() > i && ! search_info[i].moves.empty()) {
00131 ss << IconvConvert::convert("UTF-8", "EUC-JP", "*読筋 ")
00132 << search_info[i].value << " ";
00133 NumEffectState copy(state);
00134 for (size_t j=0; j<search_info[i].moves.size(); ++j) {
00135 const Move move = search_info[i].moves[j];
00136 if (move.isInvalid()
00137 || (! move.isPass() && ! copy.isValidMove(move)))
00138 break;
00139 ss << record::ki2::show(move, copy, j ? search_info[i].moves[j-1] : moves[i]);
00140 ApplyMoveOfTurn::doMove(copy, move);
00141 }
00142 ss << "\r\n";
00143 }
00144 std::cout << IconvConvert::convert("EUC-JP", "SHIFT_JIS", ss.str()) << std::flush;
00145 }
00146 }
00147 catch (CsaIOError&) {
00148 std::cerr << "parse error\n";
00149 throw;
00150 }
00151 }
00152
00153
00154
00155
00156