/*
 * chessAgent.java
 *
 * Created on April 28, 2005, 5:07 AM
 */

/** CheckMates a lone king in a king/queen vs. king end game scenario
 *  author: sweave
 *
 *
 *
 *  NOTE:  THIS PROGRAM NEEDS "TextIO.java" included with it to 
 *  compile and work!!  (google it, it is everywhere)
 */




import java.lang.Math;
import java.io.*;
import java.util.*;


public class chessAgent {
    //vars
    /*static int kx = 0, ky = 3;
    static int qx = 2, qy = 2;
    static int ex = 1, ey = 0;*/
    
    static int kx, ky, ex, ey, qx, qy;
    
    
    
    
    static char axis;
    static int limit = 999;
    static boolean[][] QT = new boolean[8][8];// Queen Threatened
    static boolean[][] QT_temp = new boolean[8][8];//used to look at potential queen moves in tryForMate();
    static boolean[][] KT = new boolean[8][8]; //adjacent squares to my KING (threatened by king)
    static boolean[][] KT_temp = new boolean[8][8];//for examining implications of potential king moves
    static boolean[][] ET = new boolean[8][8]; //adjacent to ENEMY king (+self)
    final double dangerD = Math.sqrt(        (1.0 + Math.sqrt(2.0))          );
    static boolean mate = false;
    static boolean check;
    static int[] XCoords = new int[8];//goes with distances[8]
    static int[] YCoords = new int[8];//goes with distances[8], the square coords
    static double[] distances = new double[8];
    static int distanceIndex = 0;
    static boolean reset = false;
    
