Example #1
0
        public async Task <Embed> RecommendPracticeSongs(ISocketMessageChannel ch, string name, int numSongs, bool onlyFromList)
        {
            //We will only look at songs that the player has seen in game at least once.
            var PlayerQuery = await SearchHandler.AllObjectsForPlayer(_db, name, onlyFromList);

            Dictionary <string, int[]> playerSpecific = new Dictionary <string, int[]>();
            Dictionary <string, int[]> total          = new Dictionary <string, int[]>();

            string temp;

            foreach (PlayerTableObject tObject in PlayerQuery)
            {
                temp = MakeSongTableKey(tObject.Show, tObject.Type, tObject.SongName);
                total.Add(temp, new int[] { tObject.TotalTimesPlayed, tObject.TimesCorrect });
                playerSpecific.Add(temp, new int[] { tObject.TotalTimesPlayed, tObject.TimesCorrect });
            }

            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();

            var OtherQuery = await _db.PlayerStats
                             .AsAsyncEnumerable()
                             .Where(x => x.Rule.Equals(""))
                             .Where(j => !j.PlayerName.Equals(name))
                             .Where(y => total.ContainsKey(MakeSongTableKey(y.Show, y.Type, y.SongName)))
                             .ToListAsync();

            Dictionary <string, float[]> songsToRecommend = new Dictionary <string, float[]>();
            int num = 0;

            while (songsToRecommend.Count < numSongs)
            {
                songsToRecommend.Add($"placeholder key {num}", new float[] { 1.0f,
                                                                             1.0f });
                num++;
            }

            //now we will go through all of those objects and increment the stats
            foreach (PlayerTableObject tableObject in OtherQuery)
            {
                temp = MakeSongTableKey(tableObject.Show, tableObject.Type, tableObject.SongName);
                total.TryGetValue(temp, out var currentCount);
                total[temp] = new int[] { currentCount[0] + tableObject.TotalTimesPlayed, currentCount[1] + tableObject.TimesCorrect };
            }

            //now we will go through all of the song keys and calculate the difference between
            //two rates
            List <string> allKeys = total.Keys.ToList();

            foreach (string key in allKeys)
            {
                float allTimesPlayed        = total[key][0];
                float allTimesCorrect       = total[key][1];
                float totalSuccessRate      = allTimesCorrect / allTimesPlayed;
                float timesPlayedForPlayer  = playerSpecific[key][0];
                float timesCorrectForPlayer = playerSpecific[key][1];
                float playerSuccessRate     = timesCorrectForPlayer / timesPlayedForPlayer;
                float diff = totalSuccessRate - playerSuccessRate;
                //If the difference is 0 then it will not be added so we can continue
                if (diff > 0)
                {
                    List <string> recommendKeys = songsToRecommend.Keys.ToList();
                    foreach (string songKey in recommendKeys)
                    {
                        songsToRecommend.TryGetValue(songKey, out var curr);
                        if (diff > (curr[1] - curr[0]))
                        {
                            songsToRecommend.Remove(songKey);
                            songsToRecommend.Add(key, new float[] { playerSuccessRate, totalSuccessRate });
                            break;
                        }
                    }
                }
            }
            return(await EmbedHandler.PrintRecommendedSongs(ch, songsToRecommend, name, stopWatch));
        }