Exemple #1
0
        private DiscordEmbedBuilder BuildGameFoundMessage(InhouseGame inhouseGame, InhouseQueue inhouseQueue)
        {
            var blueWinrate  = CalculateBlueSideWinrate(inhouseGame);
            var embedBuilder = new DiscordEmbedBuilder();

            embedBuilder.Title       = "📢Game found📢";
            embedBuilder.Description = $"Blue side expected winrate is {blueWinrate.ToString("0.0")}%\n" +
                                       "If you are ready to play, press ✅\n" +
                                       "If you cannot play, press ❌\n" +
                                       "Recheck if it didn't work the first time";
            var bluePlayers       = inhouseGame.InhousePlayers.Where(x => x.PlayerSide == PlayerSide.Blue).OrderBy(x => x.PlayerRole);
            var bluePlayersString = "";

            foreach (var bluePlayer in bluePlayers)
            {
                bluePlayersString += $"{inhouseQueue.Emojis[bluePlayer.PlayerRole]}{_statusEmojis[bluePlayer.PlayerStatus]}{bluePlayer.Player.DisplayName}\n";
            }
            var redPlayers       = inhouseGame.InhousePlayers.Where(x => x.PlayerSide == PlayerSide.Red).OrderBy(x => x.PlayerRole);
            var redPlayersString = "";

            foreach (var redPlayer in redPlayers)
            {
                redPlayersString += $"{inhouseQueue.Emojis[redPlayer.PlayerRole]}{_statusEmojis[redPlayer.PlayerStatus]}{redPlayer.Player.DisplayName}\n";
            }
            embedBuilder.AddField("BLUE", bluePlayersString, true);
            embedBuilder.AddField("RED", redPlayersString, true);

            return(embedBuilder);
        }
Exemple #2
0
        private double CalculateBlueSideWinrate(InhouseGame inhouseGame)
        {
            var overallBlueWinrate = 0.0;
            var overallRedWinrate  = 0.0;
            var uow = _db.UnitOfWork();

            foreach (var player in inhouseGame.InhousePlayers)
            {
                var playerStat = uow.InhousePlayerStats.GetByPlayerId(player.Player.Id);
                if (playerStat == null)
                {
                    if (player.PlayerSide == PlayerSide.Blue)
                    {
                        overallBlueWinrate += 50.0;
                    }
                    else
                    {
                        overallRedWinrate += 50.0;
                    }
                    continue;
                }
                var totalGames = playerStat.Wins + playerStat.Loses;
                var wins       = playerStat.Wins + 10 - Math.Min(10, totalGames);
                var loses      = playerStat.Loses + 10 - Math.Min(10, totalGames);
                var winrate    = 100.0 * wins / (wins + loses);
                if (player.PlayerSide == PlayerSide.Blue)
                {
                    overallBlueWinrate += winrate;
                }
                else
                {
                    overallRedWinrate += winrate;
                }
            }

            if (overallBlueWinrate == 0.0 && overallRedWinrate == 0.0)
            {
                return(50.0);
            }

            return(100 * overallBlueWinrate / (overallBlueWinrate + overallRedWinrate));
        }
Exemple #3
0
 public void AddByInhouseGame(InhouseGame inhouseGame, PlayerSide winningSide)
 {
     foreach (var player in inhouseGame.InhousePlayers)
     {
         var playerDb = GetByPlayerId(player.Player.Id);
         if (playerDb == null)
         {
             playerDb = new InhousePlayerStatDb(player.Player.Id);
         }
         if (player.PlayerSide == winningSide)
         {
             playerDb.Wins += 1;
         }
         else
         {
             playerDb.Loses += 1;
         }
         _dbset.Update(playerDb);
     }
 }
