package fanch.multijeu.sudoku.data;

import fanch.multijeu.common.utils.IntUtils;

public class SmartOldSudoku extends OldSudoku {
    /**
     * Cree un sudoku a partir d'un chaine
     *
     * @param str Le sudoku:  suite de 81 numeros ('0':case vide, '1-9' numero)
     */
    public SmartOldSudoku(String str) {
        super(str);
    }

    public SmartOldSudoku() {
        super();
    }

    public SmartOldSudoku copy(){
        return new SmartOldSudoku(toString());
    }

    @Override
    protected boolean clearRandom() {
        int histo[] = new int[9];
        int total =0;
        final int MIN=2;
        final int FACTOR=3;

        for(int i=0; i<81; i++)
        {
            final int x = get(i);
            if(x>=1 && x<=9)
                histo[x-1]++;
        }

        for(int i=0; i<9; i++) {
            if(histo[i]>MIN) total += histo[i]*FACTOR;
        }


        int n = IntUtils.rand(0, total-1);
        int val=0;
        for(int i=0; i<9; i++)
        {
            n-=histo[i]*FACTOR;
            if(n<0)
            {
                val=i+1;
                break;
            }
        }
        if(val==0)
            return false;

        int max=0;
        int imax=-1;
        for(int i=0; i<81; i++)
        {
            if(get(i)==val)
            {
                final int x = count(i);
                if(x>max)
                {
                    max=x;
                    imax=i;
                }
            }
        }
        if(imax==-1)
            return false;
        grid[imax]=0;

        return true;
    }

    protected int countLine(int y)
    {
        int n = 0;
        for(int i=0; i<9; i++)
            if(get(i, y)!=0)
                n++;
        return n;
    }

    protected int countColumn(int x)
    {
        int n = 0;
        for(int i=0; i<9; i++)
            if(get(x, i)!=0)
                n++;
        return n;
    }

    protected int countSquare(int x, int y)
    {
        int n = 0;
        int dx,  dy;
        int i, j;
        if(x>=6) dx=6; else if(x>=3) dx=3; else dx=0;
        if(y>=6) dy=6; else if(y>=3) dy=3; else dy=0;
        for(i=dx; i<dx+3; i++)
            for(j=dy; j<dy+3; j++)
                if(get(i,j)!=0) n++;
        return n;
    }

    protected int count(int x, int y)
    {
        return countSquare(x,y)+countColumn(x)+countLine(y);
    }

    protected int count(int i)
    {
        return count(i%9, i/9);
    }

    /*public static OldSudoku generate(int k)
    {
        OldSudoku s=new SmartOldSudoku();
        int x = s.find_sudoku();
        s.clearRandom(81-k);
        s.mDefault=s.toString();
        SimpleSudokuResolver sr = new SimpleSudokuResolver(s);
        sr.resolve();
        Log.e("//////////", s.toString());
        if(x>=0) return s;
        return null;
    }*/

    public static SmartOldSudoku newSudoku(){
        SmartOldSudoku s = new SmartOldSudoku();
        int x= s.find_sudoku(0);
        if (x>=0)
        {
            return s;
        }
        throw new RuntimeException("Impossible de générer le Sudoku: Nombre max de test dépassé");
    }


    public Sudoku toStdSudoku()
    {
        return new Sudoku(toString());
    }


}
