Пример #1
0
        public int GetStatus()
        {
            foreach (var blackPiece in blacks)
            {
                // Fill a map of danger.
                List <List <Point> > paths = blackPiece.GetPaths();

                foreach (var path in paths)
                {
                    // For each possible path (geometrically, to the border)
                    // fill dangerous cells in blackDanger

                    IPiece whitePiece = null;
                    bool   dangerous  = true;
                    for (int i = 1; i < path.Count; ++i)
                    {
                        if (dangerous)
                        {
                            blackDanger[path[i].X, path[i].Y] = true;
                        }

                        IPiece piece = GetPiece(path[i].X, path[i].Y);

                        if (piece != null)
                        {
                            if (piece.Black)
                            {
                                break;
                            }

                            if (piece == WhiteKing)
                            {
                                // If we've met the white king, add path as a threat to him
                                if (dangerous)
                                {
                                    WhiteKing.AddThreat(new Threat(path, i));
                                }

                                // If there is only one white piece protecting the white king from this black piece,
                                // add path as a threat to it
                                if (whitePiece != null)
                                {
                                    whitePiece.AddThreat(new Threat(path, i));
                                }
                                break;
                            }

                            dangerous = false;

                            if (whitePiece == null)
                            {
                                whitePiece = piece;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }

            if (IsDangerousForWhite(WhiteKing.X, WhiteKing.Y))
            {
                if (WhiteKing.CanMove())
                {
                    // If the white king is on a dangerous cell, but he can make a move, that's check.
                    return(Check);
                }

                if (WhiteKing.Threats.Count > 1)
                {
                    // If he can't move and there's more than one threat to him, that's mate.
                    return(Mate);
                }

                // There's one threat.
                foreach (var piece in whites)
                {
                    // For each white piece check if it can eliminate the threat
                    if (WhiteKing.Threats[0].CellsToEliminate.Any(p => piece.CanMoveTo(p.X, p.Y)))
                    {
                        return(Check);
                    }
                }

                // If nobody can help, that's mate.
                return(Mate);
            }

            // Check for stalemate.

            // If there's a white piece, that can move, that's OK.
            if (whites.Any(piece => piece.CanMove()))
            {
                return(Ok);
            }

            // Otherwise, that's stalemate.
            return(Stalemate);
        }