Пример #1
0
        /// <summary>
        /// 盤面比較
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public bool Equals(SPosition pos)
        {
            for (int i = 0; i < Square.NSQUARE; i++)
            {
                if (this.board[i] != pos.board[i])
                {
                    return(false);
                }
            }

            for (int i = 0; i < this.blackHand.Length; i++)
            {
                if (this.blackHand[i] != pos.blackHand[i])
                {
                    return(false);
                }
            }

            for (int i = 0; i < this.whiteHand.Length; i++)
            {
                if (this.whiteHand[i] != pos.whiteHand[i])
                {
                    return(false);
                }
            }

            if (this.turn != pos.turn)
            {
                return(false);
            }

            return(true);
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// 指し手の出力
        /// </summary>
        /// <param name="bookstate"></param>
        /// <param name="position"></param>
        /// <param name="aperyBook"></param>
        private static void WriteMoves(SBookState bookstate, SPosition position, AperyBook aperyBook)
        {
            if (bookstate == null)
            {
                return;
            }

            if (bookstate.Count != 0)
            {
                return; // 既に出力した
            }

            bookstate.Count++;

            foreach (SBookMove move in bookstate.Moves)
            {
                if (move.Weight != 0)
                {
                    aperyBook.Add(GetKey(position), move.ConvFromToPro(), move.Weight);
                }

                MoveData moveData = move.GetMoveData();

                if (position.Move(moveData))
                {
                    // 再帰呼び出し
                    WriteMoves(move.NextState, position, aperyBook);

                    position.UnMove(moveData, null);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// SBookをAperyBookに変換して保存する
        /// </summary>
        /// <param name="book"></param>
        /// <param name="filename"></param>
        public static void ExportApery(this SBook book, string filename)
        {
            // 初期局面の出力
            AperyBook aperyBook = new AperyBook();
            SPosition position  = new SPosition();

            book.ClearCount();
            int cnt = 0;

            foreach (SBookState state in book.BookStates)
            {
                if (state.Position != string.Empty)
                {
                    // 局面が入っている場合
                    Sfen.PositionFromString(position, state.Position);
                }

                // 指し手出力
                if (state.Count == 0 && ((state.Id == 0) || (state.Position != string.Empty)))
                {
                    WriteMoves(state, position, aperyBook);
                }

                cnt++;
            }

            aperyBook.Save(filename);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        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);
                }
            }
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <summary>
        /// SBookをYaneuraou book形式に変換して保存する
        /// </summary>
        /// <param name="book"></param>
        /// <param name="filename"></param>
        public static void ExportYaneuraOUbook(this SBook book, string filename)
        {
            //
            using (StreamWriter wr = new StreamWriter(filename, false, Encoding.UTF8))
            {
                wr.WriteLine("#YANEURAOU-DB2016 1.00");

                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, wr, 1);
                    }

                    cnt++;
                }
            }
        }
Пример #9
0
        /// <summary>
        /// SBookをAperyBookに変換して保存する
        /// </summary>
        /// <param name="book"></param>
        /// <param name="filename"></param>
        public static void ExportApery(this SBook book, string filename)
        {
            // 初期局面の出力
            AperyBook aperyBook = new AperyBook();
            SPosition position = new SPosition();
            book.ClearCount();
            int cnt = 0;

            foreach (SBookState state in book.BookStates)
            {
                if (state.Position != string.Empty)
                {
                    // 局面が入っている場合
                    Sfen.PositionFromString(position, state.Position);
                }

                // 指し手出力
                if (state.Count == 0 && ((state.Id == 0) || (state.Position != string.Empty)))
                {
                    WriteMoves(state, position, aperyBook);
                }

                cnt++;
            }

            aperyBook.Save(filename);
        }
Пример #10
0
        /// <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);
        }
Пример #11
0
        /// <summary>
        /// SBookをYaneuraou book形式に変換して保存する
        /// </summary>
        /// <param name="book"></param>
        /// <param name="filename"></param>
        public static void ExportYaneuraOUbook(this SBook book, string filename)
        {
            //
            using (StreamWriter wr = new StreamWriter(filename, false, Encoding.UTF8))
            {
                wr.WriteLine("#YANEURAOU-DB2016 1.00");

                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, wr, 1);
                    }

                    cnt++;
                }
            }
        }
