Ejemplo n.º 1
0
 public move(piece p, square s)
 {
     movablePiece = p;
     targetSquare = s;
 }
Ejemplo n.º 2
0
        //function that handles end of turn and calculation of the new turn
        //called after a player has made his move => switch sides
        //TODO
        private void endTurn()
        {
            var colorDark     = Color.DarkGray;
            var colorLight    = Color.White;
            var colorSelected = Color.OrangeRed;
            var colorMovable  = Color.DarkSeaGreen;

            turnCount++;
            //change turn owner
            if (turn == "white")
            {
                turn = "black";
            }
            else
            {
                turn = "white";
            }
            legalMoves = new List <move>();
            //this handles the mask calculation
            masks.calculateCheckers();
            //deselect piece and reset the board colors
            selectedPiece = null;
            foreach (square s in squareArray)
            {
                Panel workingPanel = _chessBoardPanels[s.xPosition, s.yPosition];
                if ((workingPanel.Location.X / tileSize) % 2 == 0)
                {
                    workingPanel.BackColor = (workingPanel.Location.Y / tileSize) % 2 != 0 ? colorDark : colorLight;
                }
                else
                {
                    workingPanel.BackColor = (workingPanel.Location.Y / tileSize) % 2 != 0 ? colorLight : colorDark;
                }
            }

            //calculate new move list
            pins.calculatePins();
            core.calculateMoves();

            //conditions for end of the game
            if (legalMoves.Count == 0 && masks.checkerCount == 0)
            {
                //game ends in a draw
                gameOver("draw");
            }
            else if (legalMoves.Count == 0 && masks.checkerCount > 0)
            {
                //the opponent wins
                if (turn == "white")
                {
                    gameOver("black");
                }
                else
                {
                    gameOver("white");
                }
            }
            //uncomment for debugging of masks - currently works(maybe?)

            /*for(int i = 0; i < 8; i++)
             * {
             *  for(int j = 0; j < 8; j++)
             *  {
             *      if (masks.kingDangerMask[i, j]) _chessBoardPanels[i, j].BackColor = Color.Blue;
             *  }
             * }*/
        }
Ejemplo n.º 3
0
 public square(int x, int y)
 {
     this.xPosition = x;
     this.yPosition = y;
     here           = null;
 }
