Beispiel #1
0
    /**
     * Apply the effect of the dam
     *
     * Fish will attempt to cross the dam and may be able to pass or "get stuck" and die
     */
    protected override void ApplyFilterEffect(Fish fish)
    {
        // only let it through if it hasn't been flagged as stuck
        if (!fish.IsStuck())
        {
            // chance between fish getting past the dam and being caught/getting stuck depends on what size the fish is
            float crossingRate;

            FishGenePair sizeGenePair = fish.GetGenome()[FishGenome.GeneType.Size];
            if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b)
            {
                crossingRate = smallCrossingRate;
            }
            else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B)
            {
                crossingRate = mediumCrossingRate;
            }
            else
            {
                crossingRate = largeCrossingRate;
            }

            // based on the crossing rate we figured out, roll for a crossing
            // if we pass, put the fish past the dam
            if (Random.Range(0f, 1f) <= crossingRate)
            {
                fish.transform.position = GetRandomDropOff(fish.transform.position.z);
            }
            // if it didn't make it, make it permanently stuck (so it can't try repeated times)
            else
            {
                fish.SetStuck(true);
            }
        }
    }
    /**
     * Get a list of all large fish genomes from a list of fish genomes
     *
     * @param genomeList List<FishGenome> The list of fish to be looked through
     *
     * @return List<FishGenome> A list of all large fish within the original list
     */
    public static List <FishGenome> FindLargeGenomes(List <FishGenome> genomeList)
    {
        return(genomeList.Where((fish) => {
            FishGenePair sizeGenePair = fish[FishGenome.GeneType.Size];

            return sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B;
        }).ToList());
    }
 /**
  * Constructor for situations where we want to create a genome from two parent genomes
  *
  * @param momGenome FishGenePair The genome from the mother
  * @param dadGenome FishGenePair the genome from the father
  */
 public FishGenome(FishGenome momGenome, FishGenome dadGenome)
 {
     for (int index = 0; index < Length; index++)
     {
         FishGenePair newPair = new FishGenePair();
         newPair.momGene     = Random.Range(0, 2) == 1 ? momGenome[index].momGene : momGenome[index].dadGene;
         newPair.dadGene     = Random.Range(0, 2) == 1 ? dadGenome[index].momGene : dadGenome[index].dadGene;
         genePairList[index] = newPair;
     }
 }
    /*
     * The sealion attempts to catch a given fish
     *
     * @param fish The fish the sealion is catching
     */
    private IEnumerator TryCatchFishCoroutine(Fish fish)
    {
        // How likely we are to catch fish is dependent on what size the fish is
        // Determine that now
        float        catchRate;
        float        weight;
        FishGenePair sizeGenePair = fish.GetGenome()[FishGenome.GeneType.Size];

        switch (sizeGenePair.momGene)
        {
        case FishGenome.X when sizeGenePair.dadGene == FishGenome.X:
            catchRate = femaleCatchRate;
            weight    = 2f;   //4
            Debug.Log("bbCatchR=" + catchRate + "; weight=" + weight);
            break;

        case FishGenome.X when sizeGenePair.dadGene == FishGenome.Y:
            catchRate = maleCatchRate;
            weight    = 9f;   //15
            Debug.Log("BBCatchR=" + catchRate + "; weight=" + weight);
            break;

        default:
            catchRate = maleCatchRate;
            weight    = 6f;   //9
            break;
        }
        Debug.Log("SeaLionCatch: MaleCR=" + maleCatchRate + "FemCR=" + femaleCatchRate);

        // Figure out whether the fish will be caught or not
        bool caught = Random.Range(0f, 1f) <= catchRate;

        // Handle fish being caught
        if (caught)
        {
            // Tell the fish that it is being caught
            fish.StartCatch();

            // Trigger Water Splash effect on fish
            fish.waterSplash.Play();
            fish.swimSpeed            = 0;
            fish.fishRenderer.enabled = false;
            yield return(new WaitForSeconds(2));

            // Actually catch the fish
            fish.Catch();
            caughtFish.Add(fish);
        }
        // Fish escaped -- just wait for end of action
        else
        {
            yield return(new WaitForSeconds(timePerApplyEffect));
        }
    }
