Example #1
0
 /// <summary>
 /// 返回将指定的字符解析出的棋子类型
 /// </summary>
 /// <param name="c">指定的字符</param>
 /// <returns></returns>
 public static PieceType ToPieceType(char c)
 {
     return(Enums.ToPieceType(c.ToString()));
 }
Example #2
0
        /// <summary>
        /// 生成指定的FEN格式字符串
        /// </summary>
        /// <returns></returns>
        public virtual string Generator()
        {
            string[]      parms = new string[6];
            StringBuilder note  = new StringBuilder();

            for (int j = 7; j >= 0; j--)
            {
                int           i       = 0;
                StringBuilder rowNote = new StringBuilder();


                string str = Rows[j].ToString();
                foreach (char achar in str)// 11b11k1B = 2b2k1b
                {
                    int tmp = 0;
                    if (!int.TryParse(achar.ToString(), out tmp))
                    {
                        if (i != 0)
                        {
                            rowNote.Append(i).Append(achar);
                            i = 0;
                        }
                        else
                        {
                            rowNote.Append(achar);
                        }
                    }
                    else
                    {
                        i++;
                    }
                }
                if (i != 0)
                {
                    rowNote.Append(i);
                }
                note.Append(rowNote).Append('/');
            }
            parms[0]    = note.ToString().TrimEnd('/');
            note.Length = 0;

            parms[1] = Enums.FormGameSide(GameSide).ToString();

            if (WhiteKingCastlingAvailability | WhiteQueenCastlingAvailability | BlackKingCastlingAvailability | BlackQueenCastlingAvailability)
            {
                if (WhiteKingCastlingAvailability)
                {
                    note.Append('K');
                }
                if (WhiteQueenCastlingAvailability)
                {
                    note.Append('Q');
                }
                if (BlackKingCastlingAvailability)
                {
                    note.Append('k');
                }
                if (BlackQueenCastlingAvailability)
                {
                    note.Append('q');
                }
            }
            else
            {
                note.Append('-');
            }

            parms[2]    = note.ToString();
            note.Length = 0;
            if (EnPassantTargetPosition == Position.Empty)
            {
                parms[3] = "-";
            }
            else
            {
                parms[3] = EnPassantTargetPosition.ToString();
            }
            parms[4] = HalfMoveClock.ToString();
            parms[5] = FullMoveNumber.ToString();

            StringBuilder sb = new StringBuilder();

            foreach (string parm in parms)
            {
                sb.Append(parm).Append(' ');
            }
            return(sb.ToString());
        }