Ejemplo n.º 4
0
        //TODO
        //handler of the player clicking a square on the board
        private void boardClickHandler(object sender, EventArgs e)
        {
            var colorDark     = Color.DarkGray;
            var colorLight    = Color.White;
            var colorSelected = Color.OrangeRed;
            var colorMovable  = Color.DarkSeaGreen;

            Panel clickedPanel = (Panel)sender;
            //the piece the player tried to click (can be null! = clicked an empty square)
            piece  clickedPiece  = squareArray[clickedPanel.Location.X / tileSize, clickedPanel.Location.Y / tileSize].here;
            square clickedSquare = squareArray[clickedPanel.Location.X / tileSize, clickedPanel.Location.Y / tileSize];

            //selecting squares works
            //TODO - check for present pieces
            //TODO - check of other selected squares - global variable?

            //dummy for debugging the game board - uncomment to use

            /*if(clickedPanel.BackColor == colorSelected)
             * {
             *  if ((clickedPanel.Location.X / tileSize) % 2 == 0)
             *      clickedPanel.BackColor = (clickedPanel.Location.Y / tileSize) % 2 != 0 ? colorDark : colorLight;
             *  else
             *      clickedPanel.BackColor = (clickedPanel.Location.Y / tileSize) % 2 != 0 ? colorLight : colorDark;
             * }
             * else clickedPanel.BackColor = colorSelected;*/


            //if it's the first turn of the game, end turn to evaluate moves for pieces
            if (firstMove)
            {
                firstMove = false;
                endTurn();
                if (board.mode == "Play versus A.I." && turn != playerfaction)
                {
                    move aiMove = ai_core.getMove();
                    //simulate the ai clicking on the board to make the move
                    boardClickHandler(_chessBoardPanels[aiMove.movablePiece.xPosition, aiMove.movablePiece.yPosition], null);
                    boardClickHandler(_chessBoardPanels[aiMove.targetSquare.xPosition, aiMove.targetSquare.yPosition], null);
                }
            }

            if (clickedPiece == null && selectedPiece == null) //player clicked meaninglessly
            {
                //do nothing
            }
            //the player attempted to select a piece while not having one selected
            else if (selectedPiece == null)          //clicked piece can NOT be null
            {
                if (clickedPiece.pieceColor == turn) //the player clicked his own piece (selected)
                {
                    selectedPiece  = clickedPiece;
                    movableSquares = new List <square>();
                    foreach (move m in legalMoves)
                    {
                        if (m.movablePiece == selectedPiece)
                        {
                            movableSquares.Add(m.targetSquare);
                        }
                    }
                    //update the gameboard with movable squares (in green)
                    _chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].BackColor = colorSelected;
                    foreach (square s in movableSquares)
                    {
                        _chessBoardPanels[s.xPosition, s.yPosition].BackColor = colorMovable;
                    }
                }
                //else do nothing - the player tried to select the enemy piece
            }
            //the player attempted to deselect a piece
            else if ((clickedPiece == null && !(movableSquares.Contains(clickedSquare))) || (clickedPiece == selectedPiece))
            {
                //deselect the selected piece
                if ((_chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].Location.X / tileSize) % 2 == 0)
                {
                    _chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].BackColor = (_chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].Location.Y / tileSize) % 2 != 0 ? colorDark : colorLight;
                }
                else
                {
                    _chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].BackColor = (_chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].Location.Y / tileSize) % 2 != 0 ? colorLight : colorDark;
                }
                selectedPiece = null;
                //update the board to deselect the pieces in color
                foreach (square s in movableSquares)
                {
                    Panel workingPanel = _chessBoardPanels[s.xPosition, s.yPosition];
                    if ((workingPanel.Location.X / tileSize) % 2 == 0)
                    {
                        workingPanel.BackColor = (workingPanel.Location.Y / tileSize) % 2 != 0 ? colorDark : colorLight;
                    }
                    else
                    {
                        workingPanel.BackColor = (workingPanel.Location.Y / tileSize) % 2 != 0 ? colorLight : colorDark;
                    }
                }
                movableSquares = null;
            }
            //the player selected one of his other pieces while having one selected already
            else if (selectedPiece != null && clickedPiece != null && clickedPiece.pieceColor == turn)
            {
                //deselect the selected piece
                if ((_chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].Location.X / tileSize) % 2 == 0)
                {
                    _chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].BackColor = (_chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].Location.Y / tileSize) % 2 != 0 ? colorDark : colorLight;
                }
                else
                {
                    _chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].BackColor = (_chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].Location.Y / tileSize) % 2 != 0 ? colorLight : colorDark;
                }
                selectedPiece = null;
                //update the board to deselect the pieces in color
                foreach (square s in movableSquares)
                {
                    Panel workingPanel = _chessBoardPanels[s.xPosition, s.yPosition];
                    if ((workingPanel.Location.X / tileSize) % 2 == 0)
                    {
                        workingPanel.BackColor = (workingPanel.Location.Y / tileSize) % 2 != 0 ? colorDark : colorLight;
                    }
                    else
                    {
                        workingPanel.BackColor = (workingPanel.Location.Y / tileSize) % 2 != 0 ? colorLight : colorDark;
                    }
                }
                movableSquares = null;

                //now select the new piece
                selectedPiece  = clickedPiece;
                movableSquares = new List <square>();
                foreach (move m in legalMoves)
                {
                    if (m.movablePiece == selectedPiece)
                    {
                        movableSquares.Add(m.targetSquare);
                    }
                }
                //update the gameboard with movable squares (in green)
                _chessBoardPanels[selectedPiece.xPosition, selectedPiece.yPosition].BackColor = colorSelected;
                foreach (square s in movableSquares)
                {
                    _chessBoardPanels[s.xPosition, s.yPosition].BackColor = colorMovable;
                }
            }
            //the player performed a move (or a take)
            else if (selectedPiece != null && movableSquares.Contains(clickedSquare))
            {
                selectedPiece.move(clickedSquare);
                endTurn();

                //handler for the A.I. to make a move
                if (board.mode == "Play versus A.I." && turn != playerfaction)
                {
                    move aiMove = ai_core.getMove();
                    //simulate the ai clicking on the board to make the move
                    boardClickHandler(_chessBoardPanels[aiMove.movablePiece.xPosition, aiMove.movablePiece.yPosition], null);
                    boardClickHandler(_chessBoardPanels[aiMove.targetSquare.xPosition, aiMove.targetSquare.yPosition], null);
                }
            }
        }
