예제 #1
0
        public async Task <IActionResult> GetRecentPlayers([FromBody] GetRecentPlayers.Request req)
        {
            var recentPlayers = new RecentPlayers(SelfHost.playerInfo.playerId.ToString());
            var list          = await recentPlayers.GetAllAsync();

            var res = new GetRecentPlayers.Response();

            res.players = new List <GetRecentPlayers.Player>();
            list.ForEach(p =>
            {
                res.players.Add(new GetRecentPlayers.Player()
                {
                    playerId  = p.field,
                    matchDate = p.value.matchDate,
                    opponent  = p.value.opponent,
                });
            });

            return(Ok(res));
        }
        public async Task <IActionResult> ReportBattleResult([FromBody] ReportBattleResult.Request req)
        {
            var cntEarthnoid = 0;
            var cntSpacenoid = 0;

            for (int i = 0; i < req.personals.Length; i++)
            {
                if (req.personals[i].side == Battle.Side.Earthnoid)
                {
                    cntEarthnoid++;
                }
                if (req.personals[i].side == Battle.Side.Spacenoid)
                {
                    cntSpacenoid++;
                }
            }
            if (cntEarthnoid == 0 || cntSpacenoid == 0)
            {
                return(Ok(new ReportBattleResult.Response()));
            }

            var updateDBs     = new Dictionary <PersonalDBContext, int>();
            var sideEarthnoid = new List <PlayerBattleInformatin>();
            var sideSpacenoid = new List <PlayerBattleInformatin>();
            var winSide       = Battle.Side.Other;

            for (int i = 0; i < req.personals.Length; i++)
            {
                var personal = req.personals[i];
                // pbi: PlayerBattleInformation

                var db = PDBSM.PersonalDBContext(personal.playerId);
                updateDBs[db] = 12345;
                var pbi = await db.PlayerBattleInformations.FindAsync(personal.playerId);

                if (pbi == null)
                {
                    pbi          = new PlayerBattleInformatin();
                    pbi.playerId = personal.playerId;
                    pbi.rating   = Battle.InitialRating;
                    pbi.victory  = 0;
                    pbi.defeat   = 0;
                    pbi.draw     = 0;
                    await db.PlayerBattleInformations.AddAsync(pbi);
                }

                if (personal.result == Battle.Result.VICTORY)
                {
                    pbi.victory++;
                }
                if (personal.result == Battle.Result.DEFEAT)
                {
                    pbi.defeat++;
                }
                if (personal.result == Battle.Result.DRAW)
                {
                    pbi.draw++;
                }

                if (personal.side == Battle.Side.Earthnoid)
                {
                    sideEarthnoid.Add(pbi);
                    if (personal.result == Battle.Result.VICTORY)
                    {
                        winSide = Battle.Side.Earthnoid;
                    }
                }
                if (personal.side == Battle.Side.Spacenoid)
                {
                    sideSpacenoid.Add(pbi);
                    if (personal.result == Battle.Result.VICTORY)
                    {
                        winSide = Battle.Side.Spacenoid;
                    }
                }
            }

            if (winSide == Battle.Side.Earthnoid || winSide == Battle.Side.Spacenoid)
            {
                var ratingEarthnoid = 0f;
                var ratingSpacenoid = 0f;
                sideEarthnoid.ForEach(p => { ratingEarthnoid += p.rating; });
                sideSpacenoid.ForEach(p => { ratingSpacenoid += p.rating; });
                ratingEarthnoid /= sideEarthnoid.Count;
                ratingSpacenoid /= sideSpacenoid.Count;


                Func <float, float, float> GainPoint = (winSideRating, loseSideRating) =>
                {
                    float winPercentage = 1f / (MathF.Pow(10, (loseSideRating - winSideRating) / 400f) + 1f);

                    var   BASE        = 25f;
                    var   COEFFICIENT = 20f;
                    float gain        = BASE + COEFFICIENT * (0.5f - winPercentage);

                    return(gain);
                };

                Action <List <PlayerBattleInformatin>, float, float, bool> TeamAdjustment =
                    (pbiList, ratingAvg, gain, win) =>
                {
                    pbiList.ForEach(async pbi =>
                    {
                        var personalGain = (gain + (win ? 1f : -1f) * gain * (ratingAvg - pbi.rating) / ratingAvg)
                                           * (win ? 1f : -1f);
                        pbi.rating = Math.Clamp(pbi.rating + personalGain, 1f, 5000f);

                        await new Player(pbi.playerId).Invalidate();
                    });
                };


                if (winSide == Battle.Side.Earthnoid)
                {
                    var gain = GainPoint(ratingEarthnoid, ratingSpacenoid);
                    TeamAdjustment(sideEarthnoid, ratingEarthnoid, gain, true);
                    TeamAdjustment(sideSpacenoid, ratingSpacenoid, gain, false);
                }
                else
                {
                    var gain = GainPoint(ratingSpacenoid, ratingEarthnoid);
                    TeamAdjustment(sideEarthnoid, ratingEarthnoid, gain, false);
                    TeamAdjustment(sideSpacenoid, ratingSpacenoid, gain, true);
                }
            }

            foreach (var db in updateDBs.Keys)
            {
                await db.SaveChangesAsync();
            }


            var matchDate = DateTime.UtcNow;

            for (int i = 0; i < req.personals.Length; i++)
            {
                var self = req.personals[i];

                var recentPlayers = new RecentPlayers(self.playerId.ToString());

                for (int j = 0; j < req.personals.Length; j++)
                {
                    var other = req.personals[j];
                    if (other.playerId == self.playerId)
                    {
                        continue;
                    }

                    await recentPlayers.SetFieldAsync(other.playerId, new RecentPlayers.Data()
                    {
                        playerName = other.playerName,
                        matchDate  = matchDate,
                        opponent   = self.side != other.side,
                    });
                }

                var list = await recentPlayers.GetAllAsync();

                list.Sort((a, b) => { return((a.value.matchDate < b.value.matchDate) ? -1 : 1); });

                while (Social.MaxRecentPlayersCnt < list.Count)
                {
                    await recentPlayers.RemoveFieldAsync(list[0].field);
                }
            }


            return(Ok(new ReportBattleResult.Response
            {
            }));
        }