public void CalculateBattleElo(BattleEvent e) { var teams = e.EndGameInfos.Where(p => !p.Spectator).GroupBy(p => p.OnVictoryTeam).OrderBy(g => g.Key).ToList(); var loserCount = teams[0].Count(); var winnerCount = teams[1].Count(); var loserElo = teams[0].Average(p => GetPlayer(p.Name).Elo); var winnerElo = teams[1].Average(p => GetPlayer(p.Name).Elo); var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); var scoreWin = 32 * (1 - eWin) / winnerCount; var scoreLose = 32 * (0 - eLose) / loserCount; foreach (var p in teams[0]) { GetPlayer(p.Name).Elo += scoreLose; } foreach (var p in teams[1]) { GetPlayer(p.Name).Elo += scoreWin; } bool is1v1 = e.AreUpgradesDisabled && loserCount == 1 && winnerCount == 1; if (is1v1) { var pLose = GetPlayer(teams[0].First().Name); var pWin = GetPlayer(teams[1].First().Name); loserElo = pLose.Elo1v1; winnerElo = pWin.Elo1v1; eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); scoreWin = 32 * (1 - eWin) / winnerCount; scoreLose = 32 * (0 - eLose) / loserCount; pLose.Elo1v1 += scoreLose; pWin.Elo1v1 += scoreWin; } }
public SendBattleResultOutput SendBattleResult(AuthInfo springieLogin, string mapName, ICollection<EndGamePlayerInfo> usersInGame) { var ret = new SendBattleResultOutput(); ret.RankNotifications = new List<RankNotification>(); if (springieLogin == null) { throw new ArgumentNullException("springieLogin"); } if (usersInGame == null) { throw new ArgumentNullException("usersInGame"); } if (!ValidateSpringieLogin(springieLogin)) { return ret; // silently ignore other than valid springie } var invalids = usersInGame.Where(x => !x.Spectator && Galaxy.GetPlayer(x.Name) == null).ToList(); foreach (var u in invalids) { ret.MessageToDisplay += "Invalid players " + u.Name + " ignored"; usersInGame.Remove(u); } if (!usersInGame.Any(p => p.OnVictoryTeam)) { ret.MessageToDisplay += "No losing players"; return ret; } if (!usersInGame.Any(p => !p.OnVictoryTeam)) { ret.MessageToDisplay += "Only losing players"; return ret; } if (!usersInGame.All(u => u.Spectator || Galaxy.GetPlayer(u.Name) != null)) { throw new Exception("Player is not registered."); } if ( !usersInGame.All( u => u.Spectator || String.Equals(Galaxy.GetPlayer(u.Name).FactionName, u.Side, StringComparison.InvariantCultureIgnoreCase))) { throw new Exception("Faction mismatch."); } var isWithoutUpgrades = disabledUpgradesHosts.Contains(springieLogin.Login); Faction victoriousFaction = null; foreach (var user in usersInGame) { if (user.Spectator) { continue; } var player = Galaxy.Players.Single(p => p.Name == user.Name); if (user.OnVictoryTeam) { player.Victories++; player.MeasuredVictories++; player.MetalEarned += Settings.Default.MetalForVictory; if (victoriousFaction == null) { victoriousFaction = Galaxy.Factions.Single(f => f.Name == player.FactionName); } } else { player.Defeats++; player.MeasuredDefeats++; player.MetalEarned += Settings.Default.MetalForDefeat; } } if (victoriousFaction == null) { ret.MessageToDisplay += "No winners"; return ret; } var planet = Galaxy.Planets.Single(p => p.MapName == mapName); var isConquest = planet.FactionName != victoriousFaction.Name; planet.FactionName = victoriousFaction.Name; if (!isWithoutUpgrades) { KillFleetsAndUpgrades(victoriousFaction, planet); } LastChanged = DateTime.Now; var sb = new StringBuilder(); var encircledPlanetIDs = new List<int>(); if (isConquest) { var encircledPlanets = Galaxy.Planets.Where(p => p.FactionName != victoriousFaction.Name && Galaxy.IsPlanetEncircled(p)); foreach (var p in encircledPlanets) { p.FactionName = victoriousFaction.Name; sb.AppendFormat(",{0} ", p.Name); encircledPlanetIDs.Add(p.ID); } if (sb.Length != 0) { sb.Append("have fallen due to lack of supply."); } } if (!SpringieStates.ContainsKey(springieLogin.Login)) { throw new Exception("No springie state found!"); } var attackingFaction = SpringieStates[springieLogin.Login].GameStartedStatus.OffensiveFactionName; var defendingFaction = Galaxy.Factions.Single(f => f.Name != attackingFaction).Name; Galaxy.Turn++; Galaxy.OffensiveFactionInternal = victoriousFaction.Name; List<PlayerRankChangedEvent> changedRanks; Galaxy.CalculatePlayerRanks(out changedRanks); Galaxy.SwapUnusedPlanets(); CalculateEndTurnMetal(); foreach (var e in changedRanks) { if (e.NewRank > e.OldRank) { new RankNotification(e.PlayerName, string.Format("Congratulations, you have been promoted to {0}!", e.NewRank)); } else { new RankNotification(e.PlayerName, string.Format("You have just lost a rank! Conquer planets to regain it!")); } } var spaceFleetOwners = from f in Galaxy.Fleets where f.IsAtDestination(Galaxy.Turn) select f.OwnerName; var battleEvent = new BattleEvent( DateTime.Now, usersInGame.Where(u => !u.Spectator).ToList(), mapName, attackingFaction, defendingFaction, victoriousFaction.Name, disabledUpgradesHosts.Contains(springieLogin.Login), State.Galaxy, encircledPlanetIDs, spaceFleetOwners); State.Galaxy.Events.Add(battleEvent); Galaxy.CalculateBattleElo(battleEvent); var enemyPlanetCount = Galaxy.Planets.Count(p => p.FactionName != victoriousFaction.Name); if (enemyPlanetCount == 0) { State.Galaxy = Galaxy.AdvanceRound(Settings.Default.GalaxyTemplatePath); ForceSaveState(); ret.MessageToDisplay += string.Format( "{0} HAS FINALLY CONQUERED THE GALAXY! (New round is starting)", victoriousFaction.Name); return ret; } ForceSaveState(); ret.MessageToDisplay += string.Format( "Congratulations, planet {0} {2} by {1} {3}", planet.Name, victoriousFaction.Name, isConquest ? "conquered" : "held", sb); return ret; }