Пример #12
0
        /// <summary>
        /// 局面追加
        /// </summary>
        public void Add(SPosition pos, MoveData moveData, int weight, int value, int depth)
        {
            string key = pos.PositionToString(1);

            SBookState state = this.GetBookState(key);

            if (state == null)
            {
                // 現在の局面がない場合
                state          = new SBookState();
                state.Games    = 1;
                state.WonBlack = 0;
                state.WonWhite = 0;

                state.Position = key;

                this.books.Add(key, state);
                this.BookStates.Add(state);
            }

            if (moveData != null)
            {
                pos.Move(moveData);
                string     next_key   = pos.PositionToString(1);
                SBookState next_state = this.GetBookState(next_key);
                pos.UnMove(moveData, null);

                if (next_state == null)
                {
                    next_state          = new SBookState();
                    next_state.Games    = 1;
                    next_state.WonBlack = 0;
                    next_state.WonWhite = 0;

                    next_state.Position = next_key;

                    this.books.Add(next_key, next_state);
                    this.BookStates.Add(next_state);
                }

                SBookMove m    = new SBookMove(moveData, next_state);
                SBookMove move = state.GetMove(m);

                if (move == null)
                {
                    // 指し手が無い場合は追加
                    m.Weight = weight;
                    m.Value  = value;
                    m.Depth  = depth;
                    state.AddMove(m);

                    // next_stateのPositionをクリアする
                    next_state.Position = string.Empty;
                    move = m;
                }
            }
        }
Пример #13
0
        /// <summary>
        /// 局面追加
        /// </summary>
        public void Add(SPosition pos, MoveData moveData, int weight, int value, int depth)
        {
            string key = pos.PositionToString(1);

            SBookState state = this.GetBookState(key);

            if (state == null)
            {
                // 現在の局面がない場合
                state = new SBookState();
                state.Games = 1;
                state.WonBlack = 0;
                state.WonWhite = 0;

                state.Position = key;

                this.books.Add(key, state);
                this.BookStates.Add(state);
            }

            if (moveData != null)
            {
                pos.Move(moveData);
                string next_key = pos.PositionToString(1);
                SBookState next_state = this.GetBookState(next_key);
                pos.UnMove(moveData, null);

                if (next_state == null)
                {
                    next_state = new SBookState();
                    next_state.Games = 1;
                    next_state.WonBlack = 0;
                    next_state.WonWhite = 0;

                    next_state.Position = next_key;

                    this.books.Add(next_key, next_state);
                    this.BookStates.Add(next_state);
                }

                SBookMove m = new SBookMove(moveData, next_state);
                SBookMove move = state.GetMove(m);

                if (move == null)
                {
                    // 指し手が無い場合は追加
                    m.Weight = weight;
                    m.Value = value;
                    m.Depth = depth;
                    state.AddMove(m);

                    // next_stateのPositionをクリアする
                    next_state.Position = string.Empty;
                    move = m;
                }
            }
        }
Пример #14
0
        /// <summary>
        /// 盤面出力
        /// </summary>
        /// <param name="notation"></param>
        /// <returns></returns>
        public static string PositionToString(this SPosition position, int num)
        {
            string sfen = string.Empty;

            using (StringWriter wr = new StringWriter())
            {
                WritePosition(position, wr, num);

                sfen = wr.ToString();
            }

            return(sfen);
        }
Пример #15
0
        /// <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);
                }
            }
        }
Пример #16
0
        /// <summary>
        /// sfen形式の棋譜読み込み
        /// </summary>
        /// <param name="notation"></param>
        /// <param name="sr"></param>
        public static void ReadNotation(SPosition pos, string str)
        {
            Tokenizer tok = new Tokenizer(str);
            string    token;

            token = tok.Token();
            if (token == "position")
            {
                token = tok.Token();
            }

            if (token == "startpos")
            {
                // 処理なし
            }
            else if (token == "sfen")
            {
                Sfen.ReadPosition(pos, tok.TokenPosition());
            }
            else if (token == "moves")
            {
                tok.Push(token);
            }
            else
            {
            }

            token = tok.Token();
            if (token == "moves")
            {
                while ((token = tok.Token()) != string.Empty)
                {
                    MoveData moveData = ParseMove(pos, token);
                    if (moveData == null)
                    {
                        break;
                    }

                    if (!pos.Move(moveData))
                    {
                        break;
                    }
                }
            }
        }
Пример #17
0
        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);
        }
Пример #18
0
        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;
        }
Пример #19
0
        /// <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;
        }
