package chess2;

public class Opponent implements ChessConstants{
    Side side;
    Side opponentSide;
    Difficulty difficulty = ChessApplet.difficulty;
    boolean inGame = true;
    boolean yourVictory = false;
    boolean yourDefeat = false;
    boolean draw = false;
    ChessBoard board;
    ChessGame game;
    int boardvalue;
    int plylevel = 100;
    int ceiling  = 2800;

    public Opponent(ChessGame GAME, Side SIDE, ChessBoard BOARD){
        if (ChessApplet.difficulty==Difficulty.VERY_EASY)
        {
            plylevel = 2;
            ceiling = 1000;
        }
        else if (ChessApplet.difficulty==Difficulty.EASY)
        {
            if (game==ChessGame.ADULTERY)
            {
                plylevel = 4;
                ceiling = 2500;
            }
            else
            {
                plylevel = 4;
                ceiling = 2500;
            }
        }
        else if (ChessApplet.difficulty==Difficulty.MEDIUM)
        {
            if (game==ChessGame.ADULTERY)
            {
                plylevel = 100;
                ceiling = 3700;
            }
            else
            {
                plylevel = 100;
                ceiling = 3000;
            }
        }
        else if (ChessApplet.difficulty==Difficulty.HARD)
        {
            if (game==ChessGame.ADULTERY)
            {
                plylevel = 100;
                ceiling = 4700;
            }
            else
            {
                plylevel = 100;
                ceiling = 3600;
            }
        }
        else if (ChessApplet.difficulty==Difficulty.VERY_HARD)
        {
            if (game==ChessGame.ADULTERY)
            {
                plylevel = 100;
                ceiling = 5700;
            }
            else
            {
                plylevel = 100;
                ceiling = 4500;
            }
        }
        game = GAME;
        side = SIDE;
        board = BOARD;
        if (side==Side.WHITE)
        {
            opponentSide = Side.BLACK;
        }
        else
        {
            opponentSide = Side.WHITE;
        }
    }
   


