/// <summary> /// 生成文字描述。 /// </summary> public void GenerateFriendlyText() { var sb = new System.Text.StringBuilder(); sb.Append(Piece.GetFriendlyName()); sb.Append("从"); sb.Append(OriginalPosition.ToString()); sb.Append("到"); sb.Append(NewPosition.ToString()); if (IsCapture && CapturedPiece != null) { sb.Append(", 吃"); sb.Append(CapturedPiece.GetFriendlyName()); } if (Promotion.HasValue) { sb.Append(", 晋升为"); sb.Append(ChessGame.OriginalMapPgnCharToPiece(Promotion.Value, Player).GetFriendlyName()); } if (Castling.Equals(CastlingType.KingSide)) { sb.Append(", 王翼易位"); } if (Castling.Equals(CastlingType.QueenSide)) { sb.Append(", 后翼易位"); } if(IsEnpassant) { sb.Append(", 吃过路兵"); } if (IsCheckmate.HasValue && IsCheckmate.Value) { sb.Append(", 将死"); } else if (IsChecking.HasValue && IsChecking.Value) { sb.Append(", 将军"); } this._storedFriendlyText = sb.ToString(); }
/// <summary> /// 生成 SAN 字符串。 /// </summary> /// <param name="gameBeforeTheMove"></param> /// <returns></returns> public string GenerateSANString(ChessGame gameBeforeTheMove) { string SANResult; if (Castling.Equals(CastlingType.KingSide)) { SANResult = "O-O"; } else if (Castling.Equals(CastlingType.QueenSide)) { SANResult = "O-O-O"; } else { var sb = new System.Text.StringBuilder(); if (!(Piece is Pieces.Pawn)) { sb.Append(char.ToUpper(Piece.GetFenCharacter())); } Piece[][] board = gameBeforeTheMove.GetBoard(); List<Move> validMoves = new List<Move>(); for (int r = 0; r < 8; r++) { for (int f = 0; f < 8; f++) { if (board[r][f] != Piece) continue; Move m = new Move(new Position((File)f, 8 - r), this.NewPosition, this.Player, this.Promotion); if (gameBeforeTheMove.IsValidMove(m)) { validMoves.Add(m); } } } if (validMoves.Count == 0) throw new PgnException("This move " + this.ToString() + " is not valid for gameBeforeTheMove."); else if (validMoves.Count > 1) { bool fileUnique = true; bool rankUnique = true; foreach (var move in validMoves) { if(!(move.OriginalPosition.Equals(this.OriginalPosition))) { if (move.OriginalPosition.File == this.OriginalPosition.File) { fileUnique = false; } if (move.OriginalPosition.Rank == this.OriginalPosition.Rank) { rankUnique = false; } } } if (fileUnique) sb.Append((char)((int)'a' + (int)this.OriginalPosition.File)); else if (rankUnique) sb.Append(this.OriginalPosition.Rank.ToString()); else { sb.Append((char)((int)'a' + (int)this.OriginalPosition.File)); sb.Append(this.OriginalPosition.Rank.ToString()); } } if (IsCapture) sb.Append("x"); sb.Append(this.NewPosition.ToString().ToLower()); if (Promotion.HasValue) { sb.Append("="); sb.Append(Promotion.Value); } if (IsCheckmate.HasValue && IsCheckmate.Value) { sb.Append("#"); } else if (IsChecking.HasValue && IsChecking.Value) { sb.Append("+"); } SANResult = sb.ToString(); } try { ChessDotNet.PgnMoveReader.ParseMove(SANResult, Player, gameBeforeTheMove); } catch (PgnException) { throw new System.ArgumentException("This move " + SANResult + " is not valid for gameBeforeTheMove."); } catch (System.ArgumentException) { throw new System.ArgumentException("This move " + SANResult + " is not valid for gameBeforeTheMove."); } this._storedSANString = SANResult; return SANResult; }