예제 #1
0
파일: SBook.cs 프로젝트: ai5/BookConv
        /// <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;
                }
            }
        }
예제 #2
0
파일: Sfen.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 指し手文字列を返す
        /// </summary>
        /// <param name="move"></param>
        /// <returns></returns>
        public static string MoveToString(MoveData move)
        {
            string sfen = string.Empty;

            using (StringWriter wr = new StringWriter())
            {
                WriteMove(move, wr);

                sfen = wr.ToString();
            }

            return sfen;
        }
예제 #3
0
        /// <summary>
        /// 内部指し手に変換
        /// </summary>
        /// <param name="gmove"></param>
        /// <returns></returns>
        private static MoveData ConvertMove(PlayerColor color, GikouMove gmove)
        {
            MoveData move = new MoveData();

            if (color == PlayerColor.White)
            {
                move.ToSquare = Square.Make((int)(gmove.to / 9), (int)(8 - (gmove.to % 9)));
                move.FromSquare = Square.Make((int)(gmove.from / 9), (int)(8 - (gmove.from % 9)));

                move.MoveType = gmove.promotion == 1 ? MoveType.Promotion : MoveType.Normal;
                if (gmove.drop == 1)
                {
                    move.MoveType |= MoveType.DropFlag;
                }

                move.Piece = (Piece)gmove.piece | Piece.WhiteFlag;
                move.CapturePiece = ((Piece)gmove.capture).Opp();
            }
            else
            {
                move.ToSquare = Square.Make((int)(8 - (gmove.to / 9)), (int)gmove.to % 9);
                move.FromSquare = Square.Make((int)(8 - (gmove.from / 9)), (int)gmove.from % 9);

                move.MoveType = gmove.promotion == 1 ? MoveType.Promotion : MoveType.Normal;
                if (gmove.drop == 1)
                {
                    move.MoveType |= MoveType.DropFlag;
                }

                move.Piece = (Piece)gmove.piece;
                move.CapturePiece = (Piece)gmove.capture;
            }
                if (move.ToSquare < 0 || move.FromSquare < 0)
                {
                Console.WriteLine("???");
                }

            return move;
        }
예제 #4
0
파일: MoveData.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 
        /// </summary>
        /// <param name="movedata"></param>
        /// <returns></returns>
        public bool Equals(MoveData movedata)
        {
            bool ret = false;

            if (movedata == null)
            {
                return false;
            }

            if (this.MoveType.HasFlag(MoveType.DropFlag) && movedata.MoveType.HasFlag(MoveType.DropFlag))
            {
                if (this.ToSquare == movedata.ToSquare
                    && this.Piece == movedata.Piece)
                {
                    ret = true;
                }
            }
            else if (this.MoveType.HasFlag(MoveType.MoveFlag) && movedata.MoveType.HasFlag(MoveType.MoveFlag))
            {
                if (this.FromSquare == movedata.FromSquare
                    && this.ToSquare == movedata.ToSquare
                    && (this.MoveType & MoveType.MoveMask) == (movedata.MoveType & MoveType.MoveMask))
                {
                    ret = true;
                }
            }
            else
            {
                if (this.MoveType == movedata.MoveType)
                {
                    ret = true;
                }
            }

            return ret;
        }
예제 #5
0
파일: MoveData.cs 프로젝트: ai5/BookConv
 public static void Copy(MoveData dest, MoveData src)
 {
     dest.ToSquare = src.ToSquare;
     dest.FromSquare = src.FromSquare;
     dest.MoveType = src.MoveType;
     dest.Piece = src.Piece;
     dest.CapturePiece = src.CapturePiece;
 }
예제 #6
0
파일: MoveData.cs 프로젝트: mizar/BookConv
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="moveData"></param>
 public MoveData(MoveData moveData)
 {
     Copy(this, moveData);
 }
예제 #7
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);
        }
예제 #8
0
파일: SPosition.cs 프로젝트: ai5/BookConv
        private int[] whiteHand; // 後手持ち駒

        #endregion Fields

        #region Constructors

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public SPosition()
        {
            this.blackHand = new int[HandMax];
            this.whiteHand = new int[HandMax];

            this.hand = new int[][] { this.blackHand, this.whiteHand };

            this.board = new Piece[Square.NSQUARE];
            this.moveLast = new MoveData();

            this.Init();
        }