Exemple #4
0
        private async Task ReadyCheck(DiscordChannel channel, InhouseGame inhouseGame)
        {
            var inhouseQueue = InhouseQueues.FirstOrDefault(x => x.ChannelId == channel.Id);
            var mentionMsg   = "";

            foreach (var player in inhouseGame.InhousePlayers)
            {
                mentionMsg += $"{player.Player.Mention} ";
            }
            var embedBuilder   = BuildGameFoundMessage(inhouseGame, inhouseQueue);
            var channelMessage = await channel.SendMessageAsync(mentionMsg, embed : embedBuilder.Build()).ConfigureAwait(false);

            var checkEmoji = DiscordEmoji.FromName(_client, ":white_check_mark:");
            var xEmoji     = DiscordEmoji.FromName(_client, ":x:");
            await channelMessage.CreateReactionAsync(checkEmoji).ConfigureAwait(false);

            await channelMessage.CreateReactionAsync(xEmoji).ConfigureAwait(false);

            await Task.Run(async() =>
            {
                while (true)
                {
                    var interactivity = _client.GetInteractivity();
                    var response      = await interactivity.WaitForReactionAsync(x => x.Message.Id == channelMessage.Id && x.User.Id != _client.CurrentUser.Id).ConfigureAwait(false);
                    if (response.TimedOut)
                    {
                        // put everyone who was ready back to queue
                        foreach (var queueGroup in inhouseGame.QueueGroups)
                        {
                            var removedPlayers = new List <InhousePlayer>();
                            foreach (var inhousePlayer in queueGroup.Players)
                            {
                                if (inhousePlayer.PlayerStatus == PlayerStatus.Ready)
                                {
                                    inhousePlayer.PlayerStatus = PlayerStatus.None;
                                }
                                else
                                {
                                    removedPlayers.Add(inhousePlayer);
                                }
                            }
                            queueGroup.Players.RemoveAll(x => removedPlayers.Any(y => x == y));
                            inhouseQueue.PlayersInQueue.Insert(0, queueGroup);
                        }
                        await ShowQueue(channel, "Game timed out, readied players will now be put back in queue.").ConfigureAwait(false);

                        InhouseGames.Remove(inhouseGame);
                        return;
                    }
                    if (response.Result.Emoji == checkEmoji)
                    {
                        // check if it is one of the players
                        var player = inhouseGame.InhousePlayers.FirstOrDefault(x => x.Player.Id == response.Result.User.Id);
                        if (player == null)
                        {
                            continue;
                        }
                        var readyPlayer          = inhouseGame.InhousePlayers.FirstOrDefault(x => x.Player.Id == response.Result.User.Id);
                        readyPlayer.PlayerStatus = PlayerStatus.Ready;
                        var embedBuilder         = BuildGameFoundMessage(inhouseGame, inhouseQueue);
                        await channelMessage.ModifyAsync(embed: embedBuilder.Build()).ConfigureAwait(false);

                        if (inhouseGame.InhousePlayers.All(x => x.PlayerStatus == PlayerStatus.Ready))
                        {
                            await channel.SendMessageAsync($"Everybody has readied, game will now start\nUse {_prefix}won to score the game.");
                            return;
                        }
                    }
                    else if (response.Result.Emoji == xEmoji)
                    {
                        // check if it is one of the players
                        var player = inhouseGame.InhousePlayers.FirstOrDefault(x => x.Player.Id == response.Result.User.Id);
                        if (player == null)
                        {
                            continue;
                        }
                        // put everyone back to queue except the author
                        foreach (var queueGroup in inhouseGame.QueueGroups)
                        {
                            var removedPlayers = new List <InhousePlayer>();
                            foreach (var inhousePlayer in queueGroup.Players)
                            {
                                if (inhousePlayer.Player.Id == response.Result.User.Id)
                                {
                                    removedPlayers.Add(inhousePlayer);
                                }
                                else
                                {
                                    inhousePlayer.PlayerStatus = PlayerStatus.None;
                                }
                            }
                            queueGroup.Players.RemoveAll(x => removedPlayers.Any(y => x == y));
                            inhouseQueue.PlayersInQueue.Insert(0, queueGroup);
                        }

                        InhouseGames.Remove(inhouseGame);
                        await ShowQueue(channel, "A player cancelled the game and was removed from the queue\nAll other players have been put back into the queue").ConfigureAwait(false);
                        return;
                    }
                }
            });
        }
