IEnumerator StartGame()
    {
        miniMap.SetActive(true);
        HUD.SetActive(true);

        float start = Time.time;

        while (true)
        {
            float percent = (Time.time - start) * 2;
            mainMenu.GetComponent <CanvasGroup>().alpha = 1 - percent;
            if (percent >= 1)
            {
                break;
            }
            yield return(new WaitForEndOfFrame());
        }
        mainMenu.SetActive(false);

        PlayerSheet.Initialize();
        distributorID = PlayerSheet.GetDistributor(difficulty);
        Debug.Log(PlayerSheet.GetName(distributorID) + " is the distributor.");
        PlayerSheet.SetParameter(distributorID, (int)ParameterType.Infected, true);
        player.transform.position = Vector2.zero;

        minutesLeft      = 16;
        days             = 0;
        spreadText.text  = "Spread: " + spread.ToString();
        minutesText.text = "Minutes Left: " + minutesLeft.ToString();
        daysText.text    = "Days: " + days.ToString();

        StartCoroutine(GameHandler());

        yield return(null);
    }
    IEnumerator GameHandler()
    {
        int i = 0;

        while (true)
        {
            // Respawn NPC s
            PlayerSheet.Shuffle();
            SpawnChars();

            // Reset spread and minutes
            spread = 0;
            for (int j = 0; j < 80; j++)
            {
                if (PlayerSheet.GetParameter(j, (int)ParameterType.Infected) == true)
                {
                    spread++;
                }
            }
            spreadText.text  = "Spread: " + spread.ToString() + "/64";
            minutesLeft      = 16;
            minutesText.text = "Minutes Left: " + minutesLeft.ToString();

            // wait for end of turn
            while (!Input.GetKeyDown(KeyCode.N))
            {
                if (spread == 1)
                {
                    i    = 0;
                    days = 0;
                    break;
                }
                yield return(null);
            }

            //Reset for next turn
            DestroyChars();

            // stop if the whole school knows
            if (spread >= 64 || won)
            {
                break;
            }

            // Infector Spreads rumor

            // spread rumor
            for (int j = 0; j < 80; j++)
            {
                // if in position to spread
                int pair = PlayerSheet.CheckPair(j);
                if (pair >= 0 && (PlayerSheet.GetParameter(j, (int)ParameterType.Infected)) == true)
                {
                    int num_spread = PlayerSheet.GetSpreadToday(i);
                    int r          = Random.Range(1, 100);

                    // if rumor can be spread
                    bool isThinking = ((PlayerSheet.GetIndex(j) == 66 || PlayerSheet.GetIndex(j) == 67 || PlayerSheet.GetIndex(j) == 68 || PlayerSheet.GetIndex(j) == 70 || PlayerSheet.GetIndex(j) == 71 ||
                                        PlayerSheet.GetIndex(j) == 76 || PlayerSheet.GetIndex(j) == 78 || PlayerSheet.GetIndex(j) == 79 || PlayerSheet.GetIndex(j) == distributorID) || PlayerSheet.GetIndex(j) < 64);

                    if (((difficulty == 0 && num_spread == 0 && r <= 40) || (difficulty == 1) && r <= 80) && PlayerSheet.GetParameter(pair, (int)ParameterType.Infected) == false && isThinking)
                    {
                        // spread rumor
                        PlayerSheet.SetSpreadToday(j, num_spread + 1);
                        PlayerSheet.SetParameter(pair, (int)ParameterType.Infected, true);

                        if (PlayerSheet.GetIndex(pair) >= 64)
                        {
                            PlayerSheet.SetRevealer(pair, j);
                        }

                        // find room
                        int room = (int)Mathf.Floor(j / 16);
                        Debug.Log(PlayerSheet.GetName(j) + " spread to " + PlayerSheet.GetName(pair) + " in room " + room.ToString());

                        for (int k = 16 * room; k < 16 * (room + 1); k++)
                        {
                            bool sharespreader1_1  = (PlayerSheet.GetTypeOne(k) == PlayerSheet.GetTypeOne(j));
                            bool sharespreader1_2  = (PlayerSheet.GetTypeOne(k) == PlayerSheet.GetTypeTwo(j));
                            bool sharespreader2_1  = (PlayerSheet.GetTypeTwo(k) == PlayerSheet.GetTypeOne(j));
                            bool sharespreader2_2  = (PlayerSheet.GetTypeTwo(k) == PlayerSheet.GetTypeTwo(j));
                            bool sharesinfected1_1 = (PlayerSheet.GetTypeOne(k) == PlayerSheet.GetTypeOne(pair));
                            bool sharesinfected1_2 = (PlayerSheet.GetTypeOne(k) == PlayerSheet.GetTypeTwo(pair));
                            bool sharesinfected2_1 = (PlayerSheet.GetTypeTwo(k) == PlayerSheet.GetTypeOne(pair));
                            bool sharesinfected2_2 = (PlayerSheet.GetTypeTwo(k) == PlayerSheet.GetTypeTwo(pair));

                            // if it is a friend
                            if (PlayerSheet.GetIndex(k) > 64 && k != j && k != pair)
                            {
                                // if they share clique with spreader
                                if (sharespreader1_1 || sharespreader1_2 || sharespreader2_1 || sharespreader2_2)
                                {
                                    int observeChance = 20;
                                    int trendChance   = 20;
                                    int friend        = (PlayerSheet.GetIndex(k) - 64);

                                    // if intuitive
                                    if (friend == 0 || friend == 1 || friend == 3 || friend == 4 || friend == 5 || friend == 6 || friend == 7 || friend == 13)
                                    {
                                        trendChance = 40;
                                    }

                                    // if observant
                                    else
                                    {
                                        observeChance = 40;
                                    }

                                    int rObserve = Random.Range(1, 100);
                                    int rTrend   = Random.Range(1, 100);

                                    // if observed, enter into stats
                                    if (rObserve < observeChance)
                                    {
                                        int mod = (PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.HistInd) % 2) == 0) ? 0 : 2;
                                        PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.S2ID1) + mod, pair);
                                        PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.SFID1) + mod, j);

                                        Debug.Log(PlayerSheet.GetName(k) + " observed " + PlayerSheet.GetName(j) + " to: " + PlayerSheet.GetName(pair));
                                        Debug.Log(rObserve);
                                    }

                                    // if trend noticed
                                    if (rTrend < trendChance)
                                    {
                                        if (sharespreader1_1)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.T2P), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.T2P)) + 1);
                                        }
                                        if (sharespreader1_2)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.T2P), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.T2P)) + 1);
                                        }
                                        if (sharespreader2_1)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.T2S), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.T2S)) + 1);
                                        }
                                        if (sharespreader2_2)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.T2S), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.T2S)) + 1);
                                        }
                                        if (sharesinfected1_1)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.TFP), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.TFP)) + 1);
                                        }
                                        if (sharesinfected1_2)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.TFP), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.TFP)) + 1);
                                        }
                                        if (sharesinfected2_1)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.TFS), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.TFS)) + 1);
                                        }
                                        if (sharesinfected2_2)
                                        {
                                            PlayerSheet.SetSpreadStat(k, Stat2Int(StatType.TFS), PlayerSheet.GetSpreadStat(k, Stat2Int(StatType.TFS)) + 1);
                                        }

                                        Debug.Log(PlayerSheet.GetName(k) + " noticed a Trend!");
                                        Debug.Log(rTrend);
                                    }
                                }
                            }

                            // add statistics
                            //PlayerSheet.SetSpreadToday(j, (int) SpreadType.ID1, pair);
                        }
                    }
                }
            }
            // new day
            if ((i % 3) == 0)
            {
                for (int j = 0; j < 80; j++)
                {
                    PlayerSheet.SetSpreadToday(j, 0);
                }
                days++;
                daysText.text = "Days: " + days.ToString();
            }
            i++;

            yield return(new WaitForEndOfFrame());
        }

        // Deconstruct game
        DestroyChars();
        miniMap.SetActive(false);
        HUD.SetActive(false);

        // start result manager
        StartCoroutine(EndGame());
    }
    public IEnumerator Dialogue(int ID)
    {
        if (minutesLeft != 0)
        {
            minutesLeft     -= 2;
            minutesText.text = "Minutes Left: " + minutesLeft.ToString();

            player.GetComponent <PlayerController>().AssertMovement(false);

            string sentence = PlayerSheet.GetName(ID) + ": ";
            cutsceneText.text = "";

            string statsString = "Stats: ";

            switch (PlayerSheet.GetIndex(ID) - 64)
            {
            case 0:
                statsString += "INFP\nIntrovert\nIntuitive\nFeeling\nProspecting";
                break;

            case 1:
                statsString += "ENFP\nExtrovert\nIntuitive\nFeeling\nProspecting";
                break;

            case 2:
                statsString += "ESTP\nExtrovert\nObservant\nThinking\nProspecting";
                break;

            case 3:
                statsString += "ENTP\nExtrovert\nIntuitive\nThinking\nProspecting";
                break;

            case 4:
                statsString += "ENTJ\nExtrovert\nIntuitive\nThinking\nJudging";
                break;

            case 5:
                statsString += "ENFJ\nExtrovert\nIntuitive\nFeeling\nJudging";
                break;

            case 6:
                statsString += "INTP\nIntrovert\nIntuitive\nThinking\nProspecting";
                break;

            case 7:
                statsString += "INTJ\nIntrovert\nIntuitive\nThinking\nJudging";
                break;

            case 8:
                statsString += "ESFP\nExtrovert\nObservant\nFeeling\nProspecting";
                break;

            case 9:
                statsString += "ESFJ\nExtrovert\nObservant\nFeeling\nJudging";
                break;

            case 10:
                statsString += "ISFP\nIntrovert\nObservant\nFeeling\nProspecting";
                break;

            case 11:
                statsString += "ISFJ\nIntrovert\nObservant\nFeeling\nJudging";
                break;

            case 12:
                statsString += "ISTJ\nIntrovert\nObservant\nThinking\nJudging";
                break;

            case 13:
                statsString += "INFJ\nIntrovert\nIntuitive\nFeeling\nJudging";
                break;

            case 14:
                statsString += "ISTP\nIntrovert\nObservant\nThinking\nProspecting";
                break;

            case 15:
                statsString += "ESTJ\nExtrovert\nObservant\nThinking\nJudging";
                break;
            }

            statsText.text = statsString;
            cutsceneObject.SetActive(true);

            // Normie
            if (PlayerSheet.GetIndex(ID) < 64)
            {
                cutsceneText.color = Color.white;

                if (PlayerSheet.GetParameter(ID, (int)ParameterType.Infected))
                {
                    PlayerSheet.SetParameter(ID, (int)ParameterType.Exposed, true);
                    NPCs[ID].GetComponentInChildren <TextMesh>().color = infectedColor;
                    sentence += "Haha, I heard you suck eggs!";
                }
                else
                {
                    int r = Random.Range(1, 100);
                    if (r >= 75)
                    {
                        sentence += PlayerSheet.GetNormieDialogue(PlayerSheet.GetTypeOne(ID) - 1);
                    }
                    else
                    {
                        sentence += PlayerSheet.GetNormieDialogue(PlayerSheet.GetTypeTwo(ID) - 1);
                    }
                }
            }
            else
            {
                cutsceneText.color = Color.yellow;
                statsWindow.SetActive(true);

                // if infected and not the spreader
                if (PlayerSheet.GetParameter(ID, (int)ParameterType.Infected) && PlayerSheet.GetIndex(ID) != distributorID)
                {
                    NPCs[ID].GetComponentInChildren <TextMesh>().color = infectedFriend;
                    PlayerSheet.SetParameter(ID, (int)ParameterType.Exposed, true);
                    sentence += "Since we're friends, I want to let you know that someone told me about the eggs... But I promise I never told anyone!";
                }

                // if uninfected
                else
                {
                    sentence += PlayerSheet.GetFriendDialogue(PlayerSheet.GetIndex(ID));
                }
            }

            int sound = 1;

            foreach (char c in sentence)
            {
                cutsceneText.text += c;
                yield return(new WaitForSeconds(.025f));

                //play sound every other character
                if (sound % 6 == 0)
                {
                    cutsceneNoise.SetActive(false);
                    cutsceneNoise.SetActive(true);
                }
                sound++;
            }

            yield return(new WaitForSeconds(1.5f));

            cutsceneText.text = "";

            // friend options
            if (PlayerSheet.GetIndex(ID) >= 64 && minutesLeft != 0)
            {
                buttons.SetActive(true);
                if (PlayerSheet.GetParameter(ID, (int)ParameterType.Exposed))
                {
                    whoToldYouButton.SetActive(true);
                }
                tmpID = ID;
            }

            else
            {
                player.GetComponent <PlayerController>().AssertMovement(true);
                cutsceneObject.SetActive(false);
            }
        }
        dialogueRunning = false;
        yield return(null);
    }