예제 #9
0
파일: SBook.cs 프로젝트: ai5/BookConv
 /// <summary>
 /// 指し手の値に変更
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public static int MoveFromMoveData(MoveData movedata)
 {
     return MoveFromMoveData(movedata.FromSquare, movedata.ToSquare, movedata.MoveType, movedata.Piece, movedata.CapturePiece, movedata.Turn);
 }
예제 #10
0
파일: SPosition.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 1手戻す
        /// </summary>
        /// <param name="moveData"></param>
        /// <returns></returns>
        private bool UnMoveNormal(MoveData moveData)
        {
            Piece piece;

            // 一応最初に簡易なチェックk

            Debug.Assert(moveData.FromSquare >= 0 && moveData.FromSquare < Square.NSQUARE, "引数エラー");

            // from側は駒がないはず
            Debug.Assert(this.board[moveData.FromSquare] == Piece.NoPiece, "引数エラー");

            // to側は駒があるかつ自分の駒
            Debug.Assert((this.board[moveData.ToSquare] != Piece.NoPiece) && (this.board[moveData.ToSquare].ColorOf() == this.turn.Opp()), "引数エラー");

            piece = moveData.Piece;

            // 成りなり判定
            if (moveData.MoveType.HasFlag(MoveType.Promotion))
            {
                // 一応成りを落とす
                piece &= ~Piece.PromotionFlag;
            }

            this.board[moveData.FromSquare] = piece;
            this.board[moveData.ToSquare] = moveData.CapturePiece;

            if (moveData.CapturePiece != Piece.NoPiece)
            {
                if (this.turn.Opp() == PlayerColor.White)
                {
                    this.whiteHand[(int)moveData.CapturePiece.ToHnadIndex()] -= 1;
                }
                else
                {
                    this.blackHand[(int)moveData.CapturePiece.ToHnadIndex()] -= 1;
                }
            }

            return true;
        }
예제 #11
0
파일: SPosition.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 持ち駒を打つ
        /// </summary>
        /// <param name="moveData"></param>
        /// <returns></returns>
        private bool UnMoveDrop(MoveData moveData)
        {
            Piece piece;
            PlayerColor unmoveTurn = this.Turn.Opp(); // unmoveするときは現在のターンと反対側

            // 一応最初に簡易なチェックk

            piece = moveData.Piece;

            Debug.Assert(this.board[moveData.ToSquare] == piece, "駒が違う?");
            Debug.Assert(!piece.IsPromoted(), "成っている状態で打てない");

            this.hand[(int)unmoveTurn][(int)moveData.Piece.ToHnadIndex()] += 1;

            this.board[moveData.ToSquare] = Piece.NoPiece;

            return true;
        }
예제 #12
0
파일: SPosition.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 通常の駒の移動
        /// </summary>
        /// <param name="moveData"></param>
        /// <returns></returns>
        private bool MoveNormal(MoveData moveData)
        {
            Piece piece;

            // 一応最初に簡易なチェックk

            Debug.Assert(moveData.FromSquare >= 0 && moveData.FromSquare < Square.NSQUARE, "引数エラー");

            // from側に駒がある
            Debug.Assert(this.board[moveData.FromSquare] != Piece.NoPiece, "引数エラー");
            // 色が一致 2手差し対応のため色チェックは外す
            //            Debug.Assert(this.board[move_data.from_square].ColorOf() == turn);

            // 移動先が空白か相手の駒
            Debug.Assert((this.board[moveData.ToSquare] == Piece.NoPiece) || (this.board[moveData.ToSquare].ColorOf() == this.turn.Opp()), "引数エラー");

            piece = moveData.Piece | PieceExtensions.PieceFlagFromColor(this.turn);  // 棋譜からの指し手だと色フラグが付いていないので現在のターンで先後を決める

            Debug.Assert(this.board[moveData.FromSquare] == piece, "引数エラー"); // from位置の駒が違う

            // 成りなり判定
            if (moveData.MoveType.HasFlag(MoveType.Promotion))
            {
                // 成りのチェック成っていない駒->成るのみOk
                Debug.Assert(!piece.IsPromoted(), "すでになっている駒を成ろうとしている");

                piece |= Piece.PromotionFlag;
            }

            this.board[moveData.FromSquare] = Piece.NoPiece;
            this.board[moveData.ToSquare] = piece;

            if (moveData.CapturePiece != Piece.NoPiece)
            {
                if (this.turn == PlayerColor.White)
                {
                    this.whiteHand[(int)moveData.CapturePiece.ToHnadIndex()] += 1;
                }
                else
                {
                    this.blackHand[(int)moveData.CapturePiece.ToHnadIndex()] += 1;
                }
            }

            return true;
        }