Beispiel #5
0
    /**
     * Apply the effect of the dam
     *
     * Fish will attempt to cross the dam and may be able to pass or "get stuck" and die
     *
     * @param fish The fish trying to pass by the dam
     */
    public void ApplyFilterEffect(Fish fish)
    {
        // Only let it through if it hasn't been flagged as stuck
        if (!fish.IsStuck())
        {
            // Chance between fish getting past the dam and being caught/getting stuck depends on what size the fish is
            float crossingRate;

            Debug.Log("Dam.ApplyFilterEffect: SMcr =" + smallCrossingRate + "; MDcr = " + mediumCrossingRate + "; LGcr = " + largeCrossingRate);

            FishGenePair sizeGenePair = fish.GetGenome()[FishGenome.GeneType.Size];
            if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b)
            {
                crossingRate = smallCrossingRate;
            }
            else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B)
            {
                crossingRate = largeCrossingRate;
            }
            else
            {
                crossingRate = mediumCrossingRate;
            }

            while (!fish.IsStuck())
            {
                // Based on the crossing rate we figured out, roll for a crossing
                // If we pass, put the fish past the dam
                if (Random.Range(0f, 1f) <= crossingRate)
                {
                    fish.transform.position = GetRandomDropOff(fish.transform.position.y);
                    break;
                }
                // If we have not expended our total tries (based on damPassCounter in fish), increment, wait, and try again
                else if (fish.damPassCounter < 2)
                {
                    fish.damPassCounter++;
                    Invoke("DamPassCooldown", 6.0f);
                }
                // If it didn't make it, make it permanently stuck (so it can't try repeated times)
                else
                {
                    fish.SetStuck(true);
                    break;
                }
            }
        }
    }
Beispiel #6
0
    /**
     * Determine which fish prefab should be used given a fish's genome
     *
     * @param genome FishGenome The genome that determines which prefab we should use
     */
    public GameObject GetFishPrefab(FishGenome genome)
    {
        // gameobject we will return at end
        GameObject toReturn;

        // get the size gene for the fish
        FishGenePair sizeGenePair = genome[FishGenome.GeneType.Size];

        // different prefabs for each sex
        if (genome.IsMale())
        {
            // different prefabs for each male size
            if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b)
            {
                toReturn = smallMale;
            }
            else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B)
            {
                toReturn = largeMale;
            }
            else
            {
                toReturn = mediumMale;
            }
        }
        else
        {
            // different prefabs for each female size
            if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b)
            {
                toReturn = smallFemale;
            }
            else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B)
            {
                toReturn = largeFemale;
            }
            else
            {
                toReturn = mediumFemale;
            }
        }

        return(toReturn);
    }
