bool PureMoveTo(IChessPoint targetPoint) { //目标棋子和当前棋子颜色不能一致 IChess targetChess = Table[targetPoint]; if (targetChess != null && targetChess.Square == this.Square) { return(false); } //是否满足规则 if (!CanMoveTo(targetPoint)) { return(false); } //吃掉对方老王 if (Table[targetPoint] is King) { Log(_currentPoint, targetPoint, true); throw new GameLoseException(this.Color == ChessColor.Red ? "红方胜" : "黑方胜"); } //移动 Table[_currentPoint] = null; //吃掉棋子或移动棋子 Table[targetPoint] = this; _lastPoint = _currentPoint; _currentPoint = targetPoint; return(true); }
/// <summary> /// Checks if a <paramref name="move"/> is legal (does not place own king under check). /// </summary> /// <typeparam name="TChess">Derived type. <paramref name="chess"/> /// must be <typeparamref name="TChess"/>.</typeparam> /// <param name="chess">A given set of <see cref="Chess"/> rules.</param> /// <param name="move">A given <see cref="Move"/>.</param> /// <returns><see langword="true"/> if the move is legal. /// Otherwise, <see langword="false"/>.</returns> /// <exception cref="ArgumentException"><paramref name="chess"/> must /// be a <typeparamref name="TChess"/> instance.</exception> public static bool IsLegal <TChess>(this IChess chess, Move move) where TChess : Chess { // Legal restraints if (!(chess is TChess)) { throw new ArgumentException( message: "Chess must be a TChess instance", paramName: nameof(chess)); } // Create a new chess state instance... IChess chessInstance = (TChess)Activator.CreateInstance( typeof(TChess), new object[] { (TChess)chess }); // Legal logic for castle if (move.Type == MoveType.Castle) { return(chessInstance.IsCastlingLegal <TChess>(move)); } // ... use it to get moved IPiece color var color = chessInstance.Position[move.FromSquare].Color; // Execute given move on instance... chessInstance.Process(move, out IPiece piece); // ... and returns wether own king is not checked return(!chessInstance.IsChecked <TChess>(color)); }
private void Start() { foreach (var description in chessDescriptions) { //initialize chesses IChess chess = null; switch (description.type) { case ChessType.oneByOne: chess = new Chess1x1(description.name, description.position); break; case ChessType.oneByTwo: chess = new Chess1x2(description.name, description.position); break; case ChessType.twoByOne: chess = new Chess2x1(description.name, description.position); break; case ChessType.twoByTwo: chess = new Chess2x2(description.name, description.position); break; default: break; } chesses.Add(description.name, chess); chess.PutToChessBoard(chessBoard); } }
/// <summary> /// Creates a new <see cref="Game"/> instance. /// </summary> /// <param name="currentMove">Sets the <see cref="Game.MoveCount"/>, /// starting at <see langword="0"/>.</param> /// <param name="currentPlayer">Sets the <see cref="Game.CurrentPlayer"/>.</param> /// <param name="rules">A given <see cref="IChess"/> instance.</param> /// <exception cref="ArgumentOutOfRangeException">If /// <paramref name="currentMove"/> is negative.</exception> public Game(int currentMove, bool currentPlayer, IChess rules) { if (currentMove < 0) { throw new ArgumentOutOfRangeException( message: "Cannot have a negative currentMove", paramName: nameof(currentMove)); } MoveCount = currentMove; CurrentPlayer = currentPlayer; Chess = rules; }
public void Run() { //stories:square do event, then table response //tom and jerry is square //tom and jerry sit at table 1 //tom ready //jerry ready //a chessing start //begin while //tom move //jerry move //if kill king or give up then chessing stop and report //end while ISquare tom = new Square(Camp.RedCamp, ChessColor.Red); ISquare jerry = new Square(Camp.BlackCamp, ChessColor.Black); tom.Logger = new LogDemo(); jerry.Logger = tom.Logger; ITable table = new ChessTable(); tom.Sit(table); jerry.Sit(table); Show(tom); Show(jerry); tom.Ready(); //table.Clear(); jerry.Ready(); //table.Start(); IChess cannon = tom.GetChess(ChessType.Cannons); IChess cannon2 = jerry.GetChess(ChessType.Cannons); var flag = false; try { flag = cannon.MoveTo(new ChessPoint(cannon.Square.Camp, 4, 2)); //2 5 flag = cannon2.MoveTo(new ChessPoint(cannon2.Square.Camp, 4, 2)); // 2 5 flag = cannon.MoveTo(new ChessPoint(cannon.Square.Camp, 4, 6)); //5 j 4 flag = cannon2.MoveTo(new ChessPoint(cannon2.Square.Camp, 4, 1)); // 2 5 flag = cannon.MoveTo(new ChessPoint(cannon.Square.Camp, 4, 9)); //5 j 4 } catch (GameLoseException ex) { Console.WriteLine(ex.Message); } //table.Stop(); //table.Report(); }
/// <summary> /// Checks if <paramref name="player"/> is currently under check. /// </summary> /// <typeparam name="TChess">Derived type. <paramref name="chess"/> /// must be <typeparamref name="TChess"/>.</typeparam> /// <param name="chess">A <see cref="Chess"/> board.</param> /// <param name="player"><see langword="true"/> for player with white pieces. Otherwise, black.</param> /// <returns><see langword="true"/> if <paramref name="player"/> is checked. /// Otherwise, <see langword="false"/>.</returns> public static bool IsChecked <TChess>(this IChess chess, bool player) where TChess : Chess { // Types of movements that might threaten a king. // A pawn may promote while threatening. var threateningMoves = new MoveType[] { MoveType.Capture, MoveType.PromoteToKnight, MoveType.PromoteToBishop, MoveType.PromoteToRook, MoveType.PromoteToQueen }.ToList(); // List of opponent's moves that might threaten the king. var enemyMoves = ((TChess)chess) .AllMoves(!player) .Where(m => threateningMoves.Contains(m.Type)) .Where(m => chess.Position.ContainsKey(m.ToSquare)) .Where(m => chess.Position[m.ToSquare] is King).ToList(); // Case enemy moves is an empty list, no piece threatens the king. return(enemyMoves.Count > 0); }
/// <summary> /// Creates a new <see cref="MockedChess"/> instance. /// </summary> /// <param name="currentMove"></param> /// <param name="currentPlayer"></param> /// <param name="rules"></param> public MockedGame(int currentMove, bool currentPlayer, IChess rules) : base(currentMove, currentPlayer, rules) { }
public void Setup() { chess = new Chess(); }
internal void SetGrid(Vector2Int grid, IChess chess) { chesses[grid.x, grid.y] = chess; }
internal ChessBoard() { chesses = new IChess[dimension.x, dimension.y]; }
/// <summary> /// Checks if castling is legal or not, for a given castles <paramref name="move"/>. /// </summary> /// <typeparam name="TChess">Derived type. <paramref name="chess"/> /// must be <typeparamref name="TChess"/>.</typeparam> /// <param name="chess">A given set of <see cref="Chess"/> rules.</param> /// <param name="move">A given <see cref="Move"/>.</param> /// <returns><see langword="true"/> if the move is legal. /// Otherwise, <see langword="false"/>.</returns> private static bool IsCastlingLegal <TChess>(this IChess chess, Move move) where TChess : Chess { // Get the castling king var king = chess.Position[move.FromSquare]; // Castle can't occur when king is checked if (chess.IsChecked <TChess>(king.Color)) { return(false); } // Define the type of castle var kingSideCastle = move.ToSquare.File == Files.g; // Determines the rook squares var rookFromSquare = new Square( kingSideCastle ? Files.h : Files.a, move.FromSquare.Rank ); var rookToSquare = new Square( kingSideCastle ? Files.f : Files.d, move.ToSquare.Rank ); // Remove rook ((Chess)chess).RemovePiece(rookFromSquare, out IPiece rook); // Get all squares between fromSquare and toSquare var currentSquare = new Square(move.FromSquare); var kingSquares = Helper .InBetweenSquares(move.FromSquare, move.ToSquare) .ToList() .Append(move.ToSquare) .ToList(); // Loop and test for checks foreach (var square in kingSquares) { // Move king along the castling path... if (!chess.Process( new Move( currentSquare, square, MoveType.Normal), out IPiece p)) { return(false); } // ... and check for checks. if (chess.IsChecked <TChess>(king.Color)) { return(false); } currentSquare = new Square(square); } // Put rook at his destination square ((Chess)chess).PlaceAt(rookToSquare, rook); return(true); }