Skip to content

Commit

Permalink
- PackedSfenの駒落ち、cshogiの出力と完全にバイナリ互換になるように調整した。
Browse files Browse the repository at this point in the history
  - UnitTestにPackedSfenのバイナリチェック追加。
  • Loading branch information
yaneurao committed Jan 10, 2024
1 parent 437c5db commit ae815e4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 15 deletions.
30 changes: 15 additions & 15 deletions source/extra/sfen_packer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ struct SfenPacker
{
// cout << pos;

// 以下の書き出し順が、GOLD,BISHOP,ROOKの順になるように調整しておく。
// (cshogiの変換例とバイナリレベルで一致させたいため)
constexpr PieceType to_apery_pieces[] = { NO_PIECE_TYPE , PAWN, LANCE, KNIGHT, SILVER, GOLD, BISHOP , ROOK };

// 駒箱枚数
// 最終、余った駒を駒箱として出力する必要がある。
int32_t hp_count[8] =
Expand Down Expand Up @@ -222,24 +226,29 @@ struct SfenPacker
for (auto c : COLOR)
for (PieceType pr = PAWN; pr < KING; ++pr)
{
int n = hand_count(pos.hand_of(c), pr);
// Aperyの手駒の並び順で列挙するように変更する。
PieceType pr2 = to_apery_pieces[pr];

int n = hand_count(pos.hand_of(c), pr2);

// この駒、n枚持ってるよ
for (int i = 0; i < n; ++i)
write_hand_piece_to_stream(make_piece(c, pr));
write_hand_piece_to_stream(make_piece(c, pr2));

// 駒箱から減らす
hp_count[pr] -= n;
hp_count[pr2] -= n;
}

// 最後に駒箱の分を出力
for (PieceType pr = PAWN ; pr < KING ; ++pr)
{
int n = hp_count[pr];
PieceType pr2 = to_apery_pieces[pr];

int n = hp_count[pr2];

// この駒、n枚駒箱にあるよ
for (int i = 0; i < n ; ++i)
write_piecebox_piece_to_stream(pr);
write_piecebox_piece_to_stream(pr2);
}

// 綺麗に書けた..気がする。
Expand All @@ -249,17 +258,8 @@ struct SfenPacker
}

// data[32]をsfen化して返す。
string unpack()
std::string unpack()
{
// 駒箱枚数
// 最終、余った駒を駒箱として出力する必要がある。
int32_t hp_count[8] =
{
0,
18/*PAWN*/, 4/*LANCE*/, 4/*KNIGHT*/, 4/*SILVER*/,
2/*BISHOP*/, 2/*ROOK*/, 4/*GOLD*/
};

stream.set_data(data);

// 盤上の81升
Expand Down
64 changes: 64 additions & 0 deletions source/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3051,6 +3051,70 @@ void Position::UnitTest(Test::UnitTester& tester)
tester.test("pos_is_ok()",pos.pos_is_ok());
}

{
// packed sfenのテスト
auto section = tester.section("PackedSfen");

vector<string> test_sfens = {
"lnsgkgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w -",
"lns1kgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL w -",
"lnsgkgsnl/9/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGK4 w -",
"lnsgk4/9/ppppppppp/9/9/9/PPPPPPPPP/9/LNSGK4 w GBRgbr",
};

// packed by cshogi
/*
board = cshogi.Board()
psfen = np.zeros(32, dtype=np.uint8)
board.set_sfen(sfen)
board.to_psfen(psfen)
print(np.array2string(psfen, separator=', '))
*/
vector<PackedSfen> packed_sfens =
{
{
89, 164, 81, 34, 12, 171, 68, 252, 44, 167, 68, 56, 94, 137, 240,
72, 132, 87, 34, 60, 167, 68, 56, 86, 137, 248, 88, 70, 137, 48,
188, 126
},
{
89, 164, 81, 34, 12, 171, 68, 252, 44, 167, 68, 56, 94, 137, 240,
72, 4, 18, 225, 57, 37, 194, 177, 74, 196, 199, 50, 74, 132, 97,
191, 126
},
{
89, 164, 81, 34, 88, 37, 226, 199, 41, 17, 188, 18, 129, 68, 120,
37, 194, 115, 74, 132, 99, 149, 136, 143, 101, 148, 8, 67, 106, 107,
191, 126
},
{
89, 36, 18, 1, 137, 128, 68, 64, 34, 144, 8, 175, 68, 120, 78,
137, 112, 172, 18, 97, 25, 37, 194, 112, 30, 159, 251, 252, 166, 212,
218, 90
}
};

bool success = true;
for(size_t i = 0 ; i < test_sfens.size() ; ++i)
{
auto sfen = test_sfens[i];
auto &packed_sfen = packed_sfens[i];

StateInfo si;
pos.set(sfen, &si, Threads.main());

PackedSfen ps;
pos.sfen_pack(ps);

// バイナリ列として一致するか。
success &= ps == packed_sfen;

// decodeで元のsfenになることは、このあとのランダムプレイヤーのテストで散々やっているから
// ここでやる必要なし。
}
tester.test("handicapped sfen",success);
}

{
// それ以外のテスト
auto section = tester.section("misc");
Expand Down

0 comments on commit ae815e4

Please sign in to comment.