Ejemplo n.º 5
0
        public static void calculateMoves()
        {
            //king moves are calculated first - if there is a double check, the rest doesn't need to be calculated
            piece playerKing = null;

            if (board.turn == "white")
            {
                playerKing = board.whitePieces.Find(p => p.pieceType == "king");
            }
            else
            {
                playerKing = board.blackPieces.Find(p => p.pieceType == "king");
            }
            bool currentPinned = false; pin currentPin = null;

            List <square> kingSquares = playerKing.getLegalMoves();

            foreach (square s in kingSquares)
            {
                board.legalMoves.Add(new move(playerKing, s));
            }
            //double check - only legal moves are to move the king
            if (masks.checkerCount >= 2)
            {
                return;
            }
            //single check - can move, block or capture checker
            //TODO: pinned pieces
            else if (masks.checkerCount == 1)
            {
                List <piece> pcs = null;
                if (board.turn == "white")
                {
                    pcs = board.whitePieces;
                }
                else
                {
                    pcs = board.blackPieces;
                }
                List <square> consideredMoves = null;

                foreach (piece p in pcs)
                {
                    //if the piece is pinned, give it special treatment
                    if (pins.existingPins.Exists(pi => pi.pinnedPiece == p))
                    {
                        currentPinned = true;
                        currentPin    = pins.existingPins.Find(pi => pi.pinnedPiece == p);
                    }
                    consideredMoves = p.getLegalMoves();
                    foreach (square s in consideredMoves)
                    {
                        //if the piece is not pinned, proceed normally
                        if (!currentPinned)
                        {
                            //move is only valid in check if it conincides with the pushmask or the capturemask
                            if (masks.captureMask[s.xPosition, s.yPosition] || masks.pushMask[s.xPosition, s.yPosition])
                            {
                                board.legalMoves.Add(new move(p, s));
                            }
                        }
                        else
                        {
                            //move has to coincide with the pin rules in addition to the pushmask or capturemask
                            if ((masks.captureMask[s.xPosition, s.yPosition] || masks.pushMask[s.xPosition, s.yPosition]) &&
                                (currentPin.pushSquares.Exists(sq => sq == s) || currentPin.takeSquares.Exists(sq => sq == s)))
                            {
                                board.legalMoves.Add(new move(p, s));
                            }
                        }
                    }
                    currentPin    = null;
                    currentPinned = false;
                }
                //no other moves are valid except for king moves, blocks or checker captures
                return;
            }
            //no check is in play - calculate moves like normal
            //pins.cs handles the calculation of pins
            //TODO: pinned pieces(separately)
            else
            {
                List <piece> pcs = null;
                if (board.turn == "white")
                {
                    pcs = board.whitePieces;
                }
                else
                {
                    pcs = board.blackPieces;
                }
                List <square> consideredMoves = null;

                foreach (piece p in pcs)
                {
                    //separate behavior for pinned pieces
                    if (pins.existingPins.Exists(pi => pi.pinnedPiece == p))
                    {
                        currentPinned = true;
                        currentPin    = pins.existingPins.Find(pi => pi.pinnedPiece == p);
                    }
                    consideredMoves = p.getLegalMoves();
                    foreach (square s in consideredMoves)
                    {
                        //normal behavior
                        if (!currentPinned)
                        {
                            board.legalMoves.Add(new move(p, s));
                        }
                        else
                        {
                            if (currentPin.pushSquares.Exists(sq => sq == s) || currentPin.takeSquares.Exists(sq => sq == s))
                            {
                                board.legalMoves.Add(new move(p, s));
                            }
                        }
                    }
                    currentPin    = null;
                    currentPinned = false;
                }
            }
        }