Exemple #5
0
        private async Task AttemptMatchmake(DiscordChannel channel)
        {
            var inhouseQueue = InhouseQueues.FirstOrDefault(x => x.ChannelId == channel.Id);

            // if less than 10 players in queue, no game can be made
            if (inhouseQueue.PlayersInQueue.Sum(x => x.Players.Count()) < 10)
            {
                return;
            }

            // brute force check for matchmake with buckets
            var buckets = new List <MatchmakeBucket>();

            buckets.Add(new MatchmakeBucket());

            // we reserve SOLO fill players for last
            MatchmakeBucket filledBucket = null;
            var             fillPlayers  = new List <QueueGroup>();

            foreach (var queueGroup in inhouseQueue.PlayersInQueue)
            {
                var tempBuckets = new List <MatchmakeBucket>();

                // check for SOLO fill players
                if (queueGroup.Players.Count() == 1 && queueGroup.Players[0].QueuedRoles[PlayerRole.Fill])
                {
                    fillPlayers.Add(queueGroup);
                    var maxBucket = buckets.FirstOrDefault(x => x.PlayerCount + fillPlayers.Count() >= 10);
                    if (maxBucket != null)
                    {
                        filledBucket = maxBucket;
                        break;
                    }
                    continue;
                }

                // get each role combination from each queueGroup
                foreach (var bucket in buckets)
                {
                    // check to see if a copy of bucket without roleCombination is already in
                    var hasOldBucket     = false;
                    var roleCombinations = queueGroup.PossibleRoleCombinations();
                    while (roleCombinations.Count() > 0)
                    {
                        var scramble        = AegisRandom.RandomNumber(0, roleCombinations.Count());
                        var roleCombination = roleCombinations[scramble];
                        roleCombinations.RemoveAt(scramble);
                        var playerSides = AegisRandom.RandomBool() ? new List <PlayerSide>()
                        {
                            PlayerSide.Blue, PlayerSide.Red
                        } : new List <PlayerSide>()
                        {
                            PlayerSide.Red, PlayerSide.Blue
                        };
                        foreach (var i in playerSides)
                        {
                            var tempBucket       = new MatchmakeBucket(bucket);
                            var canPutIntoBucket = tempBucket.TryAddRoleCombination(roleCombination, i);
                            if (canPutIntoBucket)
                            {
                                tempBucket.QueueGroups.Add(queueGroup);
                                tempBuckets.Add(tempBucket);
                            }
                            else if (!hasOldBucket)
                            {
                                tempBuckets.Add(tempBucket);
                                hasOldBucket = true;
                            }

                            if (tempBucket.PlayerCount + fillPlayers.Count() >= 10)
                            {
                                filledBucket = tempBucket;
                                break;
                            }
                        }
                        if (filledBucket != null)
                        {
                            break;
                        }
                    }
                    if (filledBucket != null)
                    {
                        break;
                    }
                }
                buckets = tempBuckets;
                if (filledBucket != null)
                {
                    break;
                }
            }

            // if no bucket is filled, then no game is found
            if (filledBucket == null)
            {
                return;
            }

            // now we put all fill players in
            var missingBlueRoles = new List <PlayerRole>();
            var missingRedRoles  = new List <PlayerRole>();

            foreach (PlayerRole role in Enum.GetValues(typeof(PlayerRole)))
            {
                if (role == PlayerRole.Fill)
                {
                    continue;
                }
                missingBlueRoles.Add(role);
                missingRedRoles.Add(role);
            }
            foreach (var role in filledBucket.BluePlayers)
            {
                missingBlueRoles.Remove(role.Key);
            }
            foreach (var role in filledBucket.RedPlayers)
            {
                missingRedRoles.Remove(role.Key);
            }

            foreach (var fillPlayer in fillPlayers)
            {
                var scramble = AegisRandom.RandomNumber(0, missingBlueRoles.Count() + missingRedRoles.Count());
                if (scramble < missingBlueRoles.Count())
                {
                    var role = missingBlueRoles[scramble];
                    missingBlueRoles.RemoveAt(scramble);
                    filledBucket.BluePlayers.Add(role, fillPlayer.Players[0]);
                    filledBucket.QueueGroups.Add(fillPlayer);
                    filledBucket.PlayerCount += 1;
                }
                else
                {
                    var role = missingRedRoles[scramble - missingBlueRoles.Count()];
                    missingRedRoles.RemoveAt(scramble - missingBlueRoles.Count());
                    filledBucket.RedPlayers.Add(role, fillPlayer.Players[0]);
                    filledBucket.QueueGroups.Add(fillPlayer);
                    filledBucket.PlayerCount += 1;
                }
            }

            // insert players into game and randomize side
            var inhouseGame = new InhouseGame(channel.Id);

            foreach (var player in filledBucket.BluePlayers)
            {
                player.Value.PlayerSide = PlayerSide.Blue;
                player.Value.PlayerRole = player.Key;
                inhouseGame.InhousePlayers.Add(player.Value);
            }

            foreach (var player in filledBucket.RedPlayers)
            {
                player.Value.PlayerSide = PlayerSide.Red;
                player.Value.PlayerRole = player.Key;
                inhouseGame.InhousePlayers.Add(player.Value);
            }

            InhouseGames.Add(inhouseGame);
            inhouseGame.QueueGroups = filledBucket.QueueGroups;

            // remove everybody in the game from queue
            var inhousePlayers = inhouseGame.InhousePlayers.Select(x => x.Player.Id);

            inhouseQueue.PlayersInQueue.RemoveAll(x => filledBucket.QueueGroups.Any(y => y == x));

            await ReadyCheck(channel, inhouseGame).ConfigureAwait(false);
        }