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