import java.io.*;
import java.lang.*;


public class Chromosome
{
    private  int      Length;
    private  int      GeneMinValue;
    private  int      GeneMaxValue;
    public   Gene[]   Genes;
    private  int      Fitness;
    private  Position Start;


    public Chromosome(int _Length, int _GeneMinValue, int _GeneMaxValue, Position _Start)
    {
        Length          = _Length;
        GeneMinValue    = _GeneMinValue;
        GeneMaxValue    = _GeneMaxValue;
        Start           = _Start;

        Genes  = new Gene[Length];
        for (int i=0; i<Length; i++)
        {
            Genes[i] = new Gene(GeneMinValue, GeneMaxValue);
        }
    }


    public void RandomGenerate()
    {
        for (int i=0; i<Length; i++)
        {
            Gene(i, (int)(Math.random() * (GeneMaxValue+1)));
        }

        CalculateFitness();  // put here outside Gene(i,Value) for efficiency
    }



    public void Gene(int _Index, int _Value)
    {
        Genes[_Index].Value(_Value);
        // CalculateFitness();  // taken out for efficiency
    }


    public int Gene(int _Index)
    {
        return Genes[_Index].Value();
    }



    public void CalculateFitness()
    {
        int Rows    =   8;
        int Columns =   8;
        int[]   dI = {-1, +1, +2, +2, +1, -1, -2, -2};
        int[]   dJ = {-2, -2, -1, +1, +2, +2, +1, -1};
        boolean[][] visited = new boolean[Rows][Columns];
        for (int r=0; r<Rows; r++)
        {
            for (int c=0; c<Columns; c++)
            {
                visited[r][c] = false;
            }
        }


        // assume a start position
        int I = Start.i;
        int J = Start.j;
        visited[I][J] = true;

        Fitness = 0;
        for (int g=0; g<Length; g++)
        {
            I = I + dI[Gene(g)];
            J = J + dJ[Gene(g)];
            if(
                ((I >= 0) && (I <= Rows-1))
                &&
                ((J >= 0) && (J <= Columns-1))
                &&
                (visited[I][J] == false)
              )
            {
                visited[I][J] = true;
                Fitness++;
            }
            else
            {
                break;
            }
        }
    }



    public int Fitness()
    {
        return Fitness;
    }


    public void Display()
    {
        System.out.println("Solution:");
        for (int i=0; i<Length; i++)
        {
            System.out.print(Gene(i) + " ");
        }
        System.out.println();
    }

}
