private PlayerRecord bestEORInRange(int StartPosition, int EndPosition, List <int> skip) { PlayerRecord bestPlayer = null; double bestEOR = 0; LocalMath lmath = new LocalMath(editorModel.FileVersion); foreach (TableRecordModel record in editorModel.TableModels[EditorModel.PLAYER_TABLE].GetRecords()) { PlayerRecord player = (PlayerRecord)record; if (player.TeamId == TeamId && player.PositionId >= StartPosition && player.PositionId <= EndPosition && !skip.Contains(player.PlayerId) && player.YearsPro < 3 && (player.Overall + lmath.pointboost(player, CON, 35)) > bestEOR) { bestPlayer = player; bestEOR = player.Overall + lmath.pointboost(player, CON, 35); } } return(bestPlayer); }
private void mainButton_Click(object sender, EventArgs e) { StreamWriter sw = null; if (output.Checked) { SaveFileDialog sfd = new SaveFileDialog(); DialogResult dr = sfd.ShowDialog(); if (sfd.FileName.Length > 0) { sw = new StreamWriter(sfd.FileName); } } mainButton.Enabled = false; Cursor.Current = Cursors.WaitCursor; LocalMath math = new LocalMath(model.FileVersion); Random rand = new Random(); DepthChartRepairer dcr = new DepthChartRepairer(model, null); // current players sorted by position Dictionary <int, double> playerMeans = new Dictionary <int, double>(); List <List <PlayerRecord> > playersByPosition = new List <List <PlayerRecord> >(); List <List <int> > targetsByPosition = new List <List <int> >(); Dictionary <int, List <double> > playerTargets = new Dictionary <int, List <double> >(); List <int> playersLeft = new List <int>(); Dictionary <int, double> playedGamesFactor = new Dictionary <int, double>(); Dictionary <int, double> startedGamesFactor = new Dictionary <int, double>(); int currentSeason = model.FranchiseTime.Year; Dictionary <int, int> gamesPlayed = new Dictionary <int, int>(); Dictionary <int, int> gamesPlayedLastYear = new Dictionary <int, int>(); Dictionary <int, int> gamesStarted = new Dictionary <int, int>(); Dictionary <int, int> gamesStartedLastYear = new Dictionary <int, int>(); foreach (SeasonGamesPlayedRecord stat in model.TableModels[EditorModel.SEASON_GAMES_PLAYED_TABLE].GetRecords()) { if (stat.Season == currentSeason - 1) { gamesStartedLastYear[stat.PlayerId] = stat.GamesStarted; gamesPlayedLastYear[stat.PlayerId] = stat.GamesPlayed; } else { if (!gamesPlayed.ContainsKey(stat.PlayerId)) { gamesPlayed[stat.PlayerId] = 0; gamesStarted[stat.PlayerId] = 0; } gamesPlayed[stat.PlayerId] += stat.GamesPlayed; if (stat.Season < 0) { gamesStarted[stat.PlayerId] += 3 * stat.GamesPlayed / 4; } else { gamesStarted[stat.PlayerId] += stat.GamesStarted; } } } foreach (KeyValuePair <int, int> pair in gamesStartedLastYear) { if (!gamesStarted.ContainsKey(pair.Key) || gamesStarted[pair.Key] == 0) { startedGamesFactor[pair.Key] = Math.Tanh((double)pair.Value / 6.0); } else { startedGamesFactor[pair.Key] = Math.Tanh((double)pair.Value / 6.0) * Math.Tanh((double)pair.Value / (double)gamesStarted[pair.Key]); } } foreach (KeyValuePair <int, int> pair in gamesPlayedLastYear) { if (!gamesPlayed.ContainsKey(pair.Key) || gamesPlayed[pair.Key] == 0) { playedGamesFactor[pair.Key] = Math.Tanh((double)pair.Value / 6.0); } else { playedGamesFactor[pair.Key] = Math.Tanh((double)pair.Value / 6.0) * Math.Tanh((double)pair.Value / (double)gamesPlayed[pair.Key]); } } List <PlayerRecord> freeAgentsAndRookies = new List <PlayerRecord>(); double youthCredit = ((double)youthSlider.Value) / 10.0; double ageDebit = ((double)ageSlider.Value) / 10.0; double playedCredit = ((double)playedSlider.Value) / 10.0; double startedCredit = ((double)startedSlider.Value) / 10.0; double randomness = ((double)randomSlider.Value) / 50.0; for (int i = 0; i < 21; i++) { playersByPosition.Add(new List <PlayerRecord>()); targetsByPosition.Add(new List <int>()); playersLeft.Add(0); for (int j = 0; j < 100; j++) { targetsByPosition[i].Add(0); } } int numPlayers = 0; foreach (PlayerRecord player in model.TableModels[EditorModel.PLAYER_TABLE].GetRecords()) { playerTargets[player.PlayerId] = new List <double>(); if (player.TeamId < 32 || (rooks.Checked && player.TeamId == 1015) || (freeAgents.Checked && player.TeamId == 1009)) { playersByPosition[player.PositionId].Add(player); playersLeft[player.PositionId]++; if (!rooks.Checked && player.YearsPro == 0) { freeAgentsAndRookies.Add(player); } double delta = playedCredit * (playedGamesFactor.ContainsKey(player.PlayerId) ? playedGamesFactor[player.PlayerId] : 0) + startedCredit * (startedGamesFactor.ContainsKey(player.PlayerId) ? startedGamesFactor[player.PlayerId] : 0) + youthCredit * math.theta(6 - player.YearsPro) * (6.0 - (double)player.YearsPro) / 6.0 - ageDebit * math.theta(player.Age + 5.0 - dcr.positionData[player.PositionId].RetirementAge) * ((double)player.Age + 5.0 - (double)dcr.positionData[player.PositionId].RetirementAge) / 5.0; delta = Math.Min(maxSlider.Value, Math.Max(-maxSlider.Value, delta)); if (player.YearsPro == 0 || player.TeamId == 1009) { delta = 0; } double mu = player.Overall + delta; playerMeans[player.PlayerId] = mu; double sigma = 1.0 + randomness * Math.Abs(playedCredit * (playedGamesFactor.ContainsKey(player.PlayerId) ? playedGamesFactor[player.PlayerId] : 0) + startedCredit * (startedGamesFactor.ContainsKey(player.PlayerId) ? startedGamesFactor[player.PlayerId] : 0) + youthCredit * math.theta(6 - player.YearsPro) * (6.0 - (double)player.YearsPro) / 6.0 + ageDebit * math.theta(player.Age + 5.0 - dcr.positionData[player.PositionId].RetirementAge) * ((double)player.Age + 5.0 - (double)dcr.positionData[player.PositionId].RetirementAge) / 5.0); double total = 0; for (int i = 0; i < 100; i++) { double thisOne = Math.Exp(-Math.Pow((double)i - mu, 2.0) / (2.0 * Math.Pow(sigma, 2.0))); playerTargets[player.PlayerId].Add(thisOne); total += thisOne; } // add anything above 100 to the 99 bin double extra = 0; for (int i = 100; i < 200; i++) { extra += Math.Exp(-Math.Pow((double)i - mu, 2.0) / (2.0 * Math.Pow(sigma, 2.0))); } playerTargets[player.PlayerId][99] += extra; total += extra; // normalize for (int i = 0; i < 100; i++) { playerTargets[player.PlayerId][i] /= total; } } else if (player.TeamId == 1009 || player.TeamId == 1015) { playersLeft[player.PositionId]++; freeAgentsAndRookies.Add(player); } else { continue; } numPlayers++; } for (int i = 0; i < 21; i++) { int total = 0; for (int j = 0; j < 100; j++) { double num = ((double)playersLeft[i]) * Math.Exp(-Math.Pow((double)j - 77.83, 2.0) / 163.44) / 22.66; targetsByPosition[i][j] = Math.Max(0, (int)Math.Round(math.bellcurve(num, Math.Sqrt(num) / 2))); total += targetsByPosition[i][j]; } while (total != playersLeft[i]) { int bin; // pick a bin to adjust while (true) { bin = (int)Math.Round(math.bellcurve(77.83, 9.04)); if (bin < 100 && bin >= 0) { break; } } if (total > playersLeft[i]) { if (targetsByPosition[i][bin] > 0) { targetsByPosition[i][bin]--; total--; } } else { targetsByPosition[i][bin]++; total++; } } } // subtract FA's and rookies as players already allocated, since // we don't want to adjust these guys at all. if (!rooks.Checked || !freeAgents.Checked) { foreach (PlayerRecord player in freeAgentsAndRookies) { // find the closest bin to adjust int binshift = 0; while (targetsByPosition[player.PositionId][Math.Min(99, player.Overall + binshift)] <= 0) { if (binshift >= 0) { binshift = -binshift - 1; } else { binshift = -binshift; } } targetsByPosition[player.PositionId][player.Overall + binshift]--; } } // now make adjustments for (int i = 0; i < 21; i++) { List <int> adjusted = new List <int>(); for (int j = 99; j >= 0; j--) { for (int k = 0; k < targetsByPosition[i][j]; k++) { Dictionary <int, double> relProbs = new Dictionary <int, double>(); double totalProbs = -100; double exponent = -1; double expMax = -1; double expMin = 0; while (Math.Abs((totalProbs - (double)targetsByPosition[i][j] + k) / totalProbs) > 0.01) { if (exponent == -1) { exponent = 1; } else if (expMax == -1) { if (totalProbs > (double)targetsByPosition[i][j] - k) { exponent *= 2; } else { expMax = exponent; exponent = (expMax + expMin) / 2.0; } } else { if (totalProbs > (double)targetsByPosition[i][j] - k) { expMin = exponent; } else { expMax = exponent; } exponent = (expMax + expMin) / 2.0; } totalProbs = 0; foreach (PlayerRecord player in playersByPosition[i]) { if (adjusted.Contains(player.PlayerId)) { continue; } relProbs[player.PlayerId] = Math.Pow(playerTargets[player.PlayerId][j], exponent); totalProbs += relProbs[player.PlayerId]; } } double tempProb = 0; double testRand = totalProbs * rand.NextDouble(); foreach (PlayerRecord player in playersByPosition[i]) { if (adjusted.Contains(player.PlayerId)) { continue; } if (testRand < tempProb + relProbs[player.PlayerId]) { adjusted.Add(player.PlayerId); if (player.Overall == j) { break; } Dictionary <int, int> baseDistributions; Dictionary <int, int> attributeDistributions = new Dictionary <int, int>(); bool young = player.Age < (player.Age - player.YearsPro + dcr.positionData[player.PositionId].RetirementAge) / 2; if (j > player.Overall && young) { baseDistributions = increaseYoungDistributions; } else if (j < player.Overall && young) { baseDistributions = decreaseYoungDistributions; } else if (j > player.Overall && !young) { baseDistributions = increaseOldDistributions; } else { baseDistributions = decreaseOldDistributions; } double total = 0; for (int m = 0; m < attributesByPosition[player.PositionId].Count; m++) { if (attributesByPosition[player.PositionId][m]) { attributeDistributions[m] = baseDistributions[m] * (j > player.Overall ? 99 - player.GetAttribute(m) : player.GetAttribute(m)); total += attributeDistributions[m]; } } if (sw == null) { Trace.WriteLine("Adjusting " + player.ToString() + " " + player.TeamId + " " + player.YearsPro + " -- Current Overall: " + player.Overall + ", Target: " + j); } else { sw.WriteLine("Adjusting " + player.ToString() + " -- Current Overall: " + player.Overall + ", Target: " + j); } for (int m = 0; m < attributesByPosition[player.PositionId].Count; m++) { if (attributesByPosition[player.PositionId][m]) { if (sw == null) { Trace.WriteLine("\t" + Enum.GetName(typeof(MaddenAttribute), m) + ": " + player.GetAttribute(m)); } else { sw.WriteLine("\t" + Enum.GetName(typeof(MaddenAttribute), m) + ": " + player.GetAttribute(m)); } } } while (player.Overall != j) { testRand = total * rand.NextDouble(); tempProb = 0; foreach (KeyValuePair <int, int> pair in attributeDistributions) { if (testRand < tempProb + pair.Value) { player.SetAttribute(pair.Key, player.GetAttribute(pair.Key) + Math.Sign(j - player.Overall)); break; } tempProb += pair.Value; } player.Overall = player.CalculateOverallRating(player.PositionId, false); } if (sw == null) { Trace.WriteLine("New attributes:"); } else { sw.WriteLine("New attributes:"); } for (int m = 0; m < attributesByPosition[player.PositionId].Count; m++) { if (attributesByPosition[player.PositionId][m]) { if (sw == null) { Trace.WriteLine("\t" + Enum.GetName(typeof(MaddenAttribute), m) + ": " + player.GetAttribute(m)); } else { sw.WriteLine("\t" + Enum.GetName(typeof(MaddenAttribute), m) + ": " + player.GetAttribute(m)); } } } break; } tempProb += relProbs[player.PlayerId]; } } // add back on any excess from players who weren't picked foreach (PlayerRecord player in playersByPosition[i]) { if (adjusted.Contains(player.PlayerId)) { continue; } double thisBin = playerTargets[player.PlayerId][j]; if (playerMeans[player.PlayerId] > 98) { playerTargets[player.PlayerId][j - 1] += thisBin; } else { for (int k = 0; k < 100; k++) { playerTargets[player.PlayerId][k] /= (1 - thisBin); } } } } } Cursor.Current = Cursors.Arrow; if (sw != null) { sw.Close(); } MessageBox.Show("Done!"); /* * Dictionary<int, int> bins = new Dictionary<int, int>(); * * for (int i = 0; i < 100; i++) * bins[i] = 0; * * foreach (PlayerRecord player in model.TableModels[EditorModel.PLAYER_TABLE].GetRecords()) * { * bins[player.Overall]++; * } * */ }