/// <summary> /// SPositionからApery用のハッシュキーを取得 /// </summary> /// <param name="position"></param> /// <returns></returns> private static ulong GetKey(SPosition pos) { ulong key = 0; // 盤上の駒 for (AperySquare ap = AperySquare.I9; ap < AperySquare.SquareNum; ap++) { int sq = Square.Make(ap.FileOf(), ap.RankOf()); Piece piece = pos.GetPiece(sq); if (piece != Piece.NoPiece) { int index = (int)piece.ConvAperyPiece(); key ^= AperyBook.ZobPiece[index][(int)ap]; } } // 持ち駒 for (PieceType pt = PieceType.FU; pt < PieceType.King; pt++) { int num = pos.GetHand(pos.Turn, pt); key ^= AperyBook.ZobHand[(int)pt - 1][num]; } if (pos.Turn == PlayerColor.White) { key ^= AperyBook.ZobTurn; } return(key); }
/// <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> /// SPositionからApery用のハッシュキーを取得 /// </summary> /// <param name="position"></param> /// <returns></returns> private static ulong GetKey(SPosition pos) { ulong key = 0; // 盤上の駒 for (AperySquare ap = AperySquare.I9; ap < AperySquare.SquareNum; ap++) { int sq = Square.Make(ap.FileOf(), ap.RankOf()); Piece piece = pos.GetPiece(sq); if (piece != Piece.NoPiece) { int index = (int)piece.ConvAperyPiece(); key ^= AperyBook.ZobPiece[index][(int)ap]; } } // 持ち駒 for (PieceType pt = PieceType.FU; pt < PieceType.King; pt++) { int num = pos.GetHand(pos.Turn, pt); key ^= AperyBook.ZobHand[(int)pt - 1][num]; } if (pos.Turn == PlayerColor.White) { key ^= AperyBook.ZobTurn; } return key; }
public static SBook ImportYaneuraOu(string filename) { SBook book = new SBook(); try { using (StreamReader sr = new StreamReader(filename)) { string line; SPosition pos = new SPosition(); book.Add(pos, null, 0, 0, 0); // 平手初期局面をいれる while ((line = sr.ReadLine()) != null) { if (line.StartsWith("sfen") || line.StartsWith("startpos") || line.StartsWith("position")) { Sfen.ReadNotation(pos, line); } else if (line.StartsWith("#") || line.StartsWith("//")) { // コメント } else { string[] str_array = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (str_array.Length >= 5) { MoveData move = Sfen.ParseMove(pos, str_array[0]); if (move.Piece == Piece.NoPiece || pos.GetPiece(move.ToSquare).ColorOf() == move.Piece.ColorOf()) { Debug.WriteLine("bb"); } if (move != null && move.MoveType.IsMoveWithoutPass()) { int weight; int depth = 0; int value = 0; int.TryParse(str_array[2], out value); int.TryParse(str_array[3], out depth); if (int.TryParse(str_array[4], out weight)) { // 指し手の追加 book.Add(pos, move, weight, value, depth); } } } } } } // idの付け直し book.SetIds(); } catch (Exception ex) { throw ex; } return(book); }
public static SBook ImportYaneuraOu(string filename) { SBook book = new SBook(); try { using (StreamReader sr = new StreamReader(filename)) { string line; SPosition pos = new SPosition(); book.Add(pos, null, 0, 0, 0); // 平手初期局面をいれる while ((line = sr.ReadLine()) != null) { if (line.StartsWith("sfen") || line.StartsWith("startpos") || line.StartsWith("position")) { Sfen.ReadNotation(pos, line); } else if (line.StartsWith("#") || line.StartsWith("//")) { // コメント } else { string[] str_array = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (str_array.Length >= 5) { MoveData move = Sfen.ParseMove(pos, str_array[0]); if (move.Piece == Piece.NoPiece || pos.GetPiece(move.ToSquare).ColorOf() == move.Piece.ColorOf()) { Debug.WriteLine("bb"); } if (move != null && move.MoveType.IsMoveWithoutPass()) { int weight; int depth = 0; int value = 0; int.TryParse(str_array[2], out value); int.TryParse(str_array[3], out depth); if (int.TryParse(str_array[4], out weight)) { // 指し手の追加 book.Add(pos, move, weight, value, depth); } } } } } } // idの付け直し book.SetIds(); } catch (Exception ex) { throw ex; } return book; }
/// <summary> /// 指し手文字列をパースして指し手を返す /// </summary> public static MoveData ParseMove(SPosition position, string move) { if (move == "resign") { return(new MoveData(MoveType.Resign)); } else if (move == "win") { // 反則勝ち return(new MoveData(MoveType.WinNyugyoku)); } else if (move == "draw") { return(new MoveData(MoveType.Draw)); } else if (move == "pass" || move == "0000") { // uci的には0000でgpsはpass return(new MoveData(MoveType.Pass)); } if (move.Length < 4) { return(null); } MoveData moveData = new MoveData(); if (move[1] == '*') { // 打つ手 moveData.MoveType = MoveType.Drop; PieceType pieceType; if (CharToPieceHashtable.TryGetValue((char)move[0], out pieceType)) { moveData.Piece = (Piece)pieceType | PieceExtensions.PieceFlagFromColor(position.Turn); } else { // 不明な文字列 moveData.Piece = Piece.NoPiece; } int file = FileFromChar(move[2]); int rank = RankFromChar(move[3]); if (file < 0 || rank < 0) { return(null); } moveData.ToSquare = Square.Make(file, rank); } else { // 移動 moveData.MoveType = MoveType.Normal; // from int file = FileFromChar(move[0]); int rank = RankFromChar(move[1]); moveData.FromSquare = Square.Make(file, rank); file = FileFromChar(move[2]); rank = RankFromChar(move[3]); if (file < 0 || rank < 0) { return(null); } moveData.ToSquare = Square.Make(file, rank); moveData.Piece = position.GetPiece(moveData.FromSquare); if (move.Length >= 5 && move[4] == '+') { // 成り moveData.MoveType = MoveType.Promotion; } } // 盤面を進める if (moveData.MoveType.IsMoveWithoutPass()) { // 指し手の場合 if (position.MoveLast.MoveType.IsMove() && moveData.ToSquare == position.MoveLast.ToSquare) { moveData.MoveType |= MoveType.Same; // 同ほげ用のフラグ設定 } if (position.GetPiece(moveData.ToSquare) != Piece.NoPiece) { moveData.MoveType |= MoveType.Capture; // 駒とったフラグ設定 moveData.CapturePiece = position.GetPiece(moveData.ToSquare); // 駒をいれる } } return(moveData); }
/// <summary> /// 局面の出力 /// </summary> /// <param name="position"></param> /// <param name="sr"></param> private static void WritePosition(SPosition position, TextWriter wr, int movenumber) { int sq = 0; int space = 0; // 盤面出力 for (int rank = 0; rank < Square.NRANK; rank++) { // 段の切り替わりで/を出力 if (rank != 0) { wr.Write('/'); } for (int file = 0; file < Square.NFILE; file++, sq++) { Piece piece = position.GetPiece(sq); char ch; if (piece == Piece.NoPiece) { space++; } else { if (space != 0) { wr.Write(space); space = 0; } if (piece.IsPromoted()) { // 成り wr.Write('+'); } ch = CharFromPieceType(piece.TypeOf()); if (piece.HasFlag(Piece.WhiteFlag)) { ch = char.ToLower(ch); } wr.Write(ch); } } if (space != 0) { wr.Write(space); space = 0; } } // 手番の出力 if (position.Turn == PlayerColor.White) { wr.Write(" w "); } else { wr.Write(" b "); } // 持ち駒の出力 int hand_cnt = 0; for (PieceType pt = PieceType.HI; pt > PieceType.NoPieceType; pt--) { int num = position.GetBlackHand(pt); if (num != 0) { if (num > 1) { wr.Write(num); } wr.Write(CharFromPieceType(pt)); hand_cnt++; } } for (PieceType pt = PieceType.HI; pt > PieceType.NoPieceType; pt--) { int num = position.GetWhiteHand(pt); if (num != 0) { if (num > 1) { wr.Write(num); } char ch = CharFromPieceType(pt); ch = char.ToLower(ch); // 後手は小文字 wr.Write(ch); hand_cnt++; } } if (hand_cnt == 0) { wr.Write("-"); } if (movenumber != 0) { wr.Write(" {0}", movenumber); // 手数 実際には次が何手目か } }
/// <summary> /// 指し手文字列をパースして指し手を返す /// </summary> public static MoveData ParseMove(SPosition position, string move) { if (move == "resign") { return new MoveData(MoveType.Resign); } else if (move == "win") { // 反則勝ち return new MoveData(MoveType.WinNyugyoku); } else if (move == "draw") { return new MoveData(MoveType.Draw); } else if (move == "pass" || move == "0000") { // uci的には0000でgpsはpass return new MoveData(MoveType.Pass); } if (move.Length < 4) { return null; } MoveData moveData = new MoveData(); if (move[1] == '*') { // 打つ手 moveData.MoveType = MoveType.Drop; PieceType pieceType; if (CharToPieceHashtable.TryGetValue((char)move[0], out pieceType)) { moveData.Piece = (Piece)pieceType | PieceExtensions.PieceFlagFromColor(position.Turn); } else { // 不明な文字列 moveData.Piece = Piece.NoPiece; } int file = FileFromChar(move[2]); int rank = RankFromChar(move[3]); if (file < 0 || rank < 0) { return null; } moveData.ToSquare = Square.Make(file, rank); } else { // 移動 moveData.MoveType = MoveType.Normal; // from int file = FileFromChar(move[0]); int rank = RankFromChar(move[1]); moveData.FromSquare = Square.Make(file, rank); file = FileFromChar(move[2]); rank = RankFromChar(move[3]); if (file < 0 || rank < 0) { return null; } moveData.ToSquare = Square.Make(file, rank); moveData.Piece = position.GetPiece(moveData.FromSquare); if (move.Length >= 5 && move[4] == '+') { // 成り moveData.MoveType = MoveType.Promotion; } } // 盤面を進める if (moveData.MoveType.IsMoveWithoutPass()) { // 指し手の場合 if (position.MoveLast.MoveType.IsMove() && moveData.ToSquare == position.MoveLast.ToSquare) { moveData.MoveType |= MoveType.Same; // 同ほげ用のフラグ設定 } if (position.GetPiece(moveData.ToSquare) != Piece.NoPiece) { moveData.MoveType |= MoveType.Capture; // 駒とったフラグ設定 moveData.CapturePiece = position.GetPiece(moveData.ToSquare); // 駒をいれる } } return moveData; }