Ejemplo n.º 6
0
 public pin(piece p, List <square> take, List <square> push)
 {
     pinnedPiece = p;
     takeSquares = take;
     pushSquares = push;
 }
Ejemplo n.º 7
0
        //figures out which pieces are pinned and puts them in pinnedPieces list
        public static void calculatePins()
        {
            existingPins = new List <pin>();
            //reference to the player's king
            piece playerKing = null;

            if (board.turn == "white")
            {
                playerKing = board.whitePieces.Find(p => p.pieceType == "king");
            }
            else
            {
                playerKing = board.blackPieces.Find(p => p.pieceType == "king");
            }

            //pins are calculates in 8 directions
            //a search starts in a direction from the king - it "xrays" a friendly piece once and marks it as a candidate for a pin
            //if the search finds an enemy candidate for a pinner after the xray, the pinned piece is marked
            //the search ends unsuccesfully if multiple friendly pieces are hit in a row, if an unfit pinner candidate is found or if the edge of the board is hit

            int           i = playerKing.xPosition; int j = playerKing.yPosition;
            bool          xrayed = false; bool foundPin = false;
            List <square> potentialPush = new List <square>();
            List <square> potentialTake = new List <square>();
            piece         pinCandidate  = null;

            //up
            j = playerKing.yPosition - 1;
            while (j >= 0)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "rook" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                j--;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }

            //right
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            i             = playerKing.xPosition + 1;
            while (i < 8)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "rook" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                i++;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }

            //down
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            j             = playerKing.xPosition + 1;
            while (j < 8)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "rook" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                j++;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }

            //left
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            i             = playerKing.xPosition - 1;
            while (i >= 0)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "rook" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                i--;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }


            //"rook" pins are done(working properly), now the diagonal "bishop" pins
            //TODO

            //top right
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            i             = playerKing.xPosition + 1; j = playerKing.yPosition - 1;
            while (i < 8 && j >= 0)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "bishop" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                i++; j--;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }

            //bottom right
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            i             = playerKing.xPosition + 1; j = playerKing.yPosition + 1;
            while (i < 8 && j < 8)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "bishop" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                i++; j++;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }

            //bottom left
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            i             = playerKing.xPosition - 1; j = playerKing.yPosition + 1;
            while (j < 8 && i >= 0)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "bishop" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                i--; j++;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }

            //top left
            i             = playerKing.xPosition; j = playerKing.yPosition;
            xrayed        = false; foundPin = false;
            potentialPush = new List <square>();
            potentialTake = new List <square>();
            pinCandidate  = null;
            i             = playerKing.xPosition - 1; j = playerKing.yPosition - 1;
            while (i >= 0 && j >= 0)
            {
                //nothing there - add to potential moves for pinned piece on this line
                if (board.squareArray[i, j].here == null)
                {
                    potentialPush.Add(board.squareArray[i, j]);
                }
                else
                {
                    //xray the friendly piece and make it a candidate
                    if (!xrayed && board.squareArray[i, j].here.pieceColor == board.turn)
                    {
                        xrayed       = true;
                        pinCandidate = board.squareArray[i, j].here;
                    }
                    //we found the pinning piece
                    else if (xrayed && (board.squareArray[i, j].here.pieceType == "bishop" || board.squareArray[i, j].here.pieceType == "queen") &&
                             board.squareArray[i, j].here.pieceColor != board.turn)
                    {
                        potentialTake.Add(board.squareArray[i, j]);
                        foundPin = true;
                        break;
                    }
                    //we found something else => the search was not successful, there is no pin here
                    else
                    {
                        break;
                    }
                }
                i--; j--;
            }
            //if we found a pin, save it
            if (foundPin)
            {
                existingPins.Add(new pin(pinCandidate, potentialTake, potentialPush));
            }
        }
