Skip to content

Instantly share code, notes, and snippets.

@TadaoYamaoka
Last active January 5, 2024 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TadaoYamaoka/52507c3334f5cc1b22f0ea9e2fed47bc to your computer and use it in GitHub Desktop.
Save TadaoYamaoka/52507c3334f5cc1b22f0ea9e2fed47bc to your computer and use it in GitHub Desktop.
kisen_to_csa.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <string>
#define EM 0
#define FU 7
#define KY 6
#define KE 5
#define GI 4
#define KI 3
#define KA 2
#define HI 1
#define OU 8
constexpr char turnchar[] = { '+', '-' };
constexpr const char* piecestr[] = {
"", "HI", "KA", "KI", "GI", "KE", "KY", "FU", "OU", "RY", "UM", "", "NG", "NK", "NY", "TO"
};
constexpr const char* openingstr[] = {
"", "矢倉", "横歩取り", "ひねり飛車", "相掛かり", "角交換腰掛銀", "角交換その他",
"中飛車", "四間飛車", "三間飛車", "向飛車", "相振飛車", "その他の戦型",
"", "", "", "", "", "", "", "", "棒銀", "筋違角", "右四間飛車"
};
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cout << "kisen_to_csa kif out" << std::endl;
return 1;
}
unsigned char buff[512];
short idx[16];
char ipx[256];
// kif
std::ifstream kiffs(argv[1], std::ios::binary);
// IDX
std::string idxfile(argv[1]);
idxfile[idxfile.size() - 3] = 'I';
idxfile[idxfile.size() - 2] = 'D';
idxfile[idxfile.size() - 1] = 'X';
std::ifstream idxfs(idxfile, std::ios::binary);
// ipx
std::string ipxfile(argv[1]);
ipxfile[ipxfile.size() - 3] = 'i';
ipxfile[ipxfile.size() - 2] = 'p';
ipxfile[ipxfile.size() - 1] = 'x';
std::ifstream ipxfs(ipxfile, std::ios::binary);
idxfs.read((char*)idx, 32);
const int size = ((int*)idx)[0];
const std::string outdir(argv[2]);
for (int n = 0; n < size; n++) {
kiffs.read((char*)buff, 512);
idxfs.read((char*)idx, 32);
ipxfs.read((char*)ipx, 256);
// ref: http://www.yss-aya.com/kisen_format.txt
// endgame
const int endcode = idx[8];
if (!(endcode == 1 || endcode == 2)) {
continue;
}
// opening
const int opening = idx[7];
// ref: http://www.yss-aya.com/kif24rate.cpp
// name
char name1[15] = {}, name2[15] = {};
std::strncpy(name1, ipx, 14);
std::strncpy(name2, ipx + 14, 14);
// rating
const short rating1 = *(short*)(ipx + 0xd4);
const short rating2 = *(short*)(ipx + 0xd6);
// 出力
std::ostringstream oss;
oss << std::setfill('0') << std::setw(5) << n + 1;
std::ofstream ofs(outdir + oss.str() + ".csa");
ofs << "V2\n";
ofs << "N+" << name1 << "\n";
ofs << "N-" << name2 << "\n";
ofs << "$START_TIME:" << idx[4] << "/" << std::setfill('0') << std::setw(2) << idx[5] << "/" << idx[6] << "\n";
ofs << "$OPENING:" << openingstr[opening] << "\n";
ofs << "PI\n+\n";
ofs << "'rating:" << name1 << ":" << name2 << "\n";
ofs << "'black_rate:" << name1 << ":" << rating1 << ".0\n";
ofs << "'white_rate:" << name2 << ":" << rating2 << ".0\n";
// 盤面初期化
int hand[2][10] = {};
int ban[82] = { EM,
KY, KE, GI, KI, OU, KI, GI, KE, KY,
EM, KA, EM, EM, EM, EM, EM, HI, EM,
FU, FU, FU, FU, FU, FU, FU, FU, FU,
EM, EM, EM, EM, EM, EM, EM, EM, EM,
EM, EM, EM, EM, EM, EM, EM, EM, EM,
EM, EM, EM, EM, EM, EM, EM, EM, EM,
FU, FU, FU, FU, FU, FU, FU, FU, FU,
EM, HI, EM, EM, EM, EM, EM, KA, EM,
KY, KE, GI, KI, OU, KI, GI, KE, KY,
};
for (int i = 0; i < 256; i++) {
int f = buff[i * 2 + 1];
int t = buff[i * 2];
if (f == 0 || t == 0) break;
ofs << turnchar[i % 2];
if (f > 100) {
f -= 100;
// 持ち駒を使う手
// 飛車、角、金、銀、桂、香、歩の枚数?
int j = 1;
for (int sum = hand[i % 2][j]; sum < f; sum += hand[i % 2][++j]) {
//printf("j=%d sum=%d",j,sum);
}
// jが 1:飛車 2:角 3:金 4:銀 5:桂 6:香 7:歩
ban[t] = j;
hand[i % 2][j]--;
//printf("%d%d%s打",t%9,(t-1)/9+1," \0飛\0角\0金\0銀\0桂\0香\0歩\0"+j*3);
ofs << "00" << (t - 1) % 9 + 1 << (t - 1) / 9 + 1 << piecestr[j] << "\n";
}
else {
bool promote = false;
if (t > 100) {
t -= 100;
promote = true;
}
//printf("%1d%1d%1d%1d%s(%s)",f%9,(f-1)/9+1,t%9,(t-1)/9+1," \0飛\0角\0金\0銀\0桂\0香\0歩\0"+ban[f]*3," \0飛\0角\0金\0銀\0桂\0香\0歩\0"+ban[t]*3);
ofs << (f - 1) % 9 + 1 << (f - 1) / 9 + 1 << (t - 1) % 9 + 1 << (t - 1) / 9 + 1;
int piecef = ban[f];
if (promote) {
//printf("成");
piecef += 8;
}
ofs << piecestr[piecef] << "\n";
hand[i % 2][ban[t] % 8]++;
ban[t] = piecef;
ban[f] = EM;
}
//printf("\n");
//printf("先手:飛車 %d 角 %d 金 %d 銀 %d 桂 %d 香 %d 歩 %d\n",hand[0][1],hand[0][2],hand[0][3],hand[0][4],hand[0][5],hand[0][6],hand[0][7]);
//printf("後手:飛車 %d 角 %d 金 %d 銀 %d 桂 %d 香 %d 歩 %d\n",hand[1][1],hand[1][2],hand[1][3],hand[1][4],hand[1][5],hand[1][6],hand[1][7]);
}
ofs << "%TORYO\n";
ofs.close();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment