/// <summary> /// SBookをGikou形式に変換して保存する /// </summary> /// <param name="book"></param> /// <param name="filename"></param> public static void ExportGikou(this SBook book, string filename) { // GikouBook gikouBook = new GikouBook(); { SPosition position = new SPosition(); book.ClearCount(); int cnt = 0; foreach (SBookState state in book.BookStates) { if (state.Count == 0 && ((state.Id == 0) || (state.Position != string.Empty))) { if (state.Position != string.Empty) { Sfen.PositionFromString(position, state.Position); } // 指し手の出力 ルートからの局面以外はやねうら王2016には正しく認識されない WriteMoves(state, position, gikouBook); } cnt++; } } gikouBook.Save(filename); }
private static void ReadGikouBook(SBook book, GikouBook gbook, SPosition pos) { long key = ExportGikouBook.ComputeKey(pos, gbook); SBookState state = book.GetBookState(pos.PositionToString(1)); if (state != null && state.Moves.Count != 0) { // すでに登録されてる? return; } // 局面登録 book.Add(pos, null, 0, 0, 0); List <GikouBookEntry> entrys = gbook.GetEntry(key); if (entrys != null) { foreach (GikouBookEntry en in entrys) { MoveData move = ConvertMove(pos.Turn, en.Move); book.Add(pos, move, (int)en.Frequency, en.Score, 1); } foreach (GikouBookEntry en in entrys) { MoveData move = ConvertMove(pos.Turn, en.Move); pos.Move(move); ReadGikouBook(book, gbook, pos); pos.UnMove(move, null); } } }
/// <summary> /// 局面のハッシュキーを取得 /// </summary> /// <param name="position"></param> /// <param name="gikouBook"></param> /// <returns></returns> public static long ComputeKey(SPosition position, GikouBook gikouBook) { long key = 0; SPosition pos = (SPosition)position.Clone(); // 後手番であれば、将棋盤を180度反転して、先手番として扱う if (pos.Turn == PlayerColor.White) { pos.Flip(); } // 盤上の駒 int gikout_sq = 0; foreach (var sq in squareTable) { key += gikouBook.HashSeeds.GetPsq((int)pos.GetPiece(sq), gikout_sq); gikout_sq += 1; } // 持ち駒 foreach (PlayerColor color in new PlayerColor[] { PlayerColor.Black, PlayerColor.White }) { for (int pt = 1; pt < SPosition.HandMax; pt++) { for (int n = pos.GetHand(color, (PieceType)pt); n > 0; n--) { key += gikouBook.HashSeeds.GetHand((int)color, pt); } } } return(key); }
/// <summary> /// 指し手の出力 /// </summary> /// <param name="bookstate"></param> /// <param name="position"></param> /// <param name="aperyBook"></param> private static void WriteMoves(SBookState bookstate, SPosition position, GikouBook gikouBook) { if (bookstate == null) { return; } if (bookstate.Count != 0) { return; // 既に出力した } bookstate.Count++; int count = 0; foreach (SBookMove move in bookstate.Moves) { if (move.Weight != 0) { count++; } } if (count != 0) { long key = ComputeKey(position, gikouBook); foreach (SBookMove move in bookstate.Moves) { if (move.Weight != 0) { gikouBook.Add(key, (uint)move.Weight, (uint)move.Weight, move.Value, move.ConvertGikouMove()); } } } foreach (SBookMove move in bookstate.Moves) { // 指し手の出力 MoveData moveData = move.GetMoveData(); if (position.Move(moveData)) { // 再帰呼び出し WriteMoves(move.NextState, position, gikouBook); position.UnMove(moveData, null); } } }
public static SBook Import(string filename) { SBook book = new SBook(); SPosition pos = new SPosition(); try { GikouBook gbook = new GikouBook(filename); ReadGikouBook(book, gbook, pos); } catch (Exception ex) { throw ex; } return(book); }