Last active
January 5, 2024 07:09
-
-
Save TadaoYamaoka/52507c3334f5cc1b22f0ea9e2fed47bc to your computer and use it in GitHub Desktop.
kisen_to_csa.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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