Пример #20
0
        ///////////////////////////////////////////////////////////////////// 
        /// <summary>
        /// sfen形式の盤情報を読み込み
        /// </summary>
        /// <param name="notation"></param>
        /// <param name="sr"></param>
        private static int ReadPosition(SPosition position, string sfen, int index = 0)
        {
            int file, rank;
            int ch;
            Piece piece;
            int piece_num;

            SPosition pos = position;

            file = 0;
            rank = 0;

            if (sfen != string.Empty)
            {
                pos.BoardClear();
            }

            // 局面データ
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;

                if (ch == ' ')
                {
                    break;
                }

                if (ch == '/')
                {
                    // 段の区切り
                    file = 0;
                    rank += 1;
                    if (rank >= Square.NRANK)
                    {
                        break;
                    }
                }
                else if (ch >= '0' && ch <= '9')
                {
                    // 数字は駒がないところ
                    file += ch - '0';
                }
                else
                {
                    piece = Piece.NoPiece;

                    // なり
                    if (ch == '+')
                    {
                        piece |= Piece.PromotionFlag;
                        if (index < sfen.Length)
                        {
                            ch = sfen[index];
                            index++;
                            if (ch == ' ')
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    // 後手
                    if (ch >= 'a' && ch <= 'z')
                    {
                        piece |= Piece.WhiteFlag;
                        ch = char.ToUpper((char)ch);
                    }

                    // charをPiece変換
                    PieceType pieceType;
                    if (CharToPieceHashtable.TryGetValue((char)ch, out pieceType))
                    {
                        piece |= (Piece)pieceType;
                    }
                    else
                    {
                        // 不明な文字列
                        Debug.Print("parse error");
                        piece = Piece.NoPiece;
                    }

                    if (piece.TypeOf() != PieceType.NoPieceType)
                    {
                        // 駒がある
                        if (file < Square.NFILE)
                        {
                            pos.SetPiece(file, rank, piece);
                            file++;
                        }
                    }
                }
            }

            // 手番
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;

                if (ch == ' ')
                {
                    break;
                }

                if (ch == 'w')
                {
                    pos.Turn = PlayerColor.White;
                }
                else if (ch == 'b')
                {
                    pos.Turn = PlayerColor.Black;
                }
            }

            // 持ち駒
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;
                if (ch == ' ')
                {
                    break;
                }

                piece_num = 1;

                // 枚数
                if (ch >= '0' && ch <= '9')
                {
                    piece_num = ch - '0';
                    if (index < sfen.Length)
                    {
                        ch = sfen[index];
                        index++;
                    }
                    else
                    {
                        break;
                    }

                    if (ch == ' ')
                    {
                        break;
                    }
                    else if (ch >= '0' && ch <= '9')
                    {
                        piece_num = (piece_num * 10) + (ch - '0');
                        if (index < sfen.Length)
                        {
                            ch = sfen[index];
                            index++;
                        }
                        else
                        {
                            break;
                        }

                        if (ch == ' ')
                        {
                            break;
                        }
                    }
                }

                PieceType piece_type;

                if (CharToPieceHashtable.TryGetValue(char.ToUpper((char)ch), out piece_type))
                {
                    if (char.IsUpper((char)ch))
                    {
                        // 大文字は先手
                        pos.SetBlackHand(piece_type, piece_num);
                    }
                    else
                    {
                        // 後手
                        pos.SetWhiteHand(piece_type, piece_num);
                    }
                }
            }

            // n手目 (読み飛ばす
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;
                if (ch == ' ')
                {
                    break;
                }
            }

            return index;
        }
Пример #21
0
        /// <summary>
        /// 指し手の出力
        /// </summary>
        /// <param name="bookstate"></param>
        /// <param name="position"></param>
        /// <param name="aperyBook"></param>
        private static void WriteMoves(SBookState bookstate, SPosition position, AperyBook aperyBook)
        {
            if (bookstate == null)
            {
                return;
            }

            if (bookstate.Count != 0)
            {
                return; // 既に出力した
            }

            bookstate.Count++;

            foreach (SBookMove move in bookstate.Moves)
            {
                if (move.Weight != 0)
                {
                    aperyBook.Add(GetKey(position), move.ConvFromToPro(), move.Weight);
                }

                MoveData moveData = move.GetMoveData();

                position.Move(moveData);

                // 再帰呼び出し
                WriteMoves(move.NextState, position, aperyBook);

                position.UnMove(moveData, null);
            }
        }
Пример #22
0
        /// <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;
        }