Ejemplo n.º 8
0
        //calculates how many pieces are in check for the player and creates the masks
        public static void calculateCheckers()
        {
            //init of masks
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    kingDangerMask[i, j] = false;
                    captureMask[i, j]    = false;
                    pushMask[i, j]       = false;
                    checkingMask[i, j]   = false;
                }
            }
            checkerCount = 0;

            //pointer to the player's king (for ease of reading)
            piece playerKing;

            if (board.turn == "white")
            {
                playerKing = board.whitePieces.Find(p => p.pieceType == "king");
            }
            else
            {
                playerKing = board.blackPieces.Find(p => p.pieceType == "king");
            }

            //first calculate the danger squares
            if (board.turn == "white")
            {
                foreach (piece p in board.blackPieces)
                {
                    if (p.pieceType == "pawn")
                    {
                        if (p.xPosition - 1 >= 0)
                        {
                            kingDangerMask[p.xPosition - 1, p.yPosition + 1] = true;
                            if (board.squareArray[p.xPosition - 1, p.yPosition + 1].here != null &&
                                board.squareArray[p.xPosition - 1, p.yPosition + 1].here.pieceType == "king" &&
                                board.squareArray[p.xPosition - 1, p.yPosition + 1].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                        if (p.xPosition + 1 < 8)
                        {
                            kingDangerMask[p.xPosition + 1, p.yPosition + 1] = true;
                            if (board.squareArray[p.xPosition + 1, p.yPosition + 1].here != null &&
                                board.squareArray[p.xPosition + 1, p.yPosition + 1].here.pieceType == "king" &&
                                board.squareArray[p.xPosition + 1, p.yPosition + 1].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "knight")
                    {
                        List <square> m = utils.knightMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "bishop")
                    {
                        List <square> m = utils.bishopDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "rook")
                    {
                        List <square> m = utils.rookDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "queen")
                    {
                        //treat the queen like a rook + bishop
                        List <square> m = utils.bishopDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                        m = utils.rookDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "king")
                    {
                        List <square> m = utils.kingDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                        }
                    }
                }
            }
            else if (board.turn == "black")
            {
                foreach (piece p in board.whitePieces)
                {
                    if (p.pieceType == "pawn")
                    {
                        if (p.xPosition - 1 >= 0)
                        {
                            kingDangerMask[p.xPosition - 1, p.yPosition - 1] = true;
                            if (board.squareArray[p.xPosition - 1, p.yPosition - 1].here != null &&
                                board.squareArray[p.xPosition - 1, p.yPosition - 1].here.pieceType == "king" &&
                                board.squareArray[p.xPosition - 1, p.yPosition - 1].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                        if (p.xPosition + 1 < 8)
                        {
                            kingDangerMask[p.xPosition + 1, p.yPosition - 1] = true;
                            if (board.squareArray[p.xPosition + 1, p.yPosition - 1].here != null &&
                                board.squareArray[p.xPosition + 1, p.yPosition - 1].here.pieceType == "king" &&
                                board.squareArray[p.xPosition + 1, p.yPosition - 1].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "knight")
                    {
                        List <square> m = utils.knightMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "bishop")
                    {
                        List <square> m = utils.bishopDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "rook")
                    {
                        List <square> m = utils.rookDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "queen")
                    {
                        //treat the queen like a rook + bishop
                        List <square> m = utils.bishopDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                        m = utils.rookDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                            if (board.squareArray[s.xPosition, s.yPosition].here != null &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceType == "king" &&
                                board.squareArray[s.xPosition, s.yPosition].here.pieceColor == board.turn)
                            {
                                checkingMask[p.xPosition, p.yPosition] = true;
                                checkerCount++;
                            }
                        }
                    }
                    else if (p.pieceType == "king")
                    {
                        List <square> m = utils.kingDangerMoves(board.squareArray[p.xPosition, p.yPosition]);
                        foreach (square s in m)
                        {
                            kingDangerMask[s.xPosition, s.yPosition] = true;
                        }
                    }
                }
            }

            //now the king danger squares are calculated - we know where the king can't move because that square is attacked
            //we know which squares have pieces that are GIVING CHECK to the player's king
            //we also know the number of pieces giving check to the player's king
            //if checkerCount >= 2 then the only legal moves are king moves to safe squares
            //if checkerCount == 1 then we have 3 options
            //  -move the king out of check
            //  -capture the checking piece
            //  -block the checking piece

            //we have to move the king => no capture is valid
            if (checkerCount >= 2)
            {
                for (int i = 0; i < 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        captureMask[i, j] = false;
                    }
                }
            }
            //we can evade the single check by capturing the piece
            if (checkerCount == 1)
            {
                captureMask = checkingMask;
            }

            //now the push mask - will include squares that we can move a piece to in order to block a single check
            //with double checks, check can't be blocked => mask is false
            if (checkerCount >= 2)
            {
                for (int i = 0; i < 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        pushMask[i, j] = false;
                    }
                }
            }

            piece checkingPiece = null;

            //if single check, then there is only one "true" on the checkingMask - find it to find the checking piece
            if (checkerCount == 1)
            {
                for (int i = 0; i < 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        if (checkingMask[i, j] == true) //we found the only checking piece
                        {
                            checkingPiece = board.squareArray[i, j].here;
                        }
                    }
                }

                //if it's a "slider" piece, find squares where we can block the check - between the piece and the king
                if (checkingPiece.pieceType == "rook" || checkingPiece.pieceType == "queen" || checkingPiece.pieceType == "bishop")
                {
                    List <square> pieceSlider = null;
                    List <square> kingSlider  = null;
                    if (checkingPiece.pieceType == "rook" ||
                        checkingPiece.pieceType == "queen")
                    {
                        pieceSlider = utils.rookSliderMoves(board.squareArray[checkingPiece.xPosition, checkingPiece.yPosition]);
                        kingSlider  = utils.rookSliderMoves(board.squareArray[playerKing.xPosition, playerKing.yPosition]);
                        //overlap the two sliders in a 2 dimensional array to get the squares where blocking is possible
                        int[,] overlap = new int[8, 8];
                        for (int i = 0; i < 8; i++)
                        {
                            for (int j = 0; j < 8; j++)
                            {
                                overlap[i, j] = 0;
                            }
                        }

                        foreach (square s in kingSlider)
                        {
                            overlap[s.xPosition, s.yPosition]++;
                        }
                        foreach (square s in pieceSlider)
                        {
                            overlap[s.xPosition, s.yPosition]++;
                        }
                        //if both pieces "saw" the square => add it to the pushMask
                        for (int i = 0; i < 8; i++)
                        {
                            for (int j = 0; j < 8; j++)
                            {
                                if (overlap[i, j] == 2)
                                {
                                    pushMask[i, j] = true;
                                }
                            }
                        }
                    }

                    if (checkingPiece.pieceType == "bishop" ||
                        checkingPiece.pieceType == "queen")
                    {
                        pieceSlider = utils.bishopSliderMoves(board.squareArray[checkingPiece.xPosition, checkingPiece.yPosition]);
                        kingSlider  = utils.bishopSliderMoves(board.squareArray[playerKing.xPosition, playerKing.yPosition]);
                        //overlap the two sliders in a 2 dimensional array to get the squares where blocking is possible
                        int[,] overlap = new int[8, 8];
                        for (int i = 0; i < 8; i++)
                        {
                            for (int j = 0; j < 8; j++)
                            {
                                overlap[i, j] = 0;
                            }
                        }

                        foreach (square s in kingSlider)
                        {
                            overlap[s.xPosition, s.yPosition]++;
                        }
                        foreach (square s in pieceSlider)
                        {
                            overlap[s.xPosition, s.yPosition]++;
                        }
                        //if both pieces "saw" the square => add it to the pushMask
                        for (int i = 0; i < 8; i++)
                        {
                            for (int j = 0; j < 8; j++)
                            {
                                if (overlap[i, j] == 2)
                                {
                                    pushMask[i, j] = true;
                                }
                            }
                        }
                    }
                }
            }

            //now both the push mask and the capture mask is DONE
            //TODO: pinned pieces
        }