package chess2;
import java.util.ArrayList;
public class ChessPiece implements ChessConstants{

    protected Side side;
    protected Side opponentSide;
    protected int xPos;
    protected int yPos;
    protected int projXPos1, projYPos1, projXPos2, projYPos2;
    boolean isAlive;
    protected ChessBoard yourBoard;
    protected ChessGame game;
    boolean inTank = false;
    boolean suffocated=false;
    public ChessPiece(){

    }
    public ChessPiece(Side SIDE, int XPOS, int YPOS, ChessBoard YOURBOARD, ChessGame GAME){
        side = SIDE;
        xPos = XPOS;
        yPos = YPOS;
        isAlive = true;
        yourBoard = YOURBOARD;
        if (side==Side.BLACK){
            opponentSide = Side.WHITE;
        }
        else{
            opponentSide = Side.BLACK;
        }
        game = GAME;

    }
    public ChessPiece(Side SIDE, int PROJXPOS1, int PROJYPOS1, int PROJXPOS2, int PROJYPOS2, ChessBoard YOURBOARD, ChessGame GAME){
        side = SIDE;
        projXPos1 = PROJXPOS1;
        projYPos1 = PROJYPOS1;
        projXPos2 = PROJXPOS2;
        projYPos2 = PROJYPOS2;
        isAlive = true;
        yourBoard = YOURBOARD;
        if (side==Side.BLACK){
            opponentSide = Side.WHITE;
        }
        else{
            opponentSide = Side.BLACK;
        }
        game = GAME;

    }
    public Projectile getFiringDirection(int XPOS,int YPOS){

        if (YPOS==projYPos1&&YPOS==projYPos2){
            return Projectile.HORIZONTAL;
        }
        if (YPOS!=projYPos1&&YPOS!=projYPos2&&(XPOS==projXPos1||XPOS==projXPos2)){
            return Projectile.VERTICAL;
        }

        if ((Math.abs(projYPos1-YPOS)==Math.abs(projXPos1-XPOS))||
                (Math.abs(projYPos2-YPOS)==Math.abs(projXPos2-XPOS))){
            return Projectile.DIAGONAL;
        }

        return null;
    }
    public void setSide(Side SIDE){
        side = SIDE;
        if (side==Side.BLACK){
            opponentSide = Side.WHITE;
        }
        else{
            opponentSide = Side.BLACK;
        }
    }
    public boolean occupies(int XPOS, int YPOS){
        if (xPos==XPOS&&yPos==YPOS){
            return true;
        }
        return false;
    }
    public ArrayList<Decision> possibleDecisions(){
        return null;
    }
    public boolean inChapel(){
        if (projYPos1!=0||projXPos1!=0||projYPos2!=0||projXPos2!=0){
            return inChapel(projXPos1, projYPos1);
        }
        return inChapel(xPos, yPos);
    }
    public boolean inChapel(int XPOS, int YPOS){
        if (game!=ChessGame.PEASANT){
            return false;
        }
        if (XPOS==C||XPOS==F){
            if (YPOS==_4||YPOS==_5){
                return true;
            }
        }
        return false;
    }
    public boolean canMarry(int XPOS, int YPOS){
        if (inTank){
            return false;
        }
        if (!(yourBoard.sideOccupyingSquare(XPOS, YPOS)==opponentSide)){
            return false;
        }
        if (yourBoard.getCorpse(XPOS, YPOS)!=null||yourBoard.getMonkey(XPOS, YPOS)!=null||yourBoard.getTank(XPOS, YPOS)!=null||yourBoard.getRook(XPOS, YPOS)!=null||
                yourBoard.pieceOccupyingSquare(xPos, yPos)==yourBoard.pieceOccupyingSquare(XPOS, YPOS)){
            for (int i=0;i<yourBoard.bishops.size();i++){
                if (yourBoard.bishops.get(i).side==side){
                    return false;
                }
            }
            boolean hasModernPriest = false;
            for (int i=0;i<yourBoard.wildCards.size();i++){
                if (yourBoard.wildCards.get(i).side==side){
                    hasModernPriest = true;
                }
            }
            if (!hasModernPriest){
                return false;
            }
        }
        if (inChapel()){
            if (Math.abs(XPOS-xPos)<=100&&Math.abs(YPOS-yPos)<=100){return true;}
        }
        return false;
    }
    public boolean onPermWall(){
        return onPermWall(xPos, yPos);
    }
    public boolean onPermWall(int XPOS, int YPOS){
        if (game!=ChessGame.PEASANT){
            return false;
        }
        if (XPOS==B||XPOS==G){
            if (YPOS==_4||YPOS==_5){
                return true;
            }
        }
        return false;
    }
    public boolean inDisco(){
        return inDisco(xPos, yPos);
    }
    public boolean inDisco(int XPOS, int YPOS){
        if (game!=ChessGame.PEASANT){
            return false;
        }
        if (XPOS==A||XPOS==H){
            if (YPOS==_4||YPOS==_5){
                return true;
            }
        }
        return false;
    }
    public boolean inToaster(Side SIDE){
        if (SIDE==Side.WHITE){
            return inWhiteToaster(xPos, yPos);
        }
        else{
            return inBlackToaster(xPos, yPos);
        }
    }

    public boolean inWhiteToaster(){
        return inWhiteToaster(xPos, yPos);
    }
    public boolean inWhiteToaster(int XPOS, int YPOS){
        if (!(game==ChessGame.PEASANT||game==ChessGame.MONKEY)){
            return false;
        }
        if (XPOS==D||XPOS==E){
            if (YPOS==_2){
                return true;
            }
        }
        return false;
    }
    public boolean inBlackToaster(){
        return inBlackToaster(xPos, yPos);
    }
    public boolean inBlackToaster(int XPOS, int YPOS){
        if (!(game==ChessGame.PEASANT||game==ChessGame.MONKEY)){
            return false;
        }
        if (XPOS==D||XPOS==E){
            if (YPOS==_7){
                return true;
            }
        }
        return false;
    }
      public boolean inBarrel(){
        return inBarrel(xPos, yPos);
    }
    public boolean inBarrel(int XPOS, int YPOS){
        if (game==ChessGame.NORMAL||game==ChessGame.ADULTERY){
            return false;
        }
        if (XPOS==D||XPOS==E){
            if (YPOS==_4||YPOS==_5){
                return true;
            }
        }
        return false;
    }
    public boolean Loaded(){
        if (yourBoard.sideOccupyingSquare(projXPos1, projYPos1)!=Side.NONE){return true; }
        if (yourBoard.sideOccupyingSquare(projXPos2, projYPos2)!=Side.NONE){return true; }
        return false;
    }