    public MoveNode decisionTree(int ply){
        return DecisionTree.decisionTree(board, side, ply, ceiling);
    }
    public ChessBoard mostValuableMove()
    {

        MoveNode decisionTree = this.decisionTree(plylevel);
         if (decisionTree.consequences.size()==0)
         {
            if (decisionTree.board.yourKing(side).inCheck())
            {
                yourVictory = true;
            }
            else if (decisionTree.board.yourKing(opponentSide).inCheck())
            {
                yourDefeat = true;
            }
            else
            {
                if (board.yourKing(side).air>board.yourKing(opponentSide).air)
                {
                    yourDefeat = true;
                }
                else if (board.yourKing(opponentSide).air>board.yourKing(side).air)
                {
                    yourVictory = true;
                }
                else
                {
                    if (game==ChessGame.ADULTERY)
                    {
                        yourDefeat = true;
                    }
                    else
                    {
                        draw = true;
                      //  System.out.println("draw A");
                    }
                }
            }
         }
        if (Reply.replies(board, opponentSide).size()==0&&board.yourKing(opponentSide).inCheck())
        {
            yourDefeat = true;
        }
        int index = 0;
      
        int greatestValue = decisionTree.consequences.get(index).value(side);
        greatestValue /= dockReversion(decisionTree.consequences.get(index).board);
        for (int i=index+1;i<decisionTree.consequences.size();i++)
        {
            int value = decisionTree.consequences.get(i).value(side);
            value -= dockReversion(decisionTree.consequences.get(i).board);
           // System.out.println("Value of consequence#"+i+": "+value);
            if (value>=greatestValue)
            {
                index = i;
                greatestValue = value;
            }
        }
        return decisionTree.consequences.get(index).board;
    }
    private int dockReversion(ChessBoard BOARD)
    {

        if (side==Side.WHITE)
        {
            Piece squareOccupation = BOARD.pieceOccupyingSquare(board.whiteMoveXPos, board.whiteMoveYPos);
            if (squareOccupation==board.whiteMovePiece)
            {
                return 4;
            }
        }
        else
        {
            Piece squareOccupation = BOARD.pieceOccupyingSquare(board.blackMoveXPos, board.blackMoveYPos);
            if (squareOccupation==board.blackMovePiece)
            {
                return 4;
            }
            
        }
        return 1;
    }
    public void move(){
     int possibleMoves = Reply.replies(board, side).size();
      int reactionMoves = Reply.replies(board, opponentSide).size();
      if (game==ChessGame.ADULTERY){
         // if (reactionMoves==0){
              for (int i=0;i<board.queens.size();i++){
                  if (board.queens.get(i).side==side){
                      if (board.squareAdjacentToSquare(board.yourKing(side).xPos, board.yourKing(side).yPos, board.queens.get(i).xPos, board.queens.get(i).yPos)){
                          yourDefeat = true;
                          break;
                      }
                  }
              }
          //}
          if (possibleMoves==0){
              for (int i=0;i<board.queens.size();i++){
                  if (board.queens.get(i).side==opponentSide){
                      if (board.squareAdjacentToSquare(board.yourKing(opponentSide).xPos, board.yourKing(opponentSide).yPos, board.queens.get(i).xPos, board.queens.get(i).yPos)){
                          yourVictory = true;
                          break;
                      }
                  }
              }
          }
      }
          if ((reactionMoves==0&&possibleMoves==0)||(yourDefeat&&yourVictory)){
              yourDefeat = false;
              yourVictory = false;
             System.out.println("Draw B");
              draw = true;
          }
      
      if (possibleMoves==0&&reactionMoves!=0){
          yourVictory = true;
          return;
      }
      if (reactionMoves==0&&possibleMoves==0)
      {
          System.out.println("Draw C");
          draw = true;
          return;
      }
        
 /*     if (board.yourKing(side).inCheckMate())
      {
          yourVictory = true;
      }
      else if(board.yourKing(opponentSide).inCheckMate())
      {
          yourDefeat = true;
      }
      else if (Reply.replies(board, side).size()==0)
      {
          draw = true;
      } */
      
      else{

        ChessBoard cloneBoard = mostValuableMove();

        board.bishops.clear();
        board.pawns.clear();
        board.rooks.clear();
        board.knights.clear();
        board.queens.clear();
        board.mysteryPieces.clear();
        board.walls.clear();
        board.corpses.clear();
        board.tanks.clear();
        board.monkeys.clear();
        board.tacoFiends.clear();
        for (int i=0;i<cloneBoard.bishops.size();i++){
                board.bishops.add(new Bishop(cloneBoard.bishops.get(i).side, cloneBoard.bishops.get(i).xPos, cloneBoard.bishops.get(i).yPos, board, game));
                board.bishops.get(i).inTank = cloneBoard.bishops.get(i).inTank;
            }
            for (int i=0;i<cloneBoard.pawns.size();i++){
                board.pawns.add(new Pawn(cloneBoard.pawns.get(i).side, cloneBoard.pawns.get(i).xPos, cloneBoard.pawns.get(i).yPos, cloneBoard.pawns.get(i).hasMoved, board, game));
                board.pawns.get(i).inTank = cloneBoard.pawns.get(i).inTank;
            }
            for (int i=0;i<cloneBoard.rooks.size();i++){
                board.rooks.add(new Rook(cloneBoard.rooks.get(i).side, cloneBoard.rooks.get(i).xPos, cloneBoard.rooks.get(i).yPos, board, game));
                board.rooks.get(i).inTank = cloneBoard.rooks.get(i).inTank;
                board.rooks.get(i).hasMoved = cloneBoard.rooks.get(i).hasMoved;
            }
            for (int i=0;i<cloneBoard.knights.size();i++){
                board.knights.add(new Knight(cloneBoard.knights.get(i).side, cloneBoard.knights.get(i).xPos, cloneBoard.knights.get(i).yPos, board, game));
                board.knights.get(i).inTank = cloneBoard.knights.get(i).inTank;
            }
            for (int i=0;i<cloneBoard.queens.size();i++){
                board.queens.add(new Queen(cloneBoard.queens.get(i).side, cloneBoard.queens.get(i).xPos, cloneBoard.queens.get(i).yPos, board, game));
                board.queens.get(i).inTank = cloneBoard.queens.get(i).inTank;
            }
           for (int i=0;i<cloneBoard.mysteryPieces.size();i++){
                board.mysteryPieces.add(new MysteryPiece(cloneBoard.mysteryPieces.get(i).side, cloneBoard.mysteryPieces.get(i).xPos, cloneBoard.mysteryPieces.get(i).yPos, board, game));
                board.mysteryPieces.get(i).inTank = cloneBoard.mysteryPieces.get(i).inTank;
            }
           for (int i=0;i<cloneBoard.walls.size();i++){
                board.walls.add(new Wall(cloneBoard.walls.get(i).xPos, cloneBoard.walls.get(i).yPos));
                board.walls.get(i).inTank = cloneBoard.walls.get(i).inTank;
            }
            for (int i=0;i<cloneBoard.corpses.size();i++){
                board.corpses.add(new Corpse(cloneBoard.corpses.get(i).side, cloneBoard.corpses.get(i).xPos, cloneBoard.corpses.get(i).yPos, board, game));
                board.corpses.get(i).inTank = cloneBoard.corpses.get(i).inTank;
            }
            for (int i=0;i<cloneBoard.tanks.size();i++){
                board.tanks.add(new Tank(cloneBoard.tanks.get(i).side, cloneBoard.tanks.get(i).projXPos1, cloneBoard.tanks.get(i).projYPos1,
                    cloneBoard.tanks.get(i).projXPos2, cloneBoard.tanks.get(i).projYPos2, board, cloneBoard.game));
            }
            for (int i=0;i<cloneBoard.monkeys.size();i++){
                board.monkeys.add(new Monkey(cloneBoard.monkeys.get(i).side, cloneBoard.monkeys.get(i).xPos, cloneBoard.monkeys.get(i).yPos, board, game));
                board.monkeys.get(i).inTank = cloneBoard.monkeys.get(i).inTank;
            }
            for (int i=0;i<cloneBoard.tacoFiends.size();i++){
                board.tacoFiends.add(new TacoFiend(cloneBoard.tacoFiends.get(i).side, cloneBoard.tacoFiends.get(i).xPos, cloneBoard.tacoFiends.get(i).yPos, board, game));
                board.tacoFiends.get(i).inTank = cloneBoard.tacoFiends.get(i).inTank;
            }

            if (cloneBoard.whiteKing!=null){board.whiteKing = new King(Side.WHITE, cloneBoard.whiteKing.xPos, cloneBoard.whiteKing.yPos, cloneBoard.whiteKing.air, board, game);
                board.whiteKing.hasMoved = cloneBoard.whiteKing.hasMoved;
                board.whiteKing.inTank = cloneBoard.whiteKing.inTank;
                board.whiteKing.air = cloneBoard.whiteKing.air;
            }
            if (cloneBoard.blackKing!=null){board.blackKing = new King(Side.BLACK, cloneBoard.blackKing.xPos, cloneBoard.blackKing.yPos, cloneBoard.blackKing.air, board, game);
                board.blackKing.hasMoved = cloneBoard.blackKing.hasMoved;
                board.blackKing.inTank = cloneBoard.blackKing.inTank;
                board.blackKing.air = cloneBoard.blackKing.air;
            }

            board.blackHasKilled = cloneBoard.blackHasKilled;
            board.whiteHasKilled = cloneBoard.whiteHasKilled;
            board.blackKillCount = cloneBoard.blackKillCount;
            board.whiteKillCount = cloneBoard.whiteKillCount;
            board.whiteMovePiece = cloneBoard.whiteMovePiece;
            board.whiteMoveXPos = cloneBoard.whiteMoveXPos;
            board.whiteMoveYPos = cloneBoard.whiteMoveYPos;
            board.blackMovePiece =  cloneBoard.blackMovePiece;
            board.blackMoveXPos = cloneBoard.blackMoveXPos;
            board.blackMoveYPos = cloneBoard.blackMoveYPos;
             if (side==Side.WHITE&&board.whiteKing.isSuffocated()){
                    board.whiteKing.air--;
                }
             if (side==Side.BLACK&&board.blackKing.isSuffocated()){
                    board.blackKing.air--;
             }
            if (board.yourKing(opponentSide).inCheckMate())
            {
                yourDefeat = true;
            }
            else if (Reply.replies(board, opponentSide).size()==0)
            {
                System.out.println("Draw D");
                draw = true;
            }
        }
    }

    
}

