void OnCollisionEnter(Collision col)
    {
        switch (col.gameObject.tag)
        {
        case "Predator":
            this.purge();
            break;

        case "Fish":

            GameObject    otherFish          = col.gameObject;
            fishComponent otherFishComponent = otherFish.GetComponent <fishComponent> ();

            if (grow_times >= 10)
            {
                if (Random.Range(0.0f, 1.0f) < probReproduction)
                {
                    reproduce(otherFishComponent);
                }
            }
            break;

        case "Plant":
            this.GetComponent <fishComponent> ().hurt(-10);
            col.gameObject.GetComponent <plantComponent> ().getBitten();
            break;

        default:
            break;
        }
    }
    void reproduce(fishComponent otherFishComponent)
    {
        hurt(20);
        GameObject newFish;

        newFish = Instantiate(fishPrefab, this.transform.position + Random.insideUnitSphere * 0.2f, Quaternion.identity) as GameObject;
        newFish.transform.localScale = new Vector3(0.5F, 0.5f, 0.5f);

        BitArray thisFishBinary  = toBinary();
        BitArray otherFishBinary = otherFishComponent.toBinary();

        BitArray genome = recombineBinary(thisFishBinary, otherFishBinary) [Random.Range(0, 1)];

        float newMaxHealth = Mathf.Abs(getPartOfBinary32AsFloat(genome, 0));
        float newMaxSpeed  = Mathf.Abs(getPartOfBinary32AsFloat(genome, 1));
        float newVision    = Mathf.Abs(getPartOfBinary32AsFloat(genome, 2));

        float newXModifier = Mathf.Abs(getPartOfBinary32AsFloat(genome, 3));
        float newYModifier = Mathf.Abs(getPartOfBinary32AsFloat(genome, 4));
        float newZModifier = Mathf.Abs(getPartOfBinary32AsFloat(genome, 5));

        if (newXModifier > scaleLimit)
        {
            newXModifier = scaleLimit;
        }
        if (newYModifier > scaleLimit)
        {
            newYModifier = scaleLimit;
        }
        if (newZModifier > scaleLimit)
        {
            newZModifier = scaleLimit;
        }


        globalBoid.fishes.Add(newFish);
        newFish.GetComponent <fishComponent> ().predefine(newMaxHealth, newMaxSpeed, newVision, newXModifier, newYModifier, newZModifier);
    }
    void ApplyRules()
    {
        ArrayList fishes;

        GameObject[] predators;
        ArrayList    plants;


        fishes    = globalBoid.fishes;
        predators = globalPack.predators;
        plants    = globalPlants.plants;


        Vector2 vcenter = Vector2.zero;
        Vector2 vavoid  = Vector2.zero;
        Vector2 vlove   = Vector2.zero;

        bool danger = false;

        float gSpeed = 2.0f;

        Vector2 goalPos = globalBoid.goalPos;

        float dist;

        int groupSize = 0;

        foreach (GameObject fish in fishes)
        {
            fishComponent otherFishComponent = fish.GetComponent <fishComponent> ();

            if (fish != this.gameObject)
            {
                dist = Vector2.Distance(this.transform.position, fish.transform.position);
                if (dist <= vision)
                {
                    vcenter += (Vector2)fish.transform.position;
                    groupSize++;

                    if (dist < 0.5f)
                    {
                        vavoid += (Vector2)(this.transform.position - fish.transform.position);
                    }

                    gSpeed = gSpeed + otherFishComponent.speed;
                }
            }
        }



        foreach (GameObject predator in predators)
        {
            dist = Vector3.Distance(this.transform.position, predator.transform.position);
            if (dist <= vision / 2)
            {
                danger  = true;
                vavoid += (Vector2)(this.transform.position - predator.transform.position);
            }
        }


        foreach (GameObject plant in plants)
        {
            dist = Vector3.Distance(this.transform.position, plant.transform.position);

            if (dist <= vision)
            {
                goalPos = plant.transform.position;
                vcenter = plant.transform.position;
                break;
            }
        }

        if (groupSize > 0)
        {
            vcenter = ((Vector3)vcenter / groupSize) + (Vector3)goalPos * 2 - (Vector3)this.transform.position;
            speed   = (gSpeed / groupSize);

            if (speed > max_speed)
            {
                speed = max_speed;
            }

            Vector2 direction = Vector2.zero;

            if (danger)
            {
                direction = (vavoid) - (Vector2)this.transform.position;;
            }
            else
            {
                direction = (vcenter + vavoid) - (Vector2)this.transform.position;;
            }



            if (direction != Vector2.zero)
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
            }
        }
    }