    public boolean inRangeOfBoard(int XPOS, int YPOS){
        if (YPOS<=_1&&YPOS>=_8&&XPOS>=A&&XPOS<=H){
            return true;
        }
        return false;
    }
    public boolean canMoveTo(int XPOS, int YPOS){
        return false;
    }
    public boolean canMoveUpTo(int XPOS, int YPOS){
        if (!(xPos==XPOS&&YPOS<yPos)){
            return false;
        }
        return canMoveInLineTo(XPOS, YPOS, 8);
    }
     public boolean canMoveUpTo(int XPOS, int YPOS, int DISTANCE){
         if (!(xPos==XPOS&&YPOS<yPos)){
            return false;
         }
         return canMoveInLineTo(XPOS, YPOS, DISTANCE);
    }
     public boolean canAttackUpTo(int XPOS, int YPOS){
         if (!(xPos==XPOS&&YPOS<yPos)){
            return false;
            }
        return canAttackInLineTo(XPOS, YPOS, 8);
    }
     public boolean canAttackUpTo(int XPOS, int YPOS, int DISTANCE){
         if (!(xPos==XPOS&&YPOS<yPos)){
            return false;
            }
         return canAttackInLineTo(XPOS, YPOS, DISTANCE);
    }
     public boolean canMoveDownTo(int XPOS, int YPOS){
         if (!(xPos==XPOS&&YPOS>yPos)){
            return false;
            }
         return canMoveInLineTo(XPOS, YPOS, 8);
    }
     public boolean canMoveDownTo(int XPOS, int YPOS, int DISTANCE){
         if (!(xPos==XPOS&&YPOS>yPos)){
            return false;
            }
         return canMoveInLineTo(XPOS, YPOS, DISTANCE);
    }
      public boolean canAttackDownTo(int XPOS, int YPOS){
          if (!(xPos==XPOS&&YPOS>yPos)){
            return false;
            }
        return canAttackInLineTo(XPOS, YPOS, 8);
    }
       public boolean canAttackDownTo(int XPOS, int YPOS, int DISTANCE){
           if (!(xPos==XPOS&&YPOS>yPos)){
            return false;
            }
        return canAttackInLineTo(XPOS, YPOS, DISTANCE);
    }
    public boolean canMoveLeftTo(int XPOS, int YPOS){
        if (!(XPOS<xPos&&YPOS==yPos)){
            return false;
        }
        return canMoveInLineTo(XPOS, YPOS, 8);
    }
    public boolean canMoveLeftTo(int XPOS, int YPOS, int DISTANCE){
        if (!(XPOS<xPos&&YPOS==yPos)){
            return false;
        }
        return canMoveInLineTo(XPOS, YPOS, DISTANCE);
    }
    public boolean canAttackLeftTo(int XPOS, int YPOS){
        if (!(XPOS<xPos&&YPOS==yPos)){
            return false;
        }
        return canAttackInLineTo(XPOS, YPOS, 8);
    }
     public boolean canAttackLeftTo(int XPOS, int YPOS, int DISTANCE){
         if (!(XPOS<xPos&&YPOS==yPos)){
            return false;
         }
         return canAttackInLineTo(XPOS, YPOS, DISTANCE);
    }
    public boolean canMoveRightTo(int XPOS, int YPOS){
        if (!(XPOS>xPos&&YPOS==yPos)){
            return false;
        }
        return canMoveInLineTo(XPOS, YPOS, 8);
    }
    public boolean canMoveRightTo(int XPOS, int YPOS, int DISTANCE){
        if (!(XPOS>xPos&&YPOS==yPos)){
            return false;
        }
        return canMoveInLineTo(XPOS, YPOS, DISTANCE);
    }
    public boolean canAttackRightTo(int XPOS, int YPOS){
        if (!(XPOS>xPos&&YPOS==yPos)){
            return false;
        }
        return canAttackInLineTo(XPOS, YPOS, 8);
    }
     public boolean canAttackRightTo(int XPOS, int YPOS, int DISTANCE){
         if (!(XPOS>xPos&&YPOS==yPos)){
            return false;
        }
        return canAttackInLineTo(XPOS, YPOS, DISTANCE);
    }
    public boolean canMoveInLineTo(int XPOS, int YPOS){
       return canMoveInLineTo(XPOS, YPOS, 8);
    }
    public boolean canMoveInLineTo(int XPOS, int YPOS, int DISTANCE){
       
        
        if (!inRangeOfBoard(XPOS, YPOS)){

            return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){

            return false;
        }
        if (XPOS==xPos^YPOS==yPos){

        }
        else if ((yPos!=YPOS&xPos!=XPOS)&&(Math.abs(xPos-XPOS)==Math.abs(yPos-YPOS)&&((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))==1))){

        }
        else{

            return false;
        }
         int diffX = xPos-XPOS;
            if (diffX<0){
                diffX = -1;
            }
            else if(diffX>0){
                diffX = 1;
            }
            else{
               diffX = 0;
            }
            int diffY = yPos-YPOS;
            if (diffY<0){
                diffY=-1;
            }
            else if(diffY>0){
                diffY=1;
            }
            else{
                diffY=0;
            }
            int dis;
            if (Math.abs(XPOS-xPos)!=0){
                dis = Math.abs(XPOS-xPos)/100;
            }
            else{
                dis = Math.abs(YPOS-yPos)/100;
            }
        if (Math.abs(xPos-XPOS)>100*DISTANCE){
            return false;
        }
        int level = yourBoard.level(xPos, yPos);
        for (int i=0;i<dis;i++){
            if (yourBoard.sideOccupyingSquare(XPOS+diffX*i*100, YPOS+diffY*i*100)!=Side.NONE){
                    if (yourBoard.sideOccupyingSquare(XPOS+diffX*i*100, YPOS+diffY*i*100)==opponentSide){
                        return false;
                    }
                    if (yourBoard.sideOccupyingSquare(XPOS+diffX*i*100, YPOS+diffY*i*100)==side){
                        return false;
                    }
            }
            if (yourBoard.pieceOccupyingSquare(XPOS, YPOS)==Piece.WALL)
            {
                return false;
            }
            if (inBarrel(XPOS+diffX*i*100, YPOS+diffY*i*100)&&!inBarrel(XPOS, YPOS)){
                        return false;
            }
            if (level<yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)){
                return false;
            }
            if (level==yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)+1){
                level--;
            }
            if (onPermWall(XPOS+diffX*i*100, YPOS+diffY*i*100)&&(i!=0||level>0)){
                return false;
            }

            if (level>yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)+1&&i!=0){
                return false;
            }

        }
            if (level<yourBoard.level(XPOS, YPOS)){
                return false;
            }
            if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
                return false;
            }

        return true;
    }
    public boolean canAttackInLineTo(int XPOS, int YPOS){
        return canAttackInLineTo(XPOS, YPOS, 8);
    }
    public boolean canAttackInLineTo(int XPOS, int YPOS, int DISTANCE){
        if (game==ChessGame.ADULTERY){
            Piece yourPiece = yourBoard.pieceOccupyingSquare(xPos, yPos);
            if (yourPiece==Piece.KING||yourPiece==Piece.QUEEN){
                Piece targetPiece = yourBoard.pieceOccupyingSquare(XPOS, YPOS);
                if (targetPiece==Piece.KING||targetPiece==Piece.QUEEN){
                    return false;
                }
            }
        }

        if (inTank){
            return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (XPOS==xPos^YPOS==yPos){

        }
        else if ((yPos!=YPOS&xPos!=XPOS)&&(Math.abs(xPos-XPOS)==Math.abs(yPos-YPOS)&&((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))==1))){

        }
        else{
            return false;
        }
        int diffX = xPos-XPOS;
        if (diffX<0){
            diffX = -1;
        }
        else if(diffX>0){
            diffX = 1;
        }
        else{
           diffX = 0;
        }
        int diffY = yPos-YPOS;
        if (diffY<0){
            diffY=-1;
        }
        else if(diffY>0){
            diffY=1;
        }
        else{
            diffY=0;
        }
        int dis;
        if (Math.abs(XPOS-xPos)!=0){
            dis = Math.abs(XPOS-xPos)/100;
        }
        else{
            dis = Math.abs(YPOS-yPos)/100;
        }
   if (yourBoard.sideOccupyingSquare(XPOS, YPOS)!=opponentSide){
        return false;
  }
    if (dis>DISTANCE){
        return false;
    }
        int level = yourBoard.level(xPos, yPos);
        for (int i=0;i<dis;i++){
            if (yourBoard.sideOccupyingSquare(XPOS+diffX*i*100, YPOS+diffY*i*100)!=Side.NONE){
                    if (yourBoard.sideOccupyingSquare(XPOS+diffX*i*100, YPOS+diffY*i*100)==opponentSide&&i!=0){
                        return false;
                    }
                    if (yourBoard.sideOccupyingSquare(XPOS+diffX*i*100, YPOS+diffY*i*100)==side){
                        return false;
                    }
                    if (inBarrel(XPOS+diffX*i*100, YPOS+diffY*i*100)&&!inBarrel(XPOS, YPOS)){
                        return false;
                    }
                    if (yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)>level&&i!=0){
                        return false;
                    }
                    if (yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)>level+1){
                        return false;
                    }
            }
            if (inBarrel(XPOS+diffX*i*100, YPOS+diffY*i*100)&&!inBarrel(XPOS, YPOS)){
                        return false;
            }
            if (level<yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)&&i!=0){
                return false;
            }
            if (onPermWall(XPOS+diffX*i*100, YPOS+diffY*i*100)&&(i!=0||level>0)){
                return false;
            }
             if (level==yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)+1){
                level--;
            }

            if (level<yourBoard.level(XPOS+diffX*i*100, YPOS+diffY*i*100)&&level!=yourBoard.level(xPos, yPos)){
                return false;
            }
        }

            if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
                return false;
            }

        return true;
    }

    public ArrayList<Decision> corpseJumps(){
        ArrayList<Decision> corpseJumps = new ArrayList();
        ChessBoard simulaBoard = new ChessBoard(yourBoard);
        for (int i=0;i<simulaBoard.corpses.size();i++){
            if (canJumpCorpse(simulaBoard.corpses.get(i).xPos, simulaBoard.corpses.get(i).yPos)){
                Decision landingSquare = landingSquare(simulaBoard.corpses.get(i).xPos, simulaBoard.corpses.get(i).yPos);
                simulaBoard.yourKing(side).xPos = landingSquare.xPos;
                simulaBoard.yourKing(side).yPos = landingSquare.yPos;
                simulaBoard.corpses.remove(i);
                i--;
                corpseJumps.add(landingSquare);
                 ArrayList<Decision> otherJumps = simulaBoard.yourKing(side).corpseJumps();
                if (otherJumps.size()>0){
                    for (int n=0;n<otherJumps.size();n++){
                        corpseJumps.add(otherJumps.get(n));
                    }
                }
            }
        }
        return corpseJumps;
    }
    public boolean canJumpCorpseTo(int XPOS, int YPOS){
        ArrayList<Corpse> searchCorpses = new ArrayList();
        for (int i=0;i<yourBoard.corpses.size();i++){
            if (canJumpCorpse(yourBoard.corpses.get(i))){
                searchCorpses.add(yourBoard.corpses.get(i));
            }
        }
        for (int i=0;i<searchCorpses.size();i++){
            Decision landingSquare = landingSquare(searchCorpses.get(i));
            if (landingSquare.xPos==XPOS&&landingSquare.yPos==YPOS){
                return true;
            }
        }
        return false;
    }
    public boolean canJumpCorpse(Corpse CORPSE){
        return canJumpCorpse(CORPSE.xPos, CORPSE.yPos);
    }
    public boolean canJumpCorpse(int XPOS, int YPOS){

        if (yourBoard.getWall(xPos, yPos)==null&&yourBoard.getWall(XPOS, YPOS)!=null){
            return false;
        }
        if (!(Math.abs(xPos-XPOS)<=100&&Math.abs(yPos-YPOS)<=100)){
            return false;
        }
        if (xPos==XPOS){
            if (yPos>YPOS){

                    if (yourBoard.sideOccupyingSquare(XPOS, YPOS-100)==side){
                        return false;
                    }
                    else if (yourBoard.sideOccupyingSquare(XPOS, YPOS-100)==opponentSide){
                        return false;
                    }
                    else if (yourBoard.level(XPOS, YPOS-100)!=yourBoard.level(xPos, yPos)){
                        return false;
                    }
                    else{
                        return true;
                    }

            }
            else if(yPos<YPOS){

                    if (yourBoard.sideOccupyingSquare(XPOS, YPOS+100)==side){
                        return false;
                    }
                    else if (yourBoard.sideOccupyingSquare(XPOS, YPOS+100)==opponentSide){
                        return false;
                    }
                    else if (yourBoard.level(XPOS, YPOS+100)!=yourBoard.level(xPos, yPos)){
                        return false;
                    }
                    else{
                        return true;
                    }


            }
        }
        else if(yPos==YPOS){
            if (xPos>XPOS){


                        if (yourBoard.sideOccupyingSquare(XPOS-100, YPOS)==side){

                        }
                        else if (yourBoard.sideOccupyingSquare(XPOS-100, YPOS)==opponentSide){

                        }
                        else if (yourBoard.level(XPOS-100, YPOS)!=yourBoard.level(xPos, yPos)){

                        }
                        else{
                            return true;
                        }


            }
            else if(xPos<XPOS){


                        if (yourBoard.sideOccupyingSquare(XPOS+100, YPOS)==side){

                        }
                        else if (yourBoard.sideOccupyingSquare(XPOS+100, YPOS)==opponentSide){

                        }
                        else if (yourBoard.level(XPOS+100, YPOS)!=yourBoard.level(xPos, yPos)){

                        }
                        else{
                            return true;
                        }

            }
        }
        else if (((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))==1)){
            if (xPos>XPOS&&yPos>YPOS){


                        if (yourBoard.sideOccupyingSquare(XPOS-100, YPOS-100)==side){

                        }
                        else if (yourBoard.sideOccupyingSquare(XPOS-100, YPOS-100)==opponentSide){

                        }
                        else if (yourBoard.level(XPOS-100, YPOS-100)!=yourBoard.level(xPos, yPos)){

                        }
                        else{
                            return true;
                        }


            }
            else if(xPos<XPOS&&yPos>YPOS){


                        if (yourBoard.sideOccupyingSquare(XPOS+100, YPOS-100)==side){

                        }
                        else if (yourBoard.sideOccupyingSquare(XPOS+100, YPOS-100)==opponentSide){

                        }
                        else if (yourBoard.level(XPOS+100, YPOS-100)!=yourBoard.level(xPos, yPos)){

                        }
                        else{
                            return true;
                        }


            }
            else if (xPos<XPOS&&yPos<YPOS){


                        if (yourBoard.sideOccupyingSquare(XPOS+100, YPOS+100)==side){

                        }
                        else if (yourBoard.sideOccupyingSquare(XPOS+100, YPOS+100)==opponentSide){

                        }
                        else if (yourBoard.level(XPOS+100, YPOS+100)!=yourBoard.level(xPos, yPos)){

                        }
                        else{
                            return true;
                        }


            }
            else if (xPos>XPOS&&yPos<YPOS){


                        if (yourBoard.sideOccupyingSquare(XPOS-100, YPOS+100)==side){

                        }
                        else if (yourBoard.sideOccupyingSquare(XPOS-100, YPOS+100)==opponentSide){

                        }
                        else if (yourBoard.level(XPOS-100, YPOS+100)!=yourBoard.level(xPos, yPos)){

                        }
                        else{
                            return true;
                        }


            }
        }
        return false;
    }
    public Decision landingSquare(Corpse CORPSE){
        return landingSquare(CORPSE.xPos, CORPSE.yPos);
    }
    public Decision landingSquare(int XPOS, int YPOS){
        if (xPos==XPOS){
            if (yPos>YPOS){
                return new Decision(XPOS, YPOS-100, DeciType.JUMPS);
            }
            else if(yPos<YPOS){
                return new Decision(XPOS, YPOS+100, DeciType.JUMPS);
            }
        }
        else if (yPos==YPOS){
            if (xPos>XPOS){
               return new Decision(XPOS-100, YPOS, DeciType.JUMPS);
            }
            else if(xPos<XPOS){
               return new Decision(XPOS+100, YPOS, DeciType.JUMPS);
            }
        }
        else if (((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))==1)){
            if (xPos>XPOS&&yPos>YPOS){
                return new Decision(XPOS-100, YPOS-100, DeciType.JUMPS);
            }
            else if(xPos<XPOS&&yPos>YPOS){
                return new Decision(XPOS+100, YPOS-100, DeciType.JUMPS);
            }
            else if (xPos<XPOS&&yPos<YPOS){
                return new Decision(XPOS+100, YPOS+100, DeciType.JUMPS);
            }
            else if (xPos>XPOS&&yPos<YPOS){
                return new Decision(XPOS-100, YPOS+100, DeciType.JUMPS);
            }
        }
        return null;
    }
    public boolean canMoveDiagonallyTo(int XPOS, int YPOS){
        if (yPos!=YPOS && xPos!=XPOS){
            if (Math.abs(xPos-XPOS)!=Math.abs(yPos-YPOS)){
              return false;
          }
          if ((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))!=1){
              return false;
          }

      }
      else{
          return false;
      }
       return canMoveInLineTo(XPOS, YPOS, 8);
    }
    public boolean canMoveDiagonallyTo(int XPOS, int YPOS, int DISTANCE){
        if (yPos!=YPOS && xPos!=XPOS){
            if (Math.abs(xPos-XPOS)!=Math.abs(yPos-YPOS)){
              return false;
          }
          if ((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))!=1){
              return false;
          }

      }
      else{
          return false;
      }
       return canMoveInLineTo(XPOS, YPOS, DISTANCE);
    }
    public boolean canAttackDiagonallyTo(int XPOS, int YPOS){
        if (yPos!=YPOS && xPos!=XPOS){
            if (Math.abs(xPos-XPOS)!=Math.abs(yPos-YPOS)){
              return false;
          }
          if ((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))!=1){
              return false;
          }

      }
      else{
          return false;
      }
        return canAttackInLineTo(XPOS, YPOS, 8);
    }
    public boolean canAttackDiagonallyTo(int XPOS, int YPOS, int DISTANCE){
        if (yPos!=YPOS && xPos!=XPOS){
            if (Math.abs(xPos-XPOS)!=Math.abs(yPos-YPOS)){
              return false;
          }
          if ((Math.abs(xPos-XPOS)/Math.abs(yPos-YPOS))!=1){
              return false;
          }

      }
      else{
          return false;
      }
        return canAttackInLineTo(XPOS, YPOS, DISTANCE);
    }

    public Path makePath(int XPOS, int YPOS){
        Path path = new Path();

        return path;
    }
    public boolean mustPonyThroughPermWallTo(int XPOS, int YPOS){
//        if (yourBoard.level(xPos, yPos)>0){return false;}
        boolean must = false;
        if (Math.abs(XPOS-xPos)==200){
           if (xPos>XPOS){
               if (onPermWall(xPos, YPOS)){must=true;}
               for (int i=xPos;i>=XPOS&&!must;i-=100){
                    if (onPermWall(i, YPOS)){must=true;}
               }
               if (!must){return false;}
                must = false;

               for (int i=xPos;i>=XPOS&&!must;i-=100){
                    if (onPermWall(i, yPos)){must=true;}
               }
               if (!must){return false;}
           }
           else if (xPos<XPOS){
               if (onPermWall(xPos, YPOS)){must=true;}
               for (int i=xPos;i<=XPOS&&!must;i+=100){
                    if (onPermWall(i, YPOS)){must=true;}
               }
               if (!must){return false;}
                must = false;

               for (int i=xPos;i<=XPOS&&!must;i+=100){
                    if (onPermWall(i, yPos)){must=true;}
               }
               if (!must){return false;}
           }
        }
        else if(Math.abs(YPOS-yPos)==200){
            if (yPos>YPOS){
               if (onPermWall(XPOS, yPos)){must=true;}
               for (int i=yPos;i>=YPOS&&!must;i-=100){
                    if (onPermWall(XPOS, i)){must=true;}
               }
               if (!must){return false;}
                must = false;

               for (int i=yPos;i>=YPOS&&!must;i-=100){
                    if (onPermWall(xPos, i)){must=true;}
               }
               if (!must){return false;}
           }
           else if (yPos<YPOS){
               if (onPermWall(XPOS, yPos)){must=true;}
               for (int i=yPos;i<=YPOS&&!must;i+=100){
                    if (onPermWall(XPOS, i)){must=true;}
               }
               if (!must){return false;}
               must = false;

               for (int i=yPos;i<=YPOS&&!must;i+=100){
                    if (onPermWall(xPos, i)){must=true;}
               }
               if (!must){return false;}
           }
        }

        return true;
    }
    public boolean canMovePoniedTo(int XPOS, int YPOS){
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }

        if (yourBoard.level(XPOS, YPOS)>yourBoard.level(xPos, yPos)){
            return false;
        }
        if (Math.abs(xPos-XPOS)==200&&Math.abs(yPos-YPOS)==100){

        }
        else if (Math.abs(xPos-XPOS)==100&&Math.abs(yPos-YPOS)==200){

        }
        else{
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if(yourBoard.sideOccupyingSquare(XPOS, YPOS)==opponentSide){
          return false;
        }
        if(yourBoard.sideOccupyingSquare(XPOS, YPOS)==side){
          return false;
        }
        if (yourBoard.level(xPos, yPos)<yourBoard.level(XPOS, YPOS)){
            return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        return true;
    }

     public boolean canAttackPoniedTo(int XPOS, int YPOS){
         if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (yourBoard.level(xPos, yPos)==0&&mustPonyThroughPermWallTo(XPOS, YPOS)){
            return false;
        }
        if (yourBoard.level(XPOS, YPOS)>yourBoard.level(xPos, yPos)+1){
            return false;
        }
        if (Math.abs(xPos-XPOS)==200&&Math.abs(yPos-YPOS)==100){

        }
        else if (Math.abs(xPos-XPOS)==100&&Math.abs(yPos-YPOS)==200){

        }
        else{
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
           return false;
        }
        if(yourBoard.sideOccupyingSquare(XPOS, YPOS)!=opponentSide){
          return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        return true;
    }
      public boolean canEnPassantTo(int XPOS, int YPOS){
          if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
          if (!canMoveDiagonallyTo(XPOS, YPOS, 1)){
              return false;
          }
          for (int i=0;i<yourBoard.pawns.size();i++){
              if (yourBoard.pawns.get(i).canBeEnPassanted){
                  if (yourBoard.pawns.get(i).side==Side.WHITE){
                      if (side==Side.BLACK&&yourBoard.pawns.get(i).xPos==XPOS&&yourBoard.pawns.get(i).yPos==YPOS-100){
                          return true;
                      }
                      return true;
                  }
                  else{
                      if (side==Side.WHITE&&yourBoard.pawns.get(i).xPos==XPOS&&yourBoard.pawns.get(i).yPos==YPOS+100){
                          return true;
                      }
                  }
              }
          }
          if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
          }
          return false;
      }


      public boolean mustMysteryThroughBarrelTo(int XPOS, int YPOS){
       if (Math.abs(XPOS-xPos)==300){
            if (XPOS>xPos){
                boolean must=false;
                for (int i=xPos;i<=XPOS;i+=100){
                    if (inBarrel(i, yPos)&&inBarrel(i, YPOS)){
                        must=true;
                        break;
                    }
                }
                if (!must){
                    return false;
                }
            }
            if (XPOS<xPos){
                boolean must=false;
                for (int i=xPos;i>=XPOS;i-=100){
                    if (inBarrel(i, yPos)&&inBarrel(i, YPOS)){
                        must=true;
                        break;
                    }
                }
                if (!must){
                    return false;
                }
            }
        }
        else if (Math.abs(YPOS-yPos)==300){
            if (YPOS>yPos){
                boolean must=false;
                for (int i=yPos;i<=YPOS;i+=100){
                    if (inBarrel(xPos, i)&&inBarrel(xPos, i)){
                        must=true;
                        break;
                    }
                }
               if (!must){
                   return false;
               }
            }
            if (YPOS<yPos){
                boolean must=false;
                for (int i=yPos;i>=YPOS;i-=100){
                    if (inBarrel(xPos, i)&&inBarrel(xPos, i)){
                        must=true;
                        break;
                    }
                }
                if (!must){
                    return false;
                }
            }
        }
        return true;
    }
     public boolean canMoveMysteriedTo(int XPOS, int YPOS){
         if (inTank){
            return false;
        }
         if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }

        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (!inBarrel(XPOS, YPOS)&&mustMysteryThroughBarrelTo(XPOS, YPOS)){
            return false;
        }
        if (Math.abs(xPos-XPOS)==300&&Math.abs(yPos-YPOS)==100){

        }
        else if (Math.abs(xPos-XPOS)==100&&Math.abs(yPos-YPOS)==300){

        }
        else{
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==Side.NONE){
            return true;
        }
        return false;
    }
    public boolean canAttackMysteriedTo(int XPOS, int YPOS){
        if (inTank){
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }

        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (mustMysteryThroughBarrelTo(XPOS, YPOS)){
            return false;
        }
        if (Math.abs(xPos-XPOS)==300&&Math.abs(yPos-YPOS)==100){

        }
        else if (Math.abs(xPos-XPOS)==100&&Math.abs(yPos-YPOS)==300){

        }
        else{
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if(yourBoard.sideOccupyingSquare(XPOS, YPOS)!=opponentSide){
          return false;
        }
        return true;
    }
 private boolean escapeRoute(int XPOS, int YPOS, ArrayList<Decision> forbidden)
 {
     forbidden.add(new Decision(XPOS, YPOS));
    int[] xPosits = {XPOS, XPOS, XPOS+100, XPOS+100, XPOS+100, XPOS-100, XPOS-100, XPOS-100};
    int[] yPosits = {YPOS+100, YPOS-100, YPOS, YPOS+100, YPOS-100, YPOS, YPOS+100, YPOS-100};
    ArrayList<Decision> possible = new ArrayList();
    for (int i=0;i<8;i++)
    {
        Side targetSide = yourBoard.sideOccupyingSquare(xPosits[i], yPosits[i]);
        boolean forbade = false;
        for (int j=0;j<forbidden.size();j++)
        {
            if (forbidden.get(j).xPos==xPosits[i] && forbidden.get(j).yPos==yPosits[i])
            {
                forbade = true;
                break;
            }
        }
        if (forbade)
        {

        }
        else if (targetSide==Side.NONE)
        {
            return true;
        }
        else if (targetSide!=Side.NULL&&targetSide!=Side.WALL)
        {
            possible.add(new Decision(xPosits[i], yPosits[i]));
           // forbidden.add(new Decision(xPosits[i], yPosits[i]));
        }
    }
    for (int i=0;i<possible.size();i++)
    {
        if (escapeRoute(possible.get(i).xPos, possible.get(i).yPos, forbidden))
        {
            return true;
        }
    }
    return false;
 }
 public boolean isSuffocated()
 {
     ArrayList<Decision> forbidden = new ArrayList();
     return !escapeRoute(xPos, yPos, forbidden);
 }
     public boolean monkeyCanMoveMysteriedTo(int XPOS, int YPOS){
         if (inTank){
            return false;
        }
       if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (!inBarrel(XPOS, YPOS)&&mustMysteryThroughBarrelTo(XPOS, YPOS)){
            return false;
        }
        if (Math.abs(xPos-XPOS)==300&&Math.abs(yPos-YPOS)==100){

        }
        else if (Math.abs(xPos-XPOS)==100&&Math.abs(yPos-YPOS)==300){

        }
        else{
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
         if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==opponentSide){
                return false;
            }
            if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==side){
                return false;
            }
            if (yourBoard.sideOccupyingSquare(XPOS, YPOS)!=opponentSide){
                return false;
            }
            if (yourBoard.level(XPOS, YPOS)>yourBoard.level(xPos, yPos)){
                return false;
            }
        return true;
    }
    public boolean monkeyCanAttackMysteriedTo(int XPOS, int YPOS){
        if (inTank){
            return false;
        }
      if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
        }
        if (mustMysteryThroughBarrelTo(XPOS, YPOS)){
            return false;
        }
        if (Math.abs(xPos-XPOS)==300&&Math.abs(yPos-YPOS)==100){

        }
        else if (Math.abs(xPos-XPOS)==100&&Math.abs(yPos-YPOS)==300){

        }
        else{
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
            if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==side){
                return false;
            }
            if (yourBoard.sideOccupyingSquare(XPOS, YPOS)!=opponentSide){
                return false;
            }
            if (yourBoard.level(XPOS, YPOS)>yourBoard.level(xPos, yPos)){
                return false;
            }
        return true;
    }
    public boolean canExplode(int XPOS, int YPOS){
        if (true)
        {
            return false;
        }
        if (inTank){
            return false;
        }
        if (!ChessApplet.explode){
            return false;
        }
        if (game!=ChessGame.MONKEY&&game!=ChessGame.PEASANT){
            return false;
        }
        if (XPOS!=xPos||YPOS!=yPos){
            return false;
        }
        if (Math.abs(yourBoard.yourKing(side).xPos-XPOS)<=100&&Math.abs(yourBoard.yourKing(side).yPos-YPOS)<=100){
            return false;
        }
        if (inBarrel()){
            if (Math.abs(yourBoard.yourKing(side).xPos-D)<=100&&Math.abs(yourBoard.yourKing(side).yPos-_4)<=100){
                return false;
            }
            if (Math.abs(yourBoard.yourKing(side).xPos-D)<=100&&Math.abs(yourBoard.yourKing(side).yPos-_5)<=100){
                return false;
            }
            if (Math.abs(yourBoard.yourKing(side).xPos-E)<=100&&Math.abs(yourBoard.yourKing(side).yPos-_4)<=100){
                return false;
            }
            if (Math.abs(yourBoard.yourKing(side).xPos-E)<=100&&Math.abs(yourBoard.yourKing(side).yPos-_5)<=100){
                return false;
            }
        }
        return true;
    }

    public boolean couldExplodeYou(Pawn PAWN){
        if (game!=ChessGame.MONKEY&&game!=ChessGame.PEASANT){
            return false;
        }
        if (PAWN.inBarrel()){
            if (Math.abs(D-xPos)<=100&&Math.abs(_4-yPos)<=100){
                return true;
            }
            if (Math.abs(D-xPos)<=100&&Math.abs(_5-yPos)<=100){
                return true;
            }
            if (Math.abs(E-xPos)<=100&&Math.abs(_4-yPos)<=100){
                return true;
            }
            if (Math.abs(E-xPos)<=100&&Math.abs(_5-yPos)<=100){
                return true;
            }
        }
        else{
            if (Math.abs(PAWN.xPos-xPos)<=100&&Math.abs(PAWN.yPos-yPos)<=100){
                return true;
            }
        }
        return false;
    }

    public boolean inCheck(){
        return inCheck(xPos, yPos);
    }
    public boolean inCheck(ChessPiece piece){
        return inCheck(piece.xPos, piece.yPos);
    }
    public boolean inCheck(int XPOS,int YPOS){
        if (game==ChessGame.ADULTERY){
            return false;
        }
         

      for (int i=0;i<yourBoard.pawns.size();i++){
            if (yourBoard.pawns.get(i).getSide() != side && yourBoard.pawns.get(i).canAttackToMinusChecking(XPOS, YPOS)){
                return true;
            }
        } 

        for (int i=0;i<yourBoard.queens.size();i++){
            if (yourBoard.queens.get(i).getSide() != side && yourBoard.queens.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                return true;
            }
        }
         for (int i=0;i<yourBoard.rooks.size();i++){
            if (yourBoard.rooks.get(i).getSide() != side && yourBoard.rooks.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                return true;
            }
        }
         for (int i=0;i<yourBoard.bishops.size();i++){
            if (yourBoard.bishops.get(i).getSide() != side && yourBoard.bishops.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                return true;
            }
        }
         for (int i=0;i<yourBoard.knights.size();i++){
            if (yourBoard.knights.get(i).getSide() != side && yourBoard.knights.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                return true;
            }
        }
      if (side==Side.BLACK){
            if (yourBoard.whiteKing!=null&&Math.abs(XPOS-yourBoard.whiteKing.xPos)<=100&&Math.abs(YPOS-yourBoard.whiteKing.yPos)<=100){
                return true;
            }
        }
        else if(side==Side.WHITE){
            if (yourBoard.blackKing!=null&&Math.abs(XPOS-yourBoard.blackKing.xPos)<=100&&Math.abs(YPOS-yourBoard.blackKing.yPos)<=100){
                return true;
            }
        }
        return false;
    }
    public ChessPiece getChecker(){
        int XPOS = xPos;
        int YPOS = yPos;

        for (int i=0;i<yourBoard.pawns.size();i++){
            if (yourBoard.pawns.get(i).getSide() != side && yourBoard.pawns.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.pawns.get(i);

            }
        }
        for (int i=0;i<yourBoard.queens.size();i++){
            if (yourBoard.queens.get(i).getSide() != side && yourBoard.queens.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.queens.get(i);

            }
        }
         for (int i=0;i<yourBoard.rooks.size();i++){
            if (yourBoard.rooks.get(i).getSide() != side && yourBoard.rooks.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.rooks.get(i);

            }
        }
         for (int i=0;i<yourBoard.bishops.size();i++){
            if (yourBoard.bishops.get(i).getSide() != side && yourBoard.bishops.get(i).canMoveTo(XPOS, YPOS)){
               return yourBoard.bishops.get(i);

            }
        }
         for (int i=0;i<yourBoard.knights.size();i++){
            if (yourBoard.knights.get(i).getSide() != side && yourBoard.knights.get(i).canMoveTo(XPOS, YPOS)){
               return yourBoard.knights.get(i);

            }
        }
        for (int i=0;i<yourBoard.mysteryPieces.size();i++){
            if (yourBoard.mysteryPieces.get(i).getSide() != side && yourBoard.mysteryPieces.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.mysteryPieces.get(i);

            }
        }
        for (int i=0;i<yourBoard.tanks.size();i++){
            if (yourBoard.tanks.get(i).getSide() != side && yourBoard.tanks.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.tanks.get(i);

            }
        }
        for (int i=0;i<yourBoard.tacoFiends.size();i++){
            if (yourBoard.tacoFiends.get(i).getSide() != side && yourBoard.tacoFiends.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.tacoFiends.get(i);

            }
        }
        for (int i=0;i<yourBoard.monkeys.size();i++){
            if (yourBoard.monkeys.get(i).getSide() != side && yourBoard.monkeys.get(i).canMoveTo(XPOS, YPOS)){
                return yourBoard.monkeys.get(i);

            }
        }
        return null;
    }
    public int numberOfChecks(){
        return numberOfChecks(xPos, yPos);
    }
    public int numberOfChecks(int XPOS, int YPOS){
        int numberOfChecks = 0;
        for (int i=0;yourBoard.pawns.size()>0&&i<yourBoard.pawns.size();i++){
             if (yourBoard.pawns.get(i).getSide() != side
                    && couldExplodeYou(yourBoard.pawns.get(i))
                    && !yourBoard.pawns.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;
            }
            if (yourBoard.pawns.get(i).getSide() != side && yourBoard.pawns.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;
            }

        }

        for (int i=0;yourBoard.queens.size()>0&&i<yourBoard.queens.size();i++){
            if (yourBoard.queens.get(i).getSide() != side && yourBoard.queens.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
         for (int i=0;yourBoard.rooks.size()>0&&i<yourBoard.rooks.size();i++){
            if (yourBoard.rooks.get(i).getSide() != side && yourBoard.rooks.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
         for (int i=0;yourBoard.bishops.size()>0&&i<yourBoard.bishops.size();i++){
            if (yourBoard.bishops.get(i).getSide() != side && yourBoard.bishops.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
         for (int i=0;yourBoard.knights.size()>0&&i<yourBoard.knights.size();i++){
            if (yourBoard.knights.get(i).getSide() != side && yourBoard.knights.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
        for (int i=0;yourBoard.monkeys.size()>0&&i<yourBoard.monkeys.size();i++){
            if (yourBoard.monkeys.get(i).getSide() != side && yourBoard.monkeys.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;
            }
        }
        for (int i=0;yourBoard.tanks.size()>0&&i<yourBoard.tanks.size();i++){
            if (yourBoard.tanks.get(i).getSide() != side && yourBoard.tanks.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;
            }
        }
        for (int i=0;yourBoard.wildCards.size()>0&&i<yourBoard.wildCards.size();i++){
            if (yourBoard.wildCards.get(i).getSide() != side && yourBoard.wildCards.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;
            }
        }
        for (int i=0;yourBoard.tacoFiends.size()>0&&i<yourBoard.tacoFiends.size();i++){
            if (yourBoard.tacoFiends.get(i).getSide() != side && yourBoard.tacoFiends.get(i).canMoveTo(XPOS, YPOS)){
                numberOfChecks++;
            }
        }
      if (yourBoard.getToaster(opponentSide)!=null){
          if (yourBoard.getToaster(opponentSide).canMoveTo(XPOS, YPOS)){
              numberOfChecks++;
          }
      }
      if (side==Side.BLACK&&yourBoard.whiteKing!=null){
            if (Math.abs(XPOS-yourBoard.whiteKing.xPos)<=100&&Math.abs(YPOS-yourBoard.whiteKing.yPos)<=100){
                numberOfChecks++;

            }
        }
        else if(side==Side.WHITE&&yourBoard.blackKing!=null){
            if (Math.abs(XPOS-yourBoard.blackKing.xPos)<=100&&Math.abs(YPOS-yourBoard.blackKing.yPos)<=100){
                numberOfChecks++;

            }
        }
        return numberOfChecks;
    }
    public int numberOfChecksMinusKingChecking(){
        return numberOfChecksMinusKingChecking(xPos, yPos);
    }
    public int numberOfChecksMinusKingChecking(int XPOS, int YPOS){
        int numberOfChecks = 0;
        for (int i=0;i<yourBoard.pawns.size();i++){
            if (yourBoard.pawns.get(i).getSide() != side && yourBoard.pawns.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;
            }
            if (yourBoard.pawns.get(i).getSide() != side && couldExplodeYou(yourBoard.pawns.get(i)) && !yourBoard.pawns.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;
            }
        }
        for (int i=0;i<yourBoard.queens.size();i++){
            if (yourBoard.queens.get(i).getSide() != side && yourBoard.queens.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
         for (int i=0;i<yourBoard.rooks.size();i++){
            if (yourBoard.rooks.get(i).getSide() != side && yourBoard.rooks.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
         for (int i=0;i<yourBoard.bishops.size();i++){
            if (yourBoard.bishops.get(i).getSide() != side && yourBoard.bishops.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
         for (int i=0;i<yourBoard.knights.size();i++){
            if (yourBoard.knights.get(i).getSide() != side && yourBoard.knights.get(i).canMoveToMinusChecking(XPOS, YPOS)){
                numberOfChecks++;

            }
        }
      if (side==Side.BLACK){
            if (yourBoard.whiteKing!=null&&Math.abs(XPOS-yourBoard.whiteKing.xPos)<=100&&Math.abs(YPOS-yourBoard.whiteKing.yPos)<=100){
                numberOfChecks++;

            }
        }
        else if(side==Side.WHITE){
            if (yourBoard.blackKing!=null&&Math.abs(XPOS-yourBoard.blackKing.xPos)<=100&&Math.abs(YPOS-yourBoard.blackKing.yPos)<=100){
                numberOfChecks++;

            }
        }
        return numberOfChecks;
    }
   public boolean inTank(){
       for (int i=0;i<yourBoard.tanks.size();i++){
           if (xPos==yourBoard.tanks.get(i).xPos&&yPos==yourBoard.tanks.get(i).yPos){
               return true;
           }
       }
       return false;
   }
   protected boolean isWildCardSubstitute(){
       for (int i=0;i<yourBoard.wildCards.size();i++){
           if (yourBoard.wildCards.get(i).side==side&&!yourBoard.wildCards.get(i).inCheck()){
               return true;
           }
       }
       return false;
   }
   protected boolean wildCardsWouldBeInCheck(int XPOS, int YPOS){
       ArrayList<WildCard> checkCards = new ArrayList();
       for (int i=0;i<yourBoard.wildCards.size();i++){
           if (yourBoard.wildCards.get(i).side==side&&!yourBoard.wildCards.get(i).inCheck()){
               checkCards.add(yourBoard.wildCards.get(i));
           }

       }
           if (checkCards.size()==0){

               return true;
           }
           ChessBoard simulaBoard = new ChessBoard(yourBoard);

           switch(simulaBoard.pieceOccupyingSquare(xPos, yPos)){
                    case KING: simulaBoard.getKing(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case KNIGHT: simulaBoard.getKnight(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case ROOK: simulaBoard.getRook(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case MYSTERYPIECE: simulaBoard.getMysteryPiece(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case CORPSE: simulaBoard.getCorpse(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case MONKEY: simulaBoard.getMonkey(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case TANK: simulaBoard.getTank(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case TACOFIEND: simulaBoard.getTacoFiend(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case QUEEN: simulaBoard.getQueen(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case PAWN: simulaBoard.getPawn(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case BISHOP: simulaBoard.getBishop(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case WILDCARD: simulaBoard.getWildCard(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case TOASTER:
                        break;
       }
       for (int i=0;i<simulaBoard.pawns.size();i++){
           simulaBoard.pawns.get(i).changeCheck();
       }

        simulaBoard.countBlackKills();
        simulaBoard.countWhiteKills();
      //  simulaBoard.controlMindsMinusKingChecking();
       for (int i=0;i<checkCards.size();i++){
           if (!checkCards.get(i).inCheck()){
               return false;
           }
       }
       return true;
   }
   protected boolean kingWouldBeInCheck(int XPOS, int YPOS){
        
     
        ChessBoard simulaBoard = new ChessBoard(yourBoard);
        if (yourBoard.pieceOccupyingSquare(xPos, yPos)==Piece.KING&&yourBoard.yourKing(side).inCheck(XPOS, YPOS)){
            return true;
        }
       switch(simulaBoard.pieceOccupyingSquare(xPos, yPos)){
                    case KING: simulaBoard.getKing(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case KNIGHT: simulaBoard.getKnight(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case ROOK: simulaBoard.getRook(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case MYSTERYPIECE: simulaBoard.getMysteryPiece(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case CORPSE: simulaBoard.getCorpse(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case MONKEY: simulaBoard.getMonkey(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case TANK: simulaBoard.getTank(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case TACOFIEND: simulaBoard.getTacoFiend(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case QUEEN: simulaBoard.getQueen(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case PAWN: simulaBoard.getPawn(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case BISHOP: simulaBoard.getBishop(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case WILDCARD: simulaBoard.getWildCard(xPos, yPos).move(XPOS, YPOS);
                        break;
                    case TOASTER: simulaBoard.getToaster(side).move(XPOS, YPOS);
                        break;
       }
       /* if (simulaBoard.yourKing(side)==null){
            return wildCardsWouldBeInCheck(XPOS, YPOS);
        }
       for (int i=0;i<simulaBoard.pawns.size();i++){

           simulaBoard.pawns.get(i).changeCheck();
       } */
        simulaBoard.countBlackKills();
        simulaBoard.countWhiteKills();
//        simulaBoard.controlMindsMinusKingChecking(side);
//        simulaBoard.controlMindsMinusKingChecking(opponentSide);
      //  simulaBoard.controlMindsMinusKingChecking();
        if (game==ChessGame.ADULTERY){
            for (int i=0;i<simulaBoard.queens.size();i++){
                if (simulaBoard.queens.get(i).side==opponentSide){
                    if (simulaBoard.squareAdjacentToSquare(simulaBoard.yourKing(opponentSide).xPos, simulaBoard.yourKing(opponentSide).yPos,
                            simulaBoard.queens.get(i).xPos, simulaBoard.queens.get(i).yPos)){
                        return true;
                    }
                }
            }
        }
        else{
            

              if (simulaBoard.yourKing(side).inCheck()){
                  return true;
              }

            
        }
        return false;
    }
    public boolean inCheckMate(){
        return inCheckMate(this);
    }
    public boolean inCheckMate(ChessPiece piece){
        if (game==ChessGame.ADULTERY)
        {
            for (int i=0;i<yourBoard.queens.size();i++){
                  if (yourBoard.queens.get(i).side==opponentSide){
                      if (yourBoard.squareAdjacentToSquare(yourBoard.yourKing(opponentSide).xPos, yourBoard.yourKing(opponentSide).yPos,
                              yourBoard.queens.get(i).xPos, yourBoard.queens.get(i).yPos)){
                          return true;
                      }
                  }
              }

        }
        if (!inCheck()){
            return false;
        }
        
       ArrayList<Decision> possibleDecisions=possibleDecisions();
       for (int i=0;i<possibleDecisions.size();i++){
           if (!kingWouldBeInCheck(possibleDecisions.get(i).xPos, possibleDecisions.get(i).yPos)){
               return false;
           }
       }
       if (numberOfChecks()>1){
           return true;
       }
       for (int i=0;i<yourBoard.queens.size();i++){
           Queen targetPiece = yourBoard.queens.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.rooks.size();i++){
           Rook targetPiece = yourBoard.rooks.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.knights.size();i++){
           Knight targetPiece = yourBoard.knights.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.bishops.size();i++){
           Bishop targetPiece = yourBoard.bishops.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.pawns.size();i++){
           Pawn targetPiece = yourBoard.pawns.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.monkeys.size();i++){
           Monkey targetPiece = yourBoard.monkeys.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.mysteryPieces.size();i++){
           MysteryPiece targetPiece = yourBoard.mysteryPieces.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.wildCards.size();i++){
           WildCard targetPiece = yourBoard.wildCards.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.tanks.size();i++){
           Tank targetPiece = yourBoard.tanks.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.tacoFiends.size();i++){
           TacoFiend targetPiece = yourBoard.tacoFiends.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       for (int i=0;i<yourBoard.corpses.size();i++){
           Corpse targetPiece = yourBoard.corpses.get(i);
           if (targetPiece.side==side){
               if (targetPiece.possibleDecisions().size()>0){
                   return false;
               }
           }
       }
       
        return true;
    }

    public int getXPos(){
        return xPos;
    }
    public int getYPos(){
        return yPos;
    }
    public Side getSide(){
        return side;
    }
    public void setXPos(int XPOS){
        xPos = XPOS;
    }
    public void setYPos(int YPOS){
        yPos = YPOS;
    }

    public String getSideInString(){
        if (side == Side.BLACK){
            return "Black";
        }
        else{
            return "White";
        }
    }

}