Beispiel #7
0
    /*
     * Loads the game state of the turn in the list of saves to revert the game to
     */
    public static void LoadGame()
    {
        // The turn number from the Pause Menu UI slider that we want to revert the game to
        int turn = (int)GameManager.Instance.pauseMenu.turnSlider.value;

        // List counters for each kind of tower we are loading in
        int currentAngler  = 0;
        int currentRanger  = 0;
        int currentSealion = 0;
        int currentTower   = 0;

        // Clear all the existing towers
        foreach (TowerBase tower in GameManager.Instance.GetTowerList())
        {
            Destroy(tower.transform.parent.gameObject);
        }

        // Grab the save from turn - 1 as we start at turn 0, but the pause menu slider starts at 1
        Save loadSave = saves[turn - 1];

        // Loop through each saved tower and load them back into the scene appropriately
        foreach (int towerType in loadSave.towerTypes)
        {
            // NOTE: This can also be accomplished with a Swicth statement, but this seems more readable for little loss of performance
            // Angler
            if (towerType == 0)
            {
                GameObject  angler      = Instantiate(GameManager.Instance.GetTowerPrefabs()[0]);
                AnglerTower towerScript = angler.GetComponent <AnglerTower>();
                angler.transform.position   = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]);
                angler.transform.rotation   = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]);
                towerScript.turnPlaced      = loadSave.anglerPlaced[currentAngler];
                towerScript.fishCaught      = loadSave.caughtFish[currentAngler];
                towerScript.smallCatchRate  = loadSave.anglerCatchRates[currentAngler][0];
                towerScript.mediumCatchRate = loadSave.anglerCatchRates[currentAngler][1];
                towerScript.largeCatchRate  = loadSave.anglerCatchRates[currentAngler][2];
                currentTower++;
                currentAngler++;
            }
            // Ranger
            else if (towerType == 1)
            {
                GameObject  ranger      = Instantiate(GameManager.Instance.GetTowerPrefabs()[1]);
                RangerTower towerScript = ranger.GetComponent <RangerTower>();
                ranger.transform.position        = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]);
                ranger.transform.rotation        = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]);
                towerScript.turnPlaced           = loadSave.rangerPlaced[currentRanger];
                towerScript.slowdownEffectSmall  = loadSave.rangerRegulateRates[currentRanger][0];
                towerScript.slowdownEffectMedium = loadSave.rangerRegulateRates[currentRanger][1];
                towerScript.slowdownEffectLarge  = loadSave.rangerRegulateRates[currentRanger][2];
                currentTower++;
                currentRanger++;
            }
            // Sealion
            else if (towerType == 4)
            {
                GameObject   sealion     = Instantiate(GameManager.Instance.GetTowerPrefabs()[4]);
                SealionTower towerScript = sealion.GetComponent <SealionTower>();
                sealion.transform.position  = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]);
                sealion.transform.rotation  = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]);
                towerScript.turnPlaced      = loadSave.sealionAppeared[currentSealion];
                towerScript.maleCatchRate   = loadSave.sealionCatchRates[currentSealion][0];
                towerScript.femaleCatchRate = loadSave.sealionCatchRates[currentSealion][1];
                currentTower++;
                currentSealion++;
            }
            // Dam
            else if (towerType == 2)
            {
                GameObject dam         = Instantiate(GameManager.Instance.GetTowerPrefabs()[2]);
                Dam        towerScript = dam.GetComponent <Dam>();
                dam.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]);
                dam.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]);
                towerScript.turnPlaced = loadSave.damPlaced;
                currentTower++;
            }
            // Ladder
            else if (towerType == 3)
            {
                GameObject ladder      = Instantiate(GameManager.Instance.GetTowerPrefabs()[3]);
                DamLadder  towerScript = ladder.GetComponent <DamLadder>();
                ladder.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]);
                ladder.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]);
                towerScript.turnPlaced    = loadSave.ladderType;
                currentTower++;
            }
        }

        // Load in the generation of fish from this turn
        List <FishGenome> revertGeneration = new List <FishGenome>();

        /*
         * This is lengthy. The gist is we COULD just grab the list via GetFish in FishSchool, but then the save
         * would not be potentially serializable if we want that in the future. So instead, we are reconstructing the
         * appropriate generation based on the counts of small, medium, and large fish (both male and female) we saved
         * at the place stage of that turn.
         */

        // Small Male Fish
        FishGenePair[] SMgenes = new FishGenePair[FishGenome.Length];
        FishGenePair   sexPair;

        sexPair.momGene = FishGenome.X;
        sexPair.dadGene = FishGenome.Y;
        FishGenePair sizePair;

        sizePair.momGene = FishGenome.b;
        sizePair.dadGene = FishGenome.b;
        SMgenes[(int)FishGenome.GeneType.Sex]  = sexPair;
        SMgenes[(int)FishGenome.GeneType.Size] = sizePair;
        FishGenome smallMGenome = new FishGenome(SMgenes);

        for (int i = 0; i < loadSave.smallMale; i++)
        {
            revertGeneration.Add(smallMGenome);
        }

        // Medium Male Fish
        FishGenePair[] MMgenes = new FishGenePair[FishGenome.Length];
        sizePair.momGene = FishGenome.b;
        sizePair.dadGene = FishGenome.B;
        MMgenes[(int)FishGenome.GeneType.Sex]  = sexPair;
        MMgenes[(int)FishGenome.GeneType.Size] = sizePair;
        FishGenome mediumMGenome = new FishGenome(MMgenes);

        for (int i = 0; i < loadSave.mediumMale; i++)
        {
            revertGeneration.Add(mediumMGenome);
        }

        // Large Male Fish
        FishGenePair[] LMgenes = new FishGenePair[FishGenome.Length];
        sizePair.momGene = FishGenome.B;
        sizePair.dadGene = FishGenome.B;
        LMgenes[(int)FishGenome.GeneType.Sex]  = sexPair;
        LMgenes[(int)FishGenome.GeneType.Size] = sizePair;
        FishGenome largeMGenome = new FishGenome(LMgenes);

        for (int i = 0; i < loadSave.largeMale; i++)
        {
            revertGeneration.Add(largeMGenome);
        }

        // Small Female Fish
        FishGenePair[] SFgenes = new FishGenePair[FishGenome.Length];
        sexPair.dadGene = FishGenome.X;
        SFgenes[(int)FishGenome.GeneType.Sex] = sexPair;
        sizePair.momGene = FishGenome.b;
        sizePair.dadGene = FishGenome.b;
        SFgenes[(int)FishGenome.GeneType.Size] = sizePair;
        FishGenome smallFGenome = new FishGenome(SFgenes);

        for (int i = 0; i < loadSave.smallFemale; i++)
        {
            revertGeneration.Add(smallFGenome);
        }

        // Medium Female Fish
        FishGenePair[] MFgenes = new FishGenePair[FishGenome.Length];
        sizePair.momGene = FishGenome.B;
        sizePair.dadGene = FishGenome.b;
        MFgenes[(int)FishGenome.GeneType.Sex]  = sexPair;
        MFgenes[(int)FishGenome.GeneType.Size] = sizePair;
        FishGenome mediumFGenome = new FishGenome(MFgenes);

        for (int i = 0; i < loadSave.mediumFemale; i++)
        {
            revertGeneration.Add(mediumFGenome);
        }

        // Large Female Fish
        FishGenePair[] LFgenes = new FishGenePair[FishGenome.Length];
        sizePair.momGene = FishGenome.B;
        sizePair.dadGene = FishGenome.B;
        LFgenes[(int)FishGenome.GeneType.Sex]  = sexPair;
        LFgenes[(int)FishGenome.GeneType.Size] = sizePair;
        FishGenome largeFGenome = new FishGenome(LFgenes);

        for (int i = 0; i < loadSave.largeFemale; i++)
        {
            revertGeneration.Add(largeFGenome);
        }
        FishGenomeUtilities.Shuffle(revertGeneration);
        GameManager.Instance.school.nextGenerationGenomes = revertGeneration;

        // Remove future turns we reverted over and set the UI slider in the pause menu appropriately
        GameManager.Instance.pauseMenu.turnSlider.maxValue = turn;
        GameManager.Instance.pauseMenu.turnSlider.value    = turn;
        GameManager.Instance.Turn = turn;
        GameManager.Instance.SetState(new PlaceState());
        currentSaveIndex = turn;
    }