Пример #23
0
        /// <summary>
        /// 指し手の出力
        /// </summary>
        /// <param name="bookstate"></param>
        /// <param name="position"></param>
        /// <param name="aperyBook"></param>
        private static void WriteMoves(SBookState bookstate, SPosition position, StreamWriter wr, int depth)
        {
            if (bookstate == null)
            {
                return;
            }

            if (bookstate.Count != 0)
            {
                return; // 既に出力した
            }

            int count = 0;

            foreach (SBookMove move in bookstate.Moves)
            {
                if (move.Weight != 0)
                {
                    count++;
                }
            }

            bookstate.Count++;

            if (count != 0)
            {
                // 局面の出力
                wr.WriteLine("sfen " + position.PositionToString(depth));

                foreach (SBookMove move in bookstate.Moves)
                {
                    if (move.Weight != 0)
                    {
                        // 指し手の出力
                        MoveData moveData = move.GetMoveData();
                        string   next_str = "none";

                        SBookMove next_move = GetNextMove(move.NextState);
                        if (next_move != null)
                        {
                            MoveData nextMoveData = next_move.GetMoveData();
                            next_str = Sfen.MoveToString(nextMoveData);
                        }

                        wr.WriteLine("{0} {1} {3} {4} {2}", Sfen.MoveToString(moveData), next_str, move.Weight, move.Value, move.Depth);
                    }
                }
            }

            foreach (SBookMove move in bookstate.Moves)
            {
                // 指し手の出力
                MoveData moveData = move.GetMoveData();

                if (position.Move(moveData))
                {
                    // 再帰呼び出し
                    WriteMoves(move.NextState, position, wr, depth + 1);

                    position.UnMove(moveData, null);
                }
            }
        }
Пример #24
0
        /// <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); // 手数 実際には次が何手目か
            }
        }
Пример #25
0
        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);
        }
Пример #26
0
        /// <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);
        }
Пример #27
0
        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;
        }
Пример #28
0
        /// <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); // 手数 実際には次が何手目か
            }
        }
Пример #29
0
        /// <summary>
        /// 指し手の出力
        /// </summary>
        /// <param name="bookstate"></param>
        /// <param name="position"></param>
        /// <param name="aperyBook"></param>
        private static void WriteMoves(SBookState bookstate, SPosition position, StreamWriter wr, int depth)
        {
            if (bookstate == null)
            {
                return;
            }

            if (bookstate.Count != 0)
            {
                return; // 既に出力した
            }

            int count = 0;
            foreach (SBookMove move in bookstate.Moves)
            {
                if (move.Weight != 0)
                {
                    count++;
                }
            }

            bookstate.Count++;

            if (count != 0)
            {
                // 局面の出力
                wr.WriteLine("sfen " + position.PositionToString(depth));

                foreach (SBookMove move in bookstate.Moves)
                {
                    if (move.Weight != 0)
                    {
                        // 指し手の出力
                        MoveData moveData = move.GetMoveData();
                        string next_str = "none";

                        SBookMove next_move = GetNextMove(move.NextState);
                        if (next_move != null)
                        {
                            MoveData nextMoveData = next_move.GetMoveData();
                            next_str = Sfen.MoveToString(nextMoveData);
                        }

                        wr.WriteLine("{0} {1} {3} {4} {2}", Sfen.MoveToString(moveData), next_str, move.Weight, move.Value, move.Depth);
                    }
                }
            }

            foreach (SBookMove move in bookstate.Moves)
            {
                // 指し手の出力
                MoveData moveData = move.GetMoveData();

                position.Move(moveData);

                // 再帰呼び出し
                WriteMoves(move.NextState, position, wr, depth + 1);

                position.UnMove(moveData, null);
            }
        }
Пример #30
0
        /// <summary>
        /// sfen形式の棋譜読み込み
        /// </summary>
        /// <param name="notation"></param>
        /// <param name="sr"></param>
        public static void ReadNotation(SPosition pos, string str)
        {
            Tokenizer tok = new Tokenizer(str);
            string token;

            token = tok.Token();
            if (token == "position")
            {
                token = tok.Token();
            }

            if (token == "startpos")
            {
                // 処理なし
            }
            else if (token == "sfen")
            {
                Sfen.ReadPosition(pos, tok.TokenPosition());
            }
            else if (token == "moves")
            {
                tok.Push(token);
            }
            else
            {
            }

            token = tok.Token();
            if (token == "moves")
            {
                while ((token = tok.Token()) != string.Empty)
                {
                    MoveData moveData = ParseMove(pos, token);
                    if (moveData == null)
                    {
                        break;
                    }

                    if (!pos.Move(moveData))
                    {
                        break;
                    }
                }
            }
        }
Пример #31
0
        /// <summary>
        /// 盤面比較
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public bool Equals(SPosition pos)
        {
            for (int i = 0; i < Square.NSQUARE; i++)
            {
                if (this.board[i] != pos.board[i])
                {
                    return false;
                }
            }

            for (int i = 0; i < this.blackHand.Length; i++)
            {
                if (this.blackHand[i] != pos.blackHand[i])
                {
                    return false;
                }
            }

            for (int i = 0; i < this.whiteHand.Length; i++)
            {
                if (this.whiteHand[i] != pos.whiteHand[i])
                {
                    return false;
                }
            }

            if (this.turn != pos.turn)
            {
                return false;
            }

            return true;
        }