예제 #13
0
파일: SPosition.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 持ち駒を打つ
        /// </summary>
        /// <param name="moveData"></param>
        /// <returns></returns>
        private bool MoveDrop(MoveData moveData)
        {
            Piece piece;

            // 一応最初に簡易なチェックk

            piece = moveData.Piece | PieceExtensions.PieceFlagFromColor(this.turn);

            // 持ってない
            if (!this.IsHand(this.turn, moveData.Piece.ToHnadIndex()))
            {
                Debug.Assert(false, "持っていない駒は打てない");
                return false;
            }

            Debug.Assert(this.board[moveData.ToSquare] == Piece.NoPiece, "移動先が空白でない");
            Debug.Assert(!piece.IsPromoted(), "成っている状態で打てない");

            this.hand[(int)this.turn][(int)moveData.Piece.ToHnadIndex()] -= 1;

            this.board[moveData.ToSquare] = piece;

            return true;
        }
예제 #14
0
파일: SPosition.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 1手戻す
        /// </summary>
        /// <param name="moveData"></param>
        /// <returns></returns>
        public bool UnMove(MoveData moveData, MoveData curent)
        {
            bool ret = true;

            Debug.Assert(moveData.ToSquare >= 0 && moveData.ToSquare < Square.NSQUARE, "引数エラー");
            Debug.Assert(moveData.MoveType.IsMove(), "引数エラー");

            if (moveData.MoveType.HasFlag(MoveType.DropFlag))
            {
                Debug.Assert(moveData.Piece != Piece.NoPiece, "引数エラー");
                ret = this.UnMoveDrop(moveData);
            }
            else if (moveData.MoveType == MoveType.Pass)
            {
                // パス
            }
            else
            {
                Debug.Assert(moveData.Piece != Piece.NoPiece, "引数エラー");
                ret = this.UnMoveNormal(moveData);
            }

            if (!ret)
            {
                // 指し手登録エラー
                return false;
            }

            if (curent != null)
            {
                MoveData.Copy(this.moveLast, curent);
            }

            this.turn = this.turn.Opp(); // 手番変更

            return ret;
        }
예제 #15
0
파일: MoveData.cs 프로젝트: ai5/BookConv
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="moveData"></param>
 public MoveData(MoveData moveData)
 {
     Copy(this, moveData);
 }
예제 #16
0
파일: SBook.cs 프로젝트: ai5/BookConv
        public SBookMove(MoveData movedata, SBookState state)
        {
            this.NextState = state;

            this.Move = SBookMove.MoveFromMoveData(movedata);
            this.Evalution = SBookMoveEvalution.None;
            this.Weight = 1;
        }
예제 #17
0
파일: Sfen.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// 指し手の出力
        /// </summary>
        /// <param name="position"></param>
        /// <param name="sr"></param>
        private static void WriteMove(MoveData move_data, TextWriter wr)
        {
            // 以下のような漢字
            // 7六歩(77)    7g7f
            // 1一1銀成(22) 1a2b+
            // 6五金打      G*6e

            if (move_data.MoveType.IsResult())
            {
                // 結果の場合
                switch (move_data.MoveType)
                {
                    case MoveType.Resign: // 投了
                    case MoveType.Timeout: // 切れ負け
                    case MoveType.LoseFoul: // 反則負け
                    case MoveType.LoseNyugyoku: // 入玉負け
                        wr.Write("resign");
                        break;
                    case MoveType.Repetition: // 千日手
                    case MoveType.Draw:  // 持将棋
                        wr.Write("draw");
                        break;
                    case MoveType.WinFoul: // 反則勝ち
                    case MoveType.WinNyugyoku: // 入玉勝ち
                        wr.Write("win");
                        break;
                    default:
                        // 上記以外は出力しない
                        break;
                }
            }
            else if (move_data.MoveType == MoveType.Pass)
            {
                wr.Write("pass"); // gps合わせで0000ではなくpassにする
            }
            else if (move_data.MoveType.HasFlag(MoveType.DropFlag))
            {
                wr.Write(
                    "{0}*{1}{2}",
                    CharFromPieceType(move_data.Piece.TypeOf()),
                    (char)('1' + move_data.ToSquare.SujiOf() - 1),
                    (char)('a' + move_data.ToSquare.DanOf() - 1));
            }
            else if (move_data.MoveType.HasFlag(MoveType.MoveFlag))
            {
                wr.Write(
                    "{0}{1}{2}{3}",
                    (char)('1' + move_data.FromSquare.SujiOf() - 1),
                    (char)('a' + move_data.FromSquare.DanOf() - 1),
                    (char)('1' + move_data.ToSquare.SujiOf() - 1),
                    (char)('a' + move_data.ToSquare.DanOf() - 1));

                if (move_data.MoveType.HasFlag(MoveType.Promotion))
                {
                    // 成り
                    wr.Write("+");
                }
            }
        }