Beispiel #8
0
    /**
     * Display attempt to catch fish
     */
    private IEnumerator TryCatchFishCoroutine(Fish fish)
    {
        // how likely we are to catch fish is dependent on what size the fish is
        // determine that now
        float        catchRate;
        FishGenePair sizeGenePair = fish.GetGenome()[FishGenome.GeneType.Size];

        if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b)
        {
            catchRate = currentSmallCatchRate;
        }
        else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B)
        {
            catchRate = currentMediumCatchRate;
        }
        else
        {
            catchRate = currentLargeCatchRate;
        }

        // figure out whether the fish will be caught or not
        bool caught = Random.Range(0f, 1f) <= catchRate;

        // do setup for catch attempt line visualizer
        catchAttemptFish = fish;

        Destroy(catchAttemptLine.material);
        catchAttemptLine.material = caught ? hitLineMaterial : missLineMaterial;

        catchAttemptLine.enabled = true;

        // handle fish being caught
        if (caught)
        {
            // tell the fish that it is being caught
            fish.StartCatch();

            // make the fish flash  for a bit
            SkinnedMeshRenderer fishRenderer = fish.GetComponentInChildren <SkinnedMeshRenderer>();
            for (int i = 0; i < numFlashesPerCatch; i++)
            {
                Material oldMaterial = fishRenderer.material;
                fishRenderer.material = flashMaterial;
                yield return(new WaitForSeconds((float)timePerApplyEffect / numFlashesPerCatch / 2f));

                Destroy(fishRenderer.material);
                fishRenderer.material = oldMaterial;
                yield return(new WaitForSeconds((float)timePerApplyEffect / numFlashesPerCatch / 2f));
            }

            // actually catch the fish
            fish.Catch();
            caughtFish.Add(fish);
        }
        // fish escaped -- just wait for end of action
        else
        {
            yield return(new WaitForSeconds(timePerApplyEffect));
        }

        // end the catch attempt line
        catchAttemptLine.enabled = false;
    }
    /**
     * Create a new, random generation of fish for the initial group of salmon
     *
     * @param generationSize int The number of fish that should be in this generation
     * @param lockSexRatio bool True if we want to lock to half males, half females (or as close as is possible), false if we want random
     * @param lockSizeRatio bool True if we want to lock to set ratios of sizes, false if we want random
     */
    public static List <FishGenome> MakeNewGeneration(int generationSize, bool lockSexRatio, bool lockSizeRatio)
    {
        // create a list to hold the new genomes
        List <FishGenome> newGeneration = new List <FishGenome>();

        for (int i = 0; i < generationSize; i++)
        {
            FishGenePair[] genes = new FishGenePair[FishGenome.Length];

            // figure out the sex gene pair
            FishGenePair sexPair;

            // the mom gene will always be an x
            sexPair.momGene = FishGenome.X;

            // how we determine the dad gene depends on whether we want equal number of males and females or if we want it to be random
            if (lockSexRatio)
            {
                // want to lock sex ratio, so odd fish will be one sex and even fish will be the other
                sexPair.dadGene = i % 2 == 0 ? FishGenome.X : FishGenome.Y;
            }
            else
            {
                // dad gene determined by pseudorandom chance
                sexPair.dadGene = Random.Range(0, 2) == 0 ? FishGenome.X : FishGenome.Y;
            }

            // add the sex gene to our list of genomes
            genes[(int)FishGenome.GeneType.Sex] = sexPair;

            // figure out the size gene pair
            FishGenePair sizePair;

            // how we determine the size genes is dependant on whether we want to lock to specific ratios or do random
            // if we're locking values, we use i % 4 to get 25% big, 50% medium, 25% small
            // if we aren't just do a random value
            int value = lockSizeRatio ? i % 4 : Random.Range(0, 4);
            switch (value)
            {
            case 0:
            default:
                sizePair.momGene = FishGenome.B;
                sizePair.dadGene = FishGenome.B;
                break;

            case 1:
                sizePair.momGene = FishGenome.B;
                sizePair.dadGene = FishGenome.b;
                break;

            case 2:
                sizePair.momGene = FishGenome.b;
                sizePair.dadGene = FishGenome.B;
                break;

            case 3:
                sizePair.momGene = FishGenome.b;
                sizePair.dadGene = FishGenome.b;
                break;
            }

            // add the size gene to our list of genomes
            genes[(int)FishGenome.GeneType.Size] = sizePair;

            // create a genome out of our genes and add it to the list
            FishGenome genome = new FishGenome(genes);
            newGeneration.Add(genome);
        }

        return(newGeneration);
    }
