//C4Stats.java
 


/** 
 *
 * @author  Sean Bridges
 * @version 1.0
 */
public final class C4Stats implements BoardStats
{

//------------------------------------------------
    //class variables
    
    //to save time, we shift rather than multiply to find the scores
    //multipliers are 32, 4,1
    //which correspond to 5,2, 1
    //dont bother shifting by 1
    private final static int SHIFT_3_IN_A_ROW = 5; //32
    private final static int SHIFT_2_IN_A_ROW = 2; //4  

    private final static int PLAYER1 = C4Board.FIRST_PLAYER_NUMBER;
    private final static int PLAYER2 = C4Board.SECOND_PLAYER_NUMBER;

//-----------------------------------------------
    //instance variables
    protected static int p1_4InARow;
    protected static int p1_3InARow;
    protected static int p1_2InARow;
    protected static int p1_1InARow;
        
    protected static int p2_4InARow;
    protected static int p2_3InARow;
    protected static int p2_2InARow;
    protected static int p2_1InARow;
    

    
//------------------------------------------------
    //Constructor
    
    /** Creates new C4Stats */
    public C4Stats() 
    {
    }

//------------------------------------------------
    //Instance methods
    
        

    public final void p2_4InARowInc()
    {
        p2_4InARow++;
    }
    
    public final void p2_3InARowInc()
    {
        p2_3InARow++;
    }

    public final void p2_2InARowInc()
    {
        p2_2InARow++;
    }
    
    public final void p2_1InARowInc()
    {
        p2_1InARow++;
    }

    public final void p1_4InARowInc()
    {
        p1_4InARow++;
    }
    
    public final  void p1_3InARowInc()
    {
        p1_3InARow++;
    }

    public final  void p1_2InARowInc()
    {
        p1_2InARow++;
    }
    
    public final void p1_1InARowInc()
    {
        p1_1InARow++;
    }
    

    
    public final void p2_4InARowDec()
    {
        p2_4InARow--;
    }
    
    public final void p2_3InARowDec()
    {
        p2_3InARow--;
    }

    public final void p2_2InARowDec()
    {
        p2_2InARow--;
    }
    
    public final void p2_1InARowDec()
    {
        p2_1InARow--;
    }

    public final void p1_4InARowDec()
    {
        p1_4InARow--;
    }
    
    public final void p1_3InARowDec()
    {
        p1_3InARow--;
    }

    public final void p1_2InARowDec()
    {
        p1_2InARow--;
    }
    
    public final void p1_1InARowDec()
    {
        p1_1InARow--;
    }

    
//------------------------------------------------
    //evaluation
    private int firstPlayerStrength()
    {
        if(p1_4InARow != 0)
        {
            return Integer.MAX_VALUE;
        }
        else if(p2_4InARow != 0)
        {
            return 0;
        }
        else
        {
            return (p1_2InARow << SHIFT_2_IN_A_ROW) + 
                   (p1_3InARow << SHIFT_3_IN_A_ROW) +
                   p1_1InARow;
        }
    }

    private int secondPlayerStrength()
    {
        if(p2_4InARow != 0)
        {
            return Integer.MAX_VALUE;
        }
        else if(p1_4InARow != 0)
        {
            return 0;
        }
        else
        {
            return (p2_2InARow << SHIFT_2_IN_A_ROW) + 
                   (p2_3InARow << SHIFT_3_IN_A_ROW) +
                   p2_1InARow;
        }
    }
    
    
//------------------------------------------------
    //BoardStats methods
    
    
    
    /** Get the score for the given player.
     * A score is an indisputable thing, such as the number of hits in battleship.
     */
    public int getScore(Player aPlayer)
    {
        if(aPlayer.getNumber() == PLAYER1)
        {
            //Connect 4 the score only goes to 1
            if(p1_4InARow != 0)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        else //second player
        {
            //Connect 4 the score only goes to 1
            if(p2_4InARow != 0)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
    } 
    
    /**
     * Get an evaluation of how well a player is doing.
     * The number returned could be debabtable, such as a measure
     * of how strong a chess players position is.
     */
    public int getStrength(Player aPlayer)
    {
        if(aPlayer.getNumber() == PLAYER1)
        {
            return firstPlayerStrength() - secondPlayerStrength();
        }
        else
        {
            return secondPlayerStrength() - firstPlayerStrength();
        }
    }
    
    /** Returns the maximum possible hueristic.
     */
    public int getMaxStrength()
    {
        return Integer.MAX_VALUE;
    }
    /** Returns the minimum possible hueristic.
     */
    public int getMinStrength()
    {
        return Integer.MIN_VALUE;
    }
    
    /**
     * Return wether or not a player has won the game
     */
    public final boolean hasSomeoneWon()
    {
        return (p1_4InARow != 0) | (p2_4InARow != 0);
    }
    
    public String toString()
    {
        return "P1Score:" + p1_4InARow + " P2Score:" + p2_4InARow + "\n" +
               "p1Strength:" + firstPlayerStrength() + " p2Strength:" + secondPlayerStrength() + "\n" +
                "p1_4:" + p1_4InARow + " p1_3:" + p1_3InARow +  " p1_2:" + p1_2InARow + " p1_1:" + p1_1InARow + "\n" +
                "p2_4:" + p2_4InARow + " p2_3:" + p2_3InARow +  " p2_2:" + p2_2InARow + " p2_1:" + p2_1InARow;
        
    }
}