/*
    Pawn races
*/

#include "evaluate.h"

#define QUEENED 400

int w_passer_wins(int p)
{
    
    int pf = p&7;
    int qs = A1 + pf;
    int f = kingsq[1];
    int ff = f&7;
    int fr = (f>>4)-4;
    int e = kingsq[0];
    int er = (e>>4)-4;
    int e2q, e2p, f2p, f2q;
    int rp = (pf == 0 || pf ==7);
    
    /* calc p distance to q  */
    int p2q = (p >> 4) - 4;

    assert(((p-A1) & 0x88) == 0);
    
    /* adjust for 2 hops */
    p2q -= (p2q == 6 && f != p-16 && f != p-32);
    
    /* adjust tempo for king in the way */
    p2q += (ff == pf && f < p);  
            
    /* calc nme k distance to q sq */
    e2q = distance[128+e-qs];// - 1 + stm;
    
    /* QUICK EXIT: race is clearly won */
    if(e2q > p2q) return QUEENED - p2q;
    
    /* calc friendly k distance to pawn */
    f2p = distance[128+f-p] - stm;
    
    /* calc nme k distance to pawn */
    e2p = distance[128+e-p];// - 1 + stm;
    
    /* 
        adjust for approach thru pawn attack 
        white pawn, black king attack, 
        neg is down(& right) , bp wk  wk > bp
        bk above (<) pawn
    */
    e2p += (vectors[136 + p - e] == -15 || vectors[136 + p - e] == -17);
    
    /* adjust for rook pawns  */
    /* ??? e2p -= rp; */
    
    /* nme king is clearly closer */
    if(e2p+1 < f2p) return -MATE;
    
        
    f2q = distance[128 + f - qs] - stm;
    
    if(rp)
    {
        if(e2q - 1 - (ff == pf) < f2q) return -MATE;
        /* else return QUEENED - p2q; */
    }
    
    //return -MATE;

    /* FITH RANK  A King on any of the three squares of the sixth row ahead 
    of his own pawn can win regardless of who moves first.*/
    
    
    /*
	following based on GNU Chess 5.0
    */
    if(p2q <= 3 && abs(ff-pf) < 2)
    {
	    /*friendly king leads by 2 squares*/
	    if(p2q > fr + 1) return QUEENED - p2q;
	    /*friendly king leads by 1 square, and ...*/
	    if(p2q == fr + 1)
	    {
		    /* Friendly KING Is on the 6th rank. enm cannot be near it*/
		    if(fr == 2) return QUEENED - p2q;
		    /*Or, <= 5th rank, and ...*/
		    if(fr > 2)
		    {
			    /* King cannot progress forward */
			    if(e == f - 32 && stm == WHITE) return -MATE;
			    return QUEENED - p2q;
		    }
	    }
	    if(p2q == fr)
	    {
		    if((fr - er < 2 || fr - er > 4) && stm == WHITE) return QUEENED - p2q;
		    if((fr - er < 1 || fr - er > 5) && stm == BLACK) return QUEENED - p2q;
		    if(p2q == 2 && e != f - 32) return (stm == WHITE)? QUEENED - p2q : -MATE;
	    }
	    if(p2q == 1 && fr == 2) 
	    {
		    assert(e2q < 2);
		    if(e != qs) return (stm == WHITE)? QUEENED - p2q : -MATE;
		    else if(f == qs + 32) return (stm == WHITE)? QUEENED - p2q : -MATE;
	    }
    }

   
    return -MATE;
}

int b_passer_wins(int p)
{
    
    int pf = p&7;
    int qs = A8 + pf;
    int f = kingsq[0];
    int ff = f&7;
    int fr = 11 - (f>>4);
    int e = kingsq[1];
    int er = 11 - (e>>4);
    int e2q, e2p, f2p, f2q;
    int rp = (pf == 0 || pf ==7);
    
    /* calc p distance to q  */
    int p2q = 11 - (p >> 4);
    
    assert(((p-A1) & 0x88) == 0);
    /* adjust for 2 hops */
    p2q -= (p2q == 6 && f != p+16 && f != p+32);
    
    /* adjust for king in the way */
    p2q += (ff == pf && f < p);
            
    /* calc nme k distance to q sq */
    e2q = distance[128+e-qs];// - stm;
    
    /* race is clearly won */
    if(e2q > p2q) return QUEENED - p2q;
    
    /* calc friendly k distance to pawn */
    f2p = distance[128+f-p] - 1 + stm;
    
    /* calc nme k distance to pawn */
    e2p = distance[128+e-p];// - stm;
    
    /* 
        adjust for approach thru pawn attack 
        black pawn, white king attack, 
        neg is down(& right)
        wk below (>) pawn
    */
    e2p += (vectors[136 + p - e] == 15 || vectors[136 + p - e] == 17);
    
    /* adjust for rook pawns  */
    /* e2p -= rp; */
    
    /* nme king is clearly closer */
    if(e2p+1 < f2p) return -MATE;
    
    
    f2q = distance[128 + f - qs] - 1 + stm;
        
    
    if(rp)
    {
        if(e2q - 1 - (ff == pf) < f2q) return -MATE;
        /* return QUEENED - p2q; */
    }
    
    //return -MATE;

    /* FIFTH RANK  A King on any of the three squares of the sixth row ahead 
    of his own pawn can win regardless of who moves first.*/
    /*if(p2q <= 3 && fr >= 8-p2q && abs(ff-pf) < 2) return QUEENED - p2q;*/


    /*
	following based on GNU Chess 5.0
    */
    if(p2q <= 3 && abs(ff-pf) < 2)
    {
	    if(p2q > fr + 1) return QUEENED - p2q;
	    if(p2q == fr + 1)
	    {
		    if(fr == 2) return QUEENED - p2q;
		    if(fr > 2)
		    {
			    if(e == f + 32 && stm == BLACK) return -MATE;
			    return QUEENED - p2q;
		    }
	    }
	    if(p2q == fr)
	    {
		    if((fr - er < 2 || fr - er > 4) && stm == BLACK) return QUEENED - p2q;
		    if((fr - er < 1 || fr - er > 5) && stm == WHITE) return QUEENED - p2q;
		    if(p2q == 2 && e != f + 32) return (stm == BLACK)? QUEENED - p2q : -MATE;
	    }
	    if(p2q == 1 && fr == 2)
	    {
		    assert(e2q < 2);
		    if(e != qs) return (stm == BLACK)? QUEENED - p2q : -MATE;
		    else if(f == qs - 32) return (stm == BLACK)? QUEENED - p2q : -MATE;
	    }
    }
    
    
    return -MATE;
}