    /** Creates a new instance of chessAgent */
    public chessAgent() {
        System.out.println("con running");
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                
                QT[i][j] = false;
                KT[i][j] = false;
                ET[i][j] = false;
                
            }
        }
        genRandom();
        setKT();
        setET();
        setQT();
        setLimit();
        
        
    }
    
    public static void main(String args[]) {
        
        //BEGIN a series of movement options, IF "this" move here, continue MAINLOOP
        
        chessAgent agent = new chessAgent();
        
        MAINLOOP: while(true) {
            distanceIndex = 0;
            //System.out.println("Current Limit is"+limit);
    
            printBoard();

            input();
            setKT();
            setET();
            setQT();
            setLimit();
            
            if(limit==0) tryForMate();
                        
            //check for: enemy in the corner, queen sqr.root 5 away - if so she's TOO CLOSE
            //queen causes stalemate by herself! otherwise the king logic should prevent stale..
            //this position will arise after a queen check to within sqrt5...
            if( (ex == 0 && ey == 0) || (ex == 7 && ey == 0) ||
                    (ex == 7 && ey == 7) || (ex == 0 && ey == 7)  ) {
                
                //enemy is in a corner check for close proximity
                double dist = dist(ex, ey, qx, qy);
                if(dist < 2.83) {
                    
                    moveQueenRandomly();
                    continue MAINLOOP;
                 
                }
 
            }
       
            /* This is the first basic choice:is the queen on limiting axis? 
             * if she's not she tries to move to it. 
             * the move must: 1. be legal 2. not induce stalemate 
             * and 3. king must not be on the axis you are moving to! 
             * (your king can block the qu and enemy can escape into the 'limiting' file)
             * if no moves are found, move randomly
             * This is the first of TWO MAIN paths in the MAINLOOP:
             * 1. queen's not on limiting rank? MOVE QUEEN TO LIMIT
             * 2. queen's on limit rank? KING CHASE
             * with some other checks thrown in - "step down" logic, getting the king 
             * out the queen's way, etc
             *
             * 
             */             
            while (isQLimit() == false) {
                
                
                //check SANDWICH
                if(isKingSandwich()) {
                    moveRandomly();
                    continue MAINLOOP;
                    
                }
                
                if(axis == 'X') {
                    
                    int newX = ex - 1;
                    for(int i=0;i<8;i++){
                        
                        if(legalForQueen( newX,  i  ) && (inducesStaleQ(newX, i) == false) && (kx != newX)){
                            
                            //success
                            qx = newX;
                            qy = i;
                            System.out.println("\n\n\nMy move:queen to:"+qx + ":" + qy);
                            continue MAINLOOP;
                        }
                    }//end for loop
                    moveRandomly();
                    continue MAINLOOP;
                    
                } else if(axis == 'x') {
                    int newX = ex + 1;
                    for(int i=0;i<8;i++){
                        
                        if(legalForQueen( newX,  i  ) && (inducesStaleQ(newX, i) == false && kx != newX)  ) {
                            
                            //success
                            qx = newX;
                            qy = i;
                            System.out.println("\n\n\nMy Move:queen to:" + qx + ":" + qy);
                            continue MAINLOOP;
                        }
                    }//end for loop
                    moveRandomly();
                    continue MAINLOOP;
                }
                
                else if(axis == 'Y') {
                    int newY = ey - 1;
                    //cycle x's
                    for(int i=0;i<8;i++){
                        
                        if(legalForQueen( i, newY ) && inducesStaleQ(i, newY) == false && ky != newY        ){
                            
                            //success
                            qy = newY;
                            qx = i;
                            System.out.println("\n\n\nMy Move:queen to:" + qx + ":" + qy);
                            continue MAINLOOP;
                        }
                    }//end for loop
                    moveRandomly();
                    continue MAINLOOP;
                } else if(axis == 'y') {
                    //System.out.println("axis:y");
                    int newY = ey + 1;
                    for(int i=0;i<8;i++){
                        
                        if(legalForQueen( i, newY ) && inducesStaleQ(i, newY) == false && ky != newY ){
                            
                            //success
                            qy = newY;
                            qx = i;
                            System.out.println("\n\n\nMy move:queen to:" + qx + ":" + qy);
                            continue MAINLOOP;
                        }
                    }//end for loop
                    moveRandomly();
                    continue MAINLOOP;
                }
                
            }//end QLimit loop
            
            //OK IF WE ARE HERE QUEEN *IS* ON LIMITING RANK
            //first check for a few conditions where king is blocking queen...
            //if both kings are on a back file, move king randomly (queen is on limit since we GOT to this pt)
            if((ex == 0 && kx == 0) || (ex == 7 && kx == 7) || (ey == 0 && ky == 0) || (ey == 7 && ky == 7) ) {
                
                moveKingRandomly();
                continue MAINLOOP;
                
            }
            
            if(isSquareOnQueensAxis(kx, ky)) {
                moveKingRandomly();
                continue MAINLOOP;
            }
            
            //check for STEP DOWN now(the force back queen move)
            //if there are 3 squares true in both threatened then step down
            int shared = 0;
            for(int i = 0; i<8; i++) {
                for(int j = 0; j<8; j++) {
                    
                    if(KT[i][j] == true && ET[i][j] == true) {
                        System.out.println("Shared king sq:"+i+":"+j);
                        shared++;
                    }
                }
            }
            
            
            //STEPDOWN
            if ( shared > 2 ) {
                
                
                
                //step down
                if (axis == 'x'){
                    for(int i = 0; i<8; i++) {
                        
                        if(legalForQueen(ex, i )  && (inducesStaleQ(ex, i) == false)) {
                            
                            qx = ex;
                            qy = i;
                            System.out.println("My move: Quuen to"+qx+":"+qy);
                            continue MAINLOOP;
                        }
                    }
                } else if (axis == 'X') {
                    for(int i = 0; i<8; i++) {
                        
                        if(legalForQueen(ex, i ) && (inducesStaleQ(ex, i) == false)) {
                            
                            qx = ex;
                            qy = i;
                            System.out.println("My move: Quuen to"+qx+":"+qy);
                            continue MAINLOOP;
                        }
                    }
                } else if ( axis == 'y') {
                    for(int i = 0; i<8; i++) {
                        
                        if(legalForQueen(i, ey)  && (inducesStaleQ(i, ey) == false)     ) {
                            
                            qx = i;
                            qy = ey;
                            System.out.println("My move: Quuen to"+qx+":"+qy);
                            continue MAINLOOP;
                            
                        }
                    }
                } else if ( axis == 'Y') {
                    for(int i = 0; i<8; i++) {
                        
                        if(legalForQueen(i, ey) && (inducesStaleQ(i, ey) == false)   ) {
                            
                            qx = i;
                            qy = ey;
                            System.out.println("My move: Quuen to"+qx+":"+qy);
                            continue MAINLOOP;
                        }
                    }
                } else { System.out.println("can't step down!?");
                
                }
                
            }
            //PAUSE KING TO PREVENT BACK AND FORTH LOOP
            if(shared == 2) {
                
                //move Queen to
                if (axis == 'x' || axis == 'X'){
                    //slide king vertically to first legal spot
                    for(int i = 0; i<8; i++){
                        if(legalForQueen(qx, i) && (inducesStaleQ(qx, i) == false)) {
                            
                            qy = i;
                            qx = qx;
                            System.out.println("Queen slides to:"+qx+":"+qy);
                            continue MAINLOOP;
                        }
                    }
                }
                if ( axis == 'y' || axis == 'Y') {
                    //slide queen horizontally
                    for(int i = 0; i<8; i++){
                        if(legalForQueen(i, qy) && (inducesStaleQ(i, qy) == false)) {
                            
                            qy = qy;
                            qx = i;
                            System.out.println("\nQueen slides to:"+qx+":"+qy);
                            continue MAINLOOP;
                        }
                    }
                    
                }
                
            } //end if shared==2 block
            
            
            
            //KING CHASE - last option!
            //KING CHASE time if we get here without 'continuing' MAINLOOP
            for(int i = 0; i<8; i++){
                for (int j = 0; j<8; j++){
                    
                    if(legalForKing(i,j) && inducesStaleK(i,j) == false)    {
                        
                        //gather distances (with *corresponding coords)
                        //but don't add the squares in the queen's axis!!!
                        
                        if(!(isSquareOnQueensAxis(i,j))) {
                            
                            distances[distanceIndex] = dist(i, j, ex, ey);
                            XCoords[distanceIndex] = i;
                            YCoords[distanceIndex] = j;
                            //System.out.println("legal for King:" + i + ":" + j + "");
                            System.out.println("changeInDistanceIndex:"+(++distanceIndex));
                        }
                        
                    }
                    //select smallest
                    
                }
            }
            //always 8! ->System.out.println(distances.length);
            /*for(int i=0; i<distanceIndex; i++){
             
                System.out.println("distance"+i+"="+distances[i]);
            }*/
            
            //OK DISTANCES WITH CORRESPONdinG COORDS COMPUTED
            //compute smallest distance
            
            double smallest = distances[0];
            int smallestX = XCoords[0];
            int smallestY = YCoords[0];
            
            for(int i = 1; i<distanceIndex; i++) {
                if (distances[i] < smallest) {
                    smallest = distances[i];
                    //System.out.println("Distance:"+ smallest);
                    smallestX = XCoords[i];
                    smallestY = YCoords[i];
                    
                }
                
            }
            //OK the smallest is computed
            //it's legal, SUCCESS
    
            kx = smallestX;
            ky = smallestY;
            System.out.println("\n\n\nMy Move:King:"+kx+":"+ky);
            
            
            continue MAINLOOP;
            
            
        }//end main loop
        
    }//END OF MAIN METHOD***
    //methods
    
    static boolean isQLimit(){
        System.out.println("QLimit() called.\n");
        
        if (axis == 'x'){
            //System.out.println("axis="+axis+"\n");
            return(qx == ex + 1);
        } else if (axis == 'X') {
            //System.out.println("axis="+axis+"\n");
            return(qx == ex - 1);
        } else if ( axis == 'y') {
            //System.out.println("axis="+axis+"\n");
            return(qy == ey +1);
        } else if ( axis == 'Y') {
            //System.out.println("axis="+axis+"\n");
            return(qy == ey - 1);
        } else {
            System.out.println("No Axis defined? Queen not on limit.");
            return(false);
        }
    }
    
    static void setLimit() {
        
        System.out.println("setLimit():posEnemy:"+ex+":"+ey+",limit="+limit+",axis="+axis);
        int smallest;
        char newAxis;
        char oldAxis = axis;
        int oldLimit = limit;
        //System.out.println("setLimit():old limit:"+oldLimit);
        int YL = 7 - ey;
        int yL = ey;
        int XL = 7 - ex;
        int xL = ex;
        
        System.out.println("YL:"+YL+":yl:"+yL+":XL:"+XL+":xL:"+xL);
        
        smallest = YL; newAxis = 'Y';
        
        if (yL < smallest) { smallest = yL; newAxis = 'y'; }
        if (XL < smallest) { smallest = XL; newAxis = 'X'; }
        if (xL < smallest) { smallest = xL; newAxis = 'x'; }
        
        //System.out.println("SetLImit():new limit:"+smallest);
        //if new smallest is still equal to limit, then just keep old axis
        /*if( limit == smallest && ) {
            System.out.println("SetLimit():No improve, keeping axis:"+axis);
            return;
        }*/
        //if limit is zero and axis changed but the enemy position is a corner spot, do NOT change axis
        if( limit == 0 && axis != newAxis && (     (ex==0&&ey==0) || (ex==0&&ey==7) || (ex==7&&ey==7) || (ex==7&&ey==0)   )   ){
            System.out.println("SetLimit():corner move, Keeping Axis:"+axis);
            return;
        }
        axis = newAxis;
        limit = smallest;
        System.out.println("SetLimit():axis is:"+axis+",limit is:"+limit);
        
    }
    
    static double dist(int x1, int y1, int x2, int y2) {
        
        double xd = (x2 - x1);
        double yd = (y2 - y1);
        double temp1 = Math.sqrt(Math.pow(xd,2.0) + Math.pow(yd,2.0)   );
        System.out.println("dist:"+x1+":"+y1+" to "+x2+":"+y2+" is:"+temp1);
        return(Math.sqrt(Math.pow(xd,2.0) + Math.pow(yd,2.0)   )   );
        
    }
    
    
    
    static void input() {
        if(isCheck()) {
            
            System.out.println("Check!");
            
        }
        System.out.println("Your move.\n");
        System.out.flush();
        boolean legal = false;
        while(!legal) {
            
            int userX, userY;
            System.out.println("Enter X:");
            System.out.flush();
            userX = TextIO.getInt();
            System.out.println("You entered x:"+userX);
            System.out.println("enter Y:");
            System.out.flush();
            userY = TextIO.getInt();
            System.out.println("You entered y:"+userY);
            
            if(!legalForEnemy(userX, userY)) {
                System.out.println("Not a legal move!");
            } else {
                ex = userX;
                ey = userY;
                legal = true;
            }
            
        }
        
    }
    
    static void setQT() { //Queen Threatened
        int x = qx;
        int y = qy;
        
        //reset QT first
        for(int i=0; i<8; i++) {
            for(int j=0; j<8; j++) {
                QT[i][j] = false;
            }
        }
        
        if(QT == null) System.out.println("\nqt null???!!!\n");
        
        //set west vector to threatened
        while(x != -1) {
            if(kx==x && ky==y){
                //System.out.println("setQTw:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQTw:no kings on:"+x+":"+y);
            QT[x--][y] = true;
        }
        
        x = qx; y = qy;
        //set east vector to threatened
        while(x != 8) {
            if(kx==x && ky==y){
                //System.out.println("setQTE:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQTe:no kings on:"+x+":"+y);
            QT[x++][y] = true;
            
        }
        
        x = qx; y = qy;
        //set South vector to threatened
        while(y != -1) {
            if(kx==x && ky==y){
                //System.out.println("setQTs:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQTs:nobody on:"+x+":"+y);
            QT[x][y--] = true;
        }
        
        x = qx; y = qy;
        //set north vector to threatened
        while(y != 8) {
            if(kx==x && ky==y){
                //System.out.println("setQTn:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQTn:nobody on:"+x+":"+y);
            QT[x][y++] = true;
            
        }
        x = qx; y = qy;
        //set northeast vector to threatened
        while(y != 8 && x != 8) {
            if((kx == x && ky == y)) {
                //System.out.println("setQTNE:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT:Ne:nobody on:"+x+":"+y);
            QT[x++][y++] = true;
        }
        x = qx; y = qy;
        //set southeast diagonal to threatened
        while(x != 8 && y != -1) {
            if (kx == x && ky == y) {
                //System.out.println("setQTSE:king at:"+x+":"+y);
                break; }
            
            //System.out.println("setQT:se:nobody on:"+x+":"+y);
            QT[x++][y--] = true;
        }
        
        //set southwest diagonal
        x = qx; y = qy;
        while(x != -1 && y != -1) {
            if ((kx == x) && (ky == y) ) {
                //System.out.println("setQTSW:king at:"+x+":"+y);
                break;
            }
            
            //otherwise continue adding/incrementing till boundary
            //System.out.println("setQT:sW:nobody on:"+x+":"+y);
            QT[x--][y--] = true;
        }
        
        //set northwest vector to threatened
        x = qx; y = qy;
        while(x != -1 && y != 8)  {
            
            if(kx == x && ky == y) {
                //System.out.println("setQTNW:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT:NW:nobody on:"+x+":"+y);
            QT[x--][y++] = true;
        }
        
        /*//print summary
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
         
                if(QT[i][j] == true){
         
                    System.out.println("setQTsummary:"+i+":"+j+" is threatened by Queen.");
         
                }
            }
        }*/
      
        
    }//end function
    
    static void setKT() {
  
        //reset all squares first
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                KT[i][j] = false;
            }
        }
        
        KT[kx][ky] = true;
        if(kx < 7) {KT[kx+1][ky] = true; } //System.out.println((kx+1)+":"+ky);}
        if(kx > 0) {KT[kx-1][ky] = true; } //System.out.println((kx-1)+":"+ky);}
        if(kx > 0 && ky < 7) {KT[kx-1][ky+1] = true; } //System.out.println((kx-1)+":"+(ky+1));}
        if( ky<7) {KT[kx][ky+1] = true; } //System.out.println((kx)+":"+(ky+1));}
        if( ky > 0 ) { KT[kx][ky-1] = true; } //System.out.println(kx+":"+(ky-1));}
        if (kx<7 && ky < 7) {KT[kx+1][ky+1] = true; } //System.out.println((kx+1)+":"+(ky+1));}
        if(kx> 0 && ky > 0) {KT[kx-1][ky-1] = true; } //System.out.println((kx-1)+":"+(ky-1));}
        if(kx < 7 && ky > 0) {KT[kx+1][ky-1] = true; } //System.out.println((kx+1)+":"+(ky-1)+"*");}
        
        
    }
    
    static void setET() {
    
        /*for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
               System.out.println("ET:"+i+":"+j+":"+ET[i][j] +":");
            }
        }*/
        
        //reset all squares first
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                ET[i][j] = false;
            }
        }
        
        //System.out.println("SetET:pos:"+ex+":"+ey);
        ET[ex][ey] = true;
        if(ex<7) {ET[ex+1][ey] = true; } //System.out.println((ex+1)+":"+ey);}
        if(ex > 0) {ET[ex-1][ey] = true;  } //System.out.println((ex-1)+":"+ey);}
        if(ex > 0 && ey < 7) {ET[ex-1][ey+1] = true; } //System.out.println((ex-1)+":"+(ey+1));}
        if( ey<7) {ET[ex][ey+1] = true; } //System.out.println((ex)+":"+(ey+1));}
        if(ey>0) {ET[ex][ey-1] = true; } //System.out.println((ex)+":"+(ey-1));}
        if (ex<7 && ey<7) {ET[ex+1][ey+1] = true; } //System.out.println((ex+1)+":"+(ey+1));}
        if(ex> 0 && ey > 0) {ET[ex-1][ey-1] = true; } //System.out.println((ex-1)+":"+(ey-1));}
        if(ex < 7 && ey > 0) {ET[ex+1][ey-1] = true; } //System.out.println((ex+1)+":"+(ey-1)+"*");}
        //System.out.println("setET done-----------");
        
        
        /*for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
         
                if(ET[i][j] == true) {
         
                    System.out.println("ET:"+i+":"+j+":"+ET[i][j] +":");
                }
         
            }
        }//end outer*/
        
        
        
        
    }
    
    static boolean legalForQueen(int x, int y) {
        
        //self and own king check
        if((kx == x && kx == y) || (qx == x && qy == y)) return false;
        
        
        try {
            
            //if it's reachable (threatened) by the queen
            if(QT[x][y] == true){
                
                //if not threatened by king OR is adjacent my king
                if(ET[x][y] == false || KT[x][y] == true) {
                    System.out.println(x+":"+y+":legalforQueen");
                    return true;
                } else {
                    //System.out.println(x+":"+y+":illegalforQueen");
                    return false;
                }
                
            } else {
                //else it's not spatially legal
                return false; }
            
        } catch(ArrayIndexOutOfBoundsException e) {
            
            System.out.println("Tested non existent square for legality!");
            return false;
            
        }
        
    }
    static boolean legalForKing(int i, int j) {
        //check ya self 'fore ya wreck ya self
        if(kx==i && ky==j) {
            System.out.println("Self Square-illegalforKing:"+i+":"+j+"\n");
            return false;
        }
        /*if (KT[i][j] == true){
           System.out.println(i+ ":" +j+"is adj K|");}
        if(ET[i][j] == false){
            System.out.println(i+":"+j+"is not adj E|");}
        if(i != qx || j != qy) {
            System.out.println(i+":"+j+" not occupied by Queen");
        }*/
        
        if(KT[i][j] == true && ET[i][j] == false && (i != qx || j != qy)) {
            System.out.println("legalForKing:"+i +":"+j+ " legal for King.\n");
            return true;
        } else {
            //System.out.println("legalForKing:illegal:"+i+":"+j+"\n");
            return false;
        }
    }//end func
    
    
    
    
    static boolean legalForEnemy(int i, int j) {
        //check ya self 'fore ya wreck ya self
        if(ex==i && ey==j) {
            
            System.out.println("Self Square-illegalforEnemy:"+i+":"+j+"\n");
            return false;
        }
        
        try {
        if (ET[i][j] == true){
            //System.out.println(i+ ">:" +j+"is adj Me|");
        }
        if(KT[i][j] == false){
            //System.out.println(i+">:"+j+"is not adj K|");
        }
        if(QT[i][j] == false) {
            //System.out.println(i+">:"+j+" not threatened by Queen");
        }
        
        if(ET[i][j] == true && KT[i][j] == false && QT[i][j] == false) {
            System.out.println("legalForEnemy:"+i +":"+j+":legal for enemy.\n");
            return true;
        } else {
            System.out.println("legalForEnemy:"+i +":"+j+ " illegal for enemy.\n");
            return false; }
        } catch (ArrayIndexOutOfBoundsException e) {
            return false;
        }
        
    }
    
    static private void printBoard() {
        //reset = false;
        //System.out.println("white king:"+kx+":"+ky);
        //System.out.println("white queen:"+qx+":"+qy);
        //System.out.println("black king:"+ex+":"+ey+"\n");
        int rowNum = 7;    //(current row starting from the top!)
        int i = 0; //index (corresponds to columns)
        /*note that for the printing, i determines
         *what COLUMN you are in, and corresponds to the X VALUE of the piece coords.
         *while rowNum indicates which ROW is printing and corresponds to
         the Y Value of the piece coords. so kx == i makes sense, etc.*/
        
        LOOP:
            while(rowNum > -1) {
                
                for (i = 0; i<8; i++) {
                    if (kx == i && ky == rowNum)  { System.out.print(" K");
                    System.out.flush(); } else if (qx == i && qy == rowNum) { System.out.print(" Q");
                    System.out.flush(); } else if (ex == i && ey == rowNum) { System.out.print(" k");
                    System.out.flush(); } else {  System.out.print(" _");
                    //System.out.print(" r"+rowNum+"c"+i);
                    System.out.flush();
                    }
                } //end row printing loop
                if (i == 8) {
                    i = 0;
                    rowNum--;
                    System.out.print(" "+(rowNum+1)+"\n");
                    System.out.flush();
                }
                
            } //end while loop
            System.out.print(" 0 1 2 3 4 5 6 7\n");
            System.out.println("\n");
            if(mate==true) {  System.out.println("Check Mate:"+qx+","+qy+".\n Thanks For Playing :)\n");
            
            
                /*System.out.println("Play again? y/n");
                char answer = TextIO.getlnChar();
                if(answer == 'N' || answer == 'n') {*/
                System.exit(0);
                
                
                }
                
                /*else, let's keep playin :)
                mate = false;
                reset = true;
                genRandom();
                return(1);*/
          
            

    } //end PrintBoard func
    
    
    static void checkForMate() {
        //cycle ET, check for legal
        //while (next one isn't null)
        //check legals
        System.out.println("Checking for mate..limit="+limit+"\n");
        int legalsForEnemy = 0;
        for(int i=0; i<8; i++) {
            for(int j=0; j<8; j++) {
                

                if (ET[i][j] == true) {
                    
                    //OK, if we'return here, it's adjacent,(or self), check
                    //to see if it is LEGAL
                    //reproducing isLegalForEnemy but whatever
                    //if not self AND not KT and not QT_temp, it's legal!
                    if(  (i != ex || j != ey) && KT[i][j] == false && QT_temp[i][j] == false) {
                        
                        System.out.println("checkForMate:"+i+":"+j+" is legal for enemy.\n");
                        legalsForEnemy++;
                    }
                }
            }
        }//end outer for
        if(legalsForEnemy == 0){
            mate = true;
        } else {
            //found no mates, set QT back to the real position
            System.out.println("checkForMate found no mates.\n");
            //else do nothing, mate still == false...
        }
        
    }//end checkformate
    
    static void tryForMate() {
        
            /*cycle legals, set 'threatened' for each, check "check", checkForMate
             *set "threatened" for every legal move
             *this will be like setQT basically repeated here
             *but i'm not gonna rewrite that function!
             */
        
        
        //cycle legals
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                if(legalForQueen(i,j)) {
                    //System.out.println("Legal for queen:"+i+":"+j);
                    
                    setQT_temp(i,j);
                    
                   /* if(QT_temp[i][j] == true) {
                            System.out.println("setQT_temp:"+i+":"+j+" is threatened by Queen.");
                    
                     }*/
                    
                    /*OK. all 'vectors' have been added - all threatened squares by the
                     *queen in her 'asterisk' pattern accounted for, for this i, j.
                     *check for check*/
                    
                    if(QT_temp[ex][ey] == true){
                        System.out.println("legal and check:"+i+":"+j+"\n");
                        //if it's check, check for mate..
                        check = true;//for use elswhere in printing
                        //if here, this i,j is a legal move, but checkforMate looks at the real
                        //coords so temporarlily set vars as appr.
                        int realQx = qx;
                        int realQy = qy;
                        qx = i; qy = j;
                        checkForMate();
                        
                        if(mate == true){
                            printBoard();
                        } else {
                            
                            System.out.println("check but not checkmate:"+i+":"+j+"\n");
                            qx = realQx;
                            qy = realQy;
                            
                        }
                    }
                    
                    
                }//end islegal IF block
            }//end inner for
        }//end outer for
    
        
    } //end TRYFORMATE
    
    static boolean isSquareOnQueensAxis(int x, int y) {
        
        if(axis == 'x' || axis == 'X'){
            //if square has same x value then it is
            if(x == qx) {
                return true;
            } else { return false; }
        } else if (axis == 'y' || axis == 'Y') {
            if(y == qy) {
                return true;
            } else { return false; }
        } else {
            System.out.println("this shouldn't have happened.");
            return false;
        }
    }//end func
    
    static void setQT_temp(int queenx, int queeny) {
        
        System.out.println("entering setQT TEMP func");
        
        //reset QT_temp
        for(int k = 0; k<8; k++) {
            for(int m = 0; m<8; m++) {
                QT_temp[k][m] = false;
            }
        }
        
        int x = queenx;
        int y = queeny;
        
        QT_temp[queenx][queeny] = true;
        
        if(QT_temp == null) System.out.println("\nQT_temp null???!!!\n");
        
        //set west vector to threatened
        while(x != -1) {
            if(kx==x && ky==y){
                System.out.println("setQT_tempw:king at:"+x+":"+y);
                break;
            }
            if(ex==x && ey==y){
                System.out.println("setQT_tempw:enemy king at:"+x+":"+y);
                //QT_temp[x--][y] = true;
                //break;
                //queen pierces enemy and threatens the whole file REGARDLESS!
                
            }
            //System.out.println("setQT_tempw:no kings on:"+x+":"+y);
            QT_temp[x--][y] = true;
        }
        
        
        
        x = queenx; y = queeny;
        //set east vector to threatened
        while(x != 8) {
            if(kx==x && ky==y){
                System.out.println("setQT_tempE:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT_tempe:no kings on:"+x+":"+y);
            QT_temp[x++][y] = true;
            
        }
        
        x = queenx; y = queeny;
        //set South vector to threatened
        while(y != -1) {
            if(kx==x && ky==y){
                System.out.println("setQT_temps:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT_temps:nobody on:"+x+":"+y);
            QT_temp[x][y--] = true;
        }
        
        x = queenx; y = queeny;
        //set north vector to threatened
        while(y != 8) {
            if(kx==x && ky==y){
                System.out.println("setQT_tempn:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT_tempn:nobody on:"+x+":"+y);
            QT_temp[x][y++] = true;
            
        }
        x = queenx; y = queeny;
        //set northeast vector to threatened
        while(y != 8 && x != 8) {
            if((kx == x && ky == y)) {
                System.out.println("setQT_tempNE:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT_temp:Ne:nobody on:"+x+":"+y);
            QT_temp[x++][y++] = true;
        }
        x = queenx; y = queeny;
        //set southeast diagonal to threatened
        while(x != 8 && y != -1) {
            if (kx == x && ky == y) {
                System.out.println("setQT_tempSE:king at:"+x+":"+y);
                break; }
            
            //System.out.println("setQT_temp:se:nobody on:"+x+":"+y);
            QT_temp[x++][y--] = true;
        }
        
        //set southwest diagonal
        x = queenx; y = queeny;
        while(x != -1 && y != -1) {
            if ((kx == x) && (ky == y) ) {
                System.out.println("setQT_tempSW:king at:"+x+":"+y);
                break;
            }
            
            //otherwise continue adding/incrementing till boundary
            //System.out.println("setQT_temp:sW:nobody on:"+x+":"+y);
            QT_temp[x--][y--] = true;
        }
        
        //set northwest vector to threatened
        x = queenx; y = queeny;
        while(x != -1 && y != 8)  {
            
            if(kx == x && ky == y) {
                System.out.println("setQT_tempNW:king at:"+x+":"+y);
                break;
            }
            
            //System.out.println("setQT_temp:NW:nobody on:"+x+":"+y);
            QT_temp[x--][y++] = true;
        }
        
        /* //print summary
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
         
                if(QT_temp[i][j] == true) {
         
                    System.out.println("setQT_temp_summary:"+i+":"+j+" is threatened by queen move"+queenx+":"+queeny);
                }
            }
        } //end outer for*/
    }//end func
    
    
    static void moveKingRandomly() {
        System.out.println("examining king moves...");
        while(true) {
            //move randomly
            Random gen = new Random();
            int randomX = gen.nextInt(8);
            int randomY = gen.nextInt(8);
            
            if(legalForKing(randomX, randomY) && (inducesStaleK(randomX, randomY) == false)       ) {
                
                //move here
                System.out.println("\n\n\nKing Move!? "+randomX+":"+randomY);
                kx = randomX;
                ky = randomY;
                return;
            }
        }//end while(true) loop
    }
    
    static void moveQueenRandomly() {
        System.out.println("examining queen moves...");
        while(true) {
            //move randomly
            Random gen = new Random();
            int randomX = gen.nextInt(8);
            int randomY = gen.nextInt(8);
            
            if(legalForQueen(randomX, randomY) && (inducesStaleQ(randomX, randomY) == false)       ) {
                
                //move here
                System.out.println("\n\n\nQueen Move!? "+randomX+":"+randomY);
                qx = randomX;
                qy = randomY;
                return;
            }
        }//end while(true) loop
        
    }
    
    static void moveRandomly() {
        
            System.out.println("Thinking...");
            Random gen = new Random();
        int whichToMove = gen.nextInt(2);
           // System.out.println("randommove:"+whichToMove);
            int randomX = gen.nextInt(8);
            int randomY = gen.nextInt(8);
        
            if(whichToMove == 1) {
                moveQueenRandomly();
            } else {
                moveKingRandomly();
            }
    
        
    }
    static boolean isCheck() {
        setQT();
        if(QT[ex][ey] == true) {
            return true;
        } else { return false; }
        
    }
    
    static boolean isKingSandwich() {
        //if they all share the SAME FILE, and it's my turn, the King is in
        //the middle (otherwise he's checked and it's my move!
        if((qx == kx && kx == ex) || (qy == ky && ky == ey) ) {
            return true;
        } else { return false; }
        
    }
    
    static void genRandom() {
        
        System.out.println("Generating random legal position...");
        int queenX, queenY, enemyX, enemyY;
        
        //generate random but legal setup
        Random gen = new Random();
        kx = gen.nextInt(8);
        ky = gen.nextInt(8);
        setKT();
        boolean legal = false;
        while(!legal) {
            
            queenX = gen.nextInt(8);
            queenY = gen.nextInt(8);
            
            if(queenX != kx || queenY != ky) {
                qx = queenX;
                qy = queenY;
                legal = true;
            }
        }
        setQT();
        
        
        legal = false;
        while(!legal) {
            enemyX = gen.nextInt(8);
            enemyY = gen.nextInt(8);
            
            if(KT[enemyX][enemyY] == false && QT[enemyX][enemyY] == false ) {
                
                ex = enemyX;
                ey = enemyY;
                legal = true;
                setET();//not necessary, will be called in sec anyway in MAINLOOP
                //no, i'll call it here cuz ...e
            }
        }
        
        
    }//end gen random
    
    static void setKT_temp(int kingX, int kingY) {
        
        //reset all squares first
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                KT_temp[i][j] = false;
            }
        }
        
        if(kingX < 7) {KT_temp[kingX+1][kingY] = true; } //System.out.println((kingX+1)+":"+kingY);}
        if(kingX > 0) {KT_temp[kingX-1][kingY] = true; } //System.out.println((kingX-1)+":"+kingY);}
        if(kingX > 0 && kingY < 7) {KT_temp[kingX-1][kingY+1] = true; } //System.out.println((kingX-1)+":"+(kingY+1));}
        if( kingY<7) {KT_temp[kingX][kingY+1] = true; } //System.out.println((kingX)+":"+(kingY+1));}
        if( kingY > 0 ) { KT_temp[kingX][kingY-1] = true; } //System.out.println(kingX+":"+(kingY-1));}
        if (kingX<7 && kingY < 7) {KT_temp[kingX+1][kingY+1] = true; } //System.out.println((kingX+1)+":"+(kingY+1));}
        if(kingX> 0 && kingY > 0) {KT_temp[kingX-1][kingY-1] = true; } //System.out.println((kingX-1)+":"+(kingY-1));}
        if(kingX < 7 && kingY > 0) {KT_temp[kingX+1][kingY-1] = true; } //System.out.println((kingX+1)+":"+(kingY-1)+"*");}
        
        
    }
    
    
    static boolean inducesStaleK(int kingX, int kingY) {
        
        if( limit != 0) {
            
            System.out.println("K:limit not zero, no stalemate possible for:"+kingX+":"+kingY);
            return false;
            
        }
        
        setKT_temp(kingX, kingY);
        int legals = 0;
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                //if queen doesn't threaten, if potential king move doesn't, if it's *ajacent but not self*...
                if(QT[i][j] == false && KT_temp[i][j] == false && ET[i][j] == true && (ex != i || ey != j)) {
                    
                    //it's legal for enemy...
                    legals++;
                    
                }
            }
        }
        //if legals is zero still, stale = true
        if(legals == 0) {
            System.out.println("K:Stalemate caused by:"+kingX+":"+kingY);
            return true;
        } else {
            System.out.println("K:Stalemate not caused by:"+kingX+":"+kingY);
            return false;
        }
        
    }//end inducesStalek
    
    
    static boolean inducesStaleQ(int queenX, int queenY) {
        
        if (limit != 0) {
            
            //System.out.println("Q:limit not zero, no stalemate at:"+queenX+":"+queenY);
            return false;
            
        }
        
        setQT_temp(queenX, queenY);
        int legals = 0;
        for(int i = 0; i<8; i++) {
            for(int j = 0; j<8; j++) {
                //if queen doesn't threaten, if potential king move doesn't, if it's *ajacent but not self*...
                if(KT[i][j] == false && QT_temp[i][j] == false && ET[i][j] == true && (ex != i || ey != j)) {
                    
                    //it's legal for enemy...
                    legals++;
                    
                }
            }
        }
        //if legals is zero still, stale = true
        if(legals == 0) {
            System.out.println("Q:Stalemate caused by:"+queenX+":"+queenY);
            return true;
        } else {
            
            System.out.println("Q:Stalemate not caused by:"+queenX+":"+queenY);
            return false;
        }
     
    }
} //END CLASS