Beispiel #10
0
    /**
     * Display attempt to catch fish
     *
     * @param fish The fish the fisherman is trying to catch
     */
    private IEnumerator TryCatchFishCoroutine(Fish fish)
    {
        // How likely we are to catch fish is dependent on what size the fish is
        // Determine that now
        float        catchRate;
        float        weight;
        FishGenePair sizeGenePair = fish.GetGenome()[FishGenome.GeneType.Size];

        switch (sizeGenePair.momGene)
        {
        case FishGenome.b when sizeGenePair.dadGene == FishGenome.b:
            catchRate = smallCatchRate;
            weight    = 2f;   //4
            //Debug.Log("bbCatchR=" + catchRate + "; weight=" + weight);
            break;

        case FishGenome.B when sizeGenePair.dadGene == FishGenome.B:
            catchRate = largeCatchRate;
            weight    = 9f;   //15
            //Debug.Log("BBCatchR=" + catchRate + "; weight=" + weight);
            break;

        default:
            catchRate = mediumCatchRate;
            weight    = 6f;   //9
            //Debug.Log("BbCatchR=" + catchRate + "; weight=" + weight);
            break;
        }
        Debug.Log("TryCatchFishCoroutine: cScr=" + smallCatchRate + "; cMcr=" + mediumCatchRate + "; cLcr=" + largeCatchRate);


        // Figure out whether the fish will be caught or not
        bool caught = Random.Range(0f, 1f) <= catchRate;

        // Do setup for catch attempt line visualizer
        catchAttemptFish = fish;

        Destroy(catchAttemptLine.material);
        catchAttemptLine.material = caught ? hitLineMaterial : missLineMaterial;

        catchAttemptLine.enabled = true;

        // Handle fish being caught
        if (caught)
        {
            // Tell the fish that it is being caught
            fish.StartCatch();

            // Trigger Water Splash effect on fish
            fish.waterSplash.Play();
            fish.swimSpeed = 0;
            yield return(new WaitForSeconds(1));

            fish.fishRenderer.enabled = false;
            yield return(new WaitForSeconds(1));

            // Actually catch the fish
            fish.Catch();
            caughtFish.Add(fish);

            // Add Appropriate Funds to Bank
            ManagerIndex.MI.MoneyManager.AddCatch(weight);

            // Increase this angler's fish caught total
            fishCaught++;
        }
        // Fish escaped -- just wait for end of action
        else
        {
            yield return(new WaitForSeconds(timePerApplyEffect));
        }

        // End the catch attempt line
        catchAttemptLine.enabled = false;
    }