Пример #32
0
 /// <summary>
 /// 盤面情報読み込み
 /// </summary>
 /// <param name="notation"></param>
 /// <param name="sfen"></param>
 public static void PositionFromString(SPosition position, string sfen)
 {
     position.Init();
     ReadPosition(position, sfen);
 }
Пример #33
0
 /// <summary>
 /// 盤面情報読み込み
 /// </summary>
 /// <param name="notation"></param>
 /// <param name="sfen"></param>
 public static void PositionFromString(SPosition position, string sfen)
 {
     position.Init();
     ReadPosition(position, sfen);
 }
Пример #34
0
        /////////////////////////////////////////////////////////////////////

        /// <summary>
        /// sfen形式の盤情報を読み込み
        /// </summary>
        /// <param name="notation"></param>
        /// <param name="sr"></param>
        private static int ReadPosition(SPosition position, string sfen, int index = 0)
        {
            int   file, rank;
            int   ch;
            Piece piece;
            int   piece_num;

            SPosition pos = position;

            file = 0;
            rank = 0;

            if (sfen != string.Empty)
            {
                pos.BoardClear();
            }

            // 局面データ
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;

                if (ch == ' ')
                {
                    break;
                }

                if (ch == '/')
                {
                    // 段の区切り
                    file  = 0;
                    rank += 1;
                    if (rank >= Square.NRANK)
                    {
                        break;
                    }
                }
                else if (ch >= '0' && ch <= '9')
                {
                    // 数字は駒がないところ
                    file += ch - '0';
                }
                else
                {
                    piece = Piece.NoPiece;

                    // なり
                    if (ch == '+')
                    {
                        piece |= Piece.PromotionFlag;
                        if (index < sfen.Length)
                        {
                            ch = sfen[index];
                            index++;
                            if (ch == ' ')
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    // 後手
                    if (ch >= 'a' && ch <= 'z')
                    {
                        piece |= Piece.WhiteFlag;
                        ch     = char.ToUpper((char)ch);
                    }

                    // charをPiece変換
                    PieceType pieceType;
                    if (CharToPieceHashtable.TryGetValue((char)ch, out pieceType))
                    {
                        piece |= (Piece)pieceType;
                    }
                    else
                    {
                        // 不明な文字列
                        Debug.Print("parse error");
                        piece = Piece.NoPiece;
                    }

                    if (piece.TypeOf() != PieceType.NoPieceType)
                    {
                        // 駒がある
                        if (file < Square.NFILE)
                        {
                            pos.SetPiece(file, rank, piece);
                            file++;
                        }
                    }
                }
            }

            // 手番
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;

                if (ch == ' ')
                {
                    break;
                }

                if (ch == 'w')
                {
                    pos.Turn = PlayerColor.White;
                }
                else if (ch == 'b')
                {
                    pos.Turn = PlayerColor.Black;
                }
            }

            // 持ち駒
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;
                if (ch == ' ')
                {
                    break;
                }

                piece_num = 1;

                // 枚数
                if (ch >= '0' && ch <= '9')
                {
                    piece_num = ch - '0';
                    if (index < sfen.Length)
                    {
                        ch = sfen[index];
                        index++;
                    }
                    else
                    {
                        break;
                    }

                    if (ch == ' ')
                    {
                        break;
                    }
                    else if (ch >= '0' && ch <= '9')
                    {
                        piece_num = (piece_num * 10) + (ch - '0');
                        if (index < sfen.Length)
                        {
                            ch = sfen[index];
                            index++;
                        }
                        else
                        {
                            break;
                        }

                        if (ch == ' ')
                        {
                            break;
                        }
                    }
                }

                PieceType piece_type;

                if (CharToPieceHashtable.TryGetValue(char.ToUpper((char)ch), out piece_type))
                {
                    if (char.IsUpper((char)ch))
                    {
                        // 大文字は先手
                        pos.SetBlackHand(piece_type, piece_num);
                    }
                    else
                    {
                        // 後手
                        pos.SetWhiteHand(piece_type, piece_num);
                    }
                }
            }

            // n手目 (読み飛ばす
            while (index < sfen.Length)
            {
                ch = sfen[index];
                index++;
                if (ch == ' ')
                {
                    break;
                }
            }

            return(index);
        }