package Cluedo.g1;

abstract class ClueProblem {
    private int _n;          // number of cards
    private int _p;          // number of players
    private int _c;          // number of cards that each player holds
    private int _k;          // number of cards on the stake

    static java.util.Random _rand = new java.util.Random();

    public ClueProblem( int n, int p, int c ) {
        _n = n;
        _p = p;
        _c = c;
        _k = n - p * c;
    }

    public final int n() {
        return _n;
    }

    public final int p() {
        return _p;
    }

    public final int c() {
        return _c;
    }

    public final int k() {
        return _k;
    }

    static int[] randomReorder( int[] cards ) {
        int[] ret = new int[cards.length];
        for ( int i=0; i<cards.length; i++ )
            ret[i] = cards[i];
        for ( int i=0; i<cards.length; i++ )
        {
            int rnd = _rand.nextInt( cards.length-i );
            int tmp = ret[i+rnd];
            ret[i+rnd] = ret[i];
            ret[i] = tmp;
        }
        return ret;
    }

    /** tell the solver the idx-th player owns at least n1 of cards,
     * and at most n2 of them.
     */
    abstract void owns( int idx, int[] cards, int n1, int n2 );

    /** observes other players' interrogations
     */
    abstract void observe( int interrogator, int interrogatee, int[] cards, boolean response );

    /** find a best player to quest
     */
    abstract int who();

    /** ask the idx-th player a question 
     */
    abstract int[] quest( int idx );

    /** reply a question from the idx-th player
     */
    abstract int reply( int idx, int[] cards );

    /** get the rate of knowledge to the cards on the stake
     */
    abstract double rate();

    /** return a best guess of cards on the stake
     */
    abstract int[] guess();

    /** resize an input array to size n
     */
    static int[] resizeArray( int[] array, int n ) {
        if ( 0 == n )
            return null;

        int[] ret = new int[n];
        System.arraycopy( array, 0, ret, 0, Math.min(n, array.length) );
        return ret;
    }

    static void printcards( int[] array ) {
        for ( int i=0; i<array.length; i++ )
            System.out.print( " " + (array[i]+1) );
        System.out.println();
    }

}
