예제 #1
0
        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);
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
    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);
        }
    }
예제 #4
0
        /// <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;
        }
예제 #5
0
        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();
        }
예제 #6
0
        /// <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);
        }
예제 #7
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)
 {
 }
예제 #8
0
 public void Setup()
 {
     chess = new Chess();
 }
예제 #9
0
 internal void SetGrid(Vector2Int grid, IChess chess)
 {
     chesses[grid.x, grid.y] = chess;
 }
예제 #10
0
 internal ChessBoard()
 {
     chesses = new IChess[dimension.x, dimension.y];
 }
예제 #11
0
        /// <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);
        }