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());
    }