예제 #18
0
파일: SBook.cs 프로젝트: ai5/BookConv
        /// <summary>
        /// MoveDataを取得
        /// </summary>
        /// <returns></returns>
        public MoveData GetMoveData()
        {
            MoveData moveData = new MoveData();

            moveData.ToSquare = this.To;
            moveData.FromSquare = this.From;
            moveData.Piece = this.Piece;
            moveData.MoveType = this.MoveType;
            moveData.CapturePiece = this.CapturePiece;

            return moveData;
        }
예제 #19
0
파일: Sfen.cs 프로젝트: ai5/BookConv
        /// <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>
        /// 指し手の出力
        /// </summary>
        /// <param name="position"></param>
        /// <param name="sr"></param>
        private static void WriteMove(MoveData move_data, TextWriter wr)
        {
            // 以下のような漢字
            // 7六歩(77)    7g7f
            // 1一1銀成(22) 1a2b+
            // 6五金打      G*6e

            if (move_data.MoveType.IsResult())
            {
                // 結果の場合
                switch (move_data.MoveType)
                {
                case MoveType.Resign:       // 投了
                case MoveType.Timeout:      // 切れ負け
                case MoveType.LoseFoul:     // 反則負け
                case MoveType.LoseNyugyoku: // 入玉負け
                    wr.Write("resign");
                    break;

                case MoveType.Repetition: // 千日手
                case MoveType.Draw:       // 持将棋
                    wr.Write("draw");

                    break;

                case MoveType.WinFoul:     // 反則勝ち
                case MoveType.WinNyugyoku: // 入玉勝ち
                    wr.Write("win");
                    break;

                default:
                    // 上記以外は出力しない
                    break;
                }
            }
            else if (move_data.MoveType == MoveType.Pass)
            {
                wr.Write("pass"); // gps合わせで0000ではなくpassにする
            }
            else if (move_data.MoveType.HasFlag(MoveType.DropFlag))
            {
                wr.Write(
                    "{0}*{1}{2}",
                    CharFromPieceType(move_data.Piece.TypeOf()),
                    (char)('1' + move_data.ToSquare.SujiOf() - 1),
                    (char)('a' + move_data.ToSquare.DanOf() - 1));
            }
            else if (move_data.MoveType.HasFlag(MoveType.MoveFlag))
            {
                wr.Write(
                    "{0}{1}{2}{3}",
                    (char)('1' + move_data.FromSquare.SujiOf() - 1),
                    (char)('a' + move_data.FromSquare.DanOf() - 1),
                    (char)('1' + move_data.ToSquare.SujiOf() - 1),
                    (char)('a' + move_data.ToSquare.DanOf() - 1));

                if (move_data.MoveType.HasFlag(MoveType.Promotion))
                {
                    // 成り
                    wr.Write("+");
                }
            }
        }
예제 #21
0
파일: SBook.cs 프로젝트: mizar/BookConv
 /// <summary>
 /// 指し手の値に変更
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public static int MoveFromMoveData(MoveData movedata)
 {
     return(MoveFromMoveData(movedata.FromSquare, movedata.ToSquare, movedata.MoveType, movedata.Piece, movedata.CapturePiece, movedata.Turn));
 }