Example #3
0
        public void Parse(string value)
        {
            #region Starting

            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException();
            }
            value = value.Trim();
            if (value.Length < 2 || value == "\r\n")
            {
                throw new ArgumentOutOfRangeException(value);
            }
            this.Actions.Add(Enums.Action.General);

            #endregion

            #region 针对尾部标记符进行一些操作,并返回裁剪掉尾部标记符的Value值
            foreach (string flagword in Servicer.Flags)
            {
                if (value.EndsWith(flagword))
                {
                    if (flagword.Equals("+"))//Qh5+
                    {
                        this.Actions.Add(Enums.Action.Check);
                    }
                    value = value.Substring(0, value.LastIndexOf(flagword));//裁剪掉尾部标记符
                    break;
                }
            }
            #endregion

            bool isMatch = false;
            foreach (var item in Servicer.StepRegex)
            {
                if (item.Second.IsMatch(value))
                {
                    switch (item.First)
                    {
                        #region case
                    case Servicer.AsStep.As_e4:
                        this.PieceType      = Enums.ToPieceType(this.GameSide);
                        this.TargetPosition = Position.Parse(value);
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_Rd7:
                        this.PieceType      = Enums.ToPieceType(value[0], this.GameSide);
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_Rxa2:
                        this.PieceType = Enums.ToPieceType(value[0], this.GameSide);
                        this.Actions.Add(Enums.Action.Capture);
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_Rbe1:
                        this.PieceType      = Enums.ToPieceType(value[0], this.GameSide);
                        this.SourceChar     = value[1];
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_N1c3:
                        this.PieceType      = Enums.ToPieceType(value[0], this.GameSide);
                        this.SourceChar     = value[1];
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_hxg6:
                        this.PieceType  = Enums.ToPieceType(this.GameSide);
                        this.SourceChar = value[0];
                        this.Actions.Add(Enums.Action.Capture);
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_Ngxf6:
                        this.PieceType  = Enums.ToPieceType(value[0], this.GameSide);
                        this.SourceChar = value[1];
                        this.Actions.Add(Enums.Action.Capture);
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_R8xf5:    //N1c3
                        this.PieceType  = Enums.ToPieceType(value[0], this.GameSide);
                        this.SourceChar = value[1];
                        this.Actions.Add(Enums.Action.Capture);
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_e8_Q:
                        this.PieceType = Enums.ToPieceType(this.GameSide);
                        this.Actions.Add(Enums.ToPromoteAction(value[value.Length - 1]));
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 4, 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_exf8_Q:
                        this.PieceType  = Enums.ToPieceType(this.GameSide);
                        this.SourceChar = value[0];
                        this.Actions.Add(Enums.Action.Capture);
                        this.Actions.Add(Enums.ToPromoteAction(value[value.Length - 1]));
                        this.TargetPosition = Position.Parse(value.Substring(value.Length - 4, 2));
                        isMatch             = true;
                        break;

                    case Servicer.AsStep.As_O_O:
                        this.PieceType = Enums.PieceType.None;
                        this.Actions.Add(Enums.Action.KingSideCastling);
                        isMatch = true;
                        break;

                    case Servicer.AsStep.As_O_O_O:
                        this.PieceType = Enums.PieceType.None;
                        this.Actions.Add(Enums.Action.QueenSideCastling);
                        isMatch = true;
                        break;
                        #endregion
                    }
                    if (isMatch == true)
                    {
                        break;
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// 解析一条FEN字符串
        /// </summary>
        /// <param name="str"></param>
        public virtual void Parse(string str)
        {
            string[] note = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            #region 16.1.3.1: Parse piece placement data

            int dot   = 1;
            int index = 0;

            string[] row = note[0].Split('/');
            if (row.Length != 8)
            {
                throw new ArgumentException("Invalid board specification, " + row.Length + " ranks are defined, there should be 8.");
            }

            foreach (string line in row)
            {
                index = 0;
                foreach (char achar in line)
                {
                    if (achar >= '0' && achar <= '9')
                    {
                        index += (int)(achar - '0');
                    }
                    else
                    {
                        if (Enums.ToPieceType(achar) != Enums.PieceType.None)
                        {
                            if (index > 7)  // This check needed here to avoid overrunning index below under some error conditions.
                            {
                                throw new ArgumentException("Invalid board specification, rank " + (dot / 8 + 1) + " has more then 8 items specified.");
                            }
                            this.SetByPosition(dot + index, achar);
                        }
                        index++;
                    }
                }

                if (index == 0) // Allow null lines = /8/
                {
                    index += 8;
                }

                if (index != 8)
                {
                    throw new ArgumentException("Invalid board specification, rank " + (dot / 8 + 1) + " has " + index + " items specified, there should be 8.");
                }

                dot += 8;
            }

            #endregion

            #region 16.1.3.2: Parse active color

            if (note.Length >= 2)
            {
                // 16.1.3.2: Parse active color
                if (note[1].Length > 0)
                {
                    char colorchar = Char.ToLower(note[1][0]);
                    if (colorchar.Equals('w') || colorchar.Equals('b'))
                    {
                        GameSide = Enums.ToGameSide(colorchar);
                    }
                    else
                    {
                        throw new ArgumentException("Invalid color designation, use w or b as 2nd field separated by spaces.");
                    }

                    if (note[1].Length != 1)
                    {
                        throw new ArgumentException("Invalid color designation, 2nd field is " + note[1].Length + " chars long, only 1 allowed.");
                    }
                }
            }

            #endregion

            #region 16.1.3.3: Parse castling availability

            if (note.Length >= 3)
            {
                foreach (char achar in note[2])
                {
                    switch (achar)
                    {
                    case 'K':
                        this.WhiteKingCastlingAvailability = true;
                        break;

                    case 'Q':
                        this.WhiteQueenCastlingAvailability = true;
                        break;

                    case 'k':
                        this.BlackKingCastlingAvailability = true;
                        break;

                    case 'q':
                        this.BlackQueenCastlingAvailability = true;
                        break;

                    case '-':
                        break;

                    default:
                        throw new Exception("Invalid castle privileges designation, use: KQkq or -");
                    }
                }
            }

            #endregion

            #region 16.1.3.4: Parse en passant target square such as "e3"
            try
            {
                if (note.Length >= 4)
                {
                    // 16.1.3.4: Parse en passant target square such as "e3"
                    if (note[3].Length == 2)
                    {
                        if (GameSide == Enums.GameSide.White)
                        {
                            if (note[3][1] != '6')
                            {
                                throw new Exception("Invalid target square for white En passant captures: " + this.EnPassantTargetPosition.ToString());
                            }
                        }
                        else
                        {
                            if (note[3][1] != '3')
                            {
                                throw new Exception("Invalid target square for black En passant captures: " + this.EnPassantTargetPosition.ToString());
                            }
                        }
                    }
                    this.EnPassantTargetPosition = Position.Parse(note[3]);
                }
            }
            catch { }
            #endregion

            #region 16.1.3.5: Parse halfmove clock, count of half-move since last pawn advance or unit capture
            try
            {
                if (note.Length >= 5)
                {
                    // 16.1.3.5: Parse halfmove clock, count of half-move since last pawn advance or unit capture
                    this.HalfMoveClock = Int16.Parse(note[4]);
                }
            }
            catch { }
            #endregion

            #region 16.1.3.6: Parse fullmove number, increment after each black move
            try
            {
                if (note.Length >= 6)
                {
                    // 16.1.3.6: Parse fullmove number, increment after each black move
                    this.FullMoveNumber = Int16.Parse(note[5]);
                }
            }
            catch { }
            #endregion
        }
Example #5
0
 /// <summary>
 /// 重写。生成该棋子的字符表示。
 /// </summary>
 /// <returns>大写表示为白棋,小写表示黑棋</returns>
 public override string ToString()
 {
     return(Enums.FromPieceType(this.PieceType));
 }