private void RefreshIVs(bool now = false) { if (data == null || pokemon == null) { return; } ivTaskCancelation?.Cancel(); ivTaskCancelation = new CancellationTokenSource(); Task.Run(async() => { if (!now) { await Task.Delay(500); } if (ivTaskCancelation.IsCancellationRequested) { return; } // Simulate IV possibilities Tuple <int, int, int>[] ivPossibilities = Enumerable.Range(0, 16).SelectMany(atk => Enumerable.Range(0, 16).SelectMany(def => Enumerable.Range(0, 16).Select(sta => Tuple.Create(atk, def, sta)))).ToArray(); Tuple <int, int, int>[] matchingIVs = ivPossibilities.AsParallel().Where(ivPossibility => { int cp = pokemon.GetCP(pokemonLevel, ivPossibility.Item1, ivPossibility.Item2, ivPossibility.Item3); int hp = pokemon.GetHP(pokemonLevel, ivPossibility.Item3); // Refine IV possibilities with checkboxes bool refine = false; if (data.CP == cp && data.HP == hp) { if (!attack.Checked && !defense.Checked && !stamina.Checked) { refine = true; } else if (!attack.Checked && !defense.Checked && stamina.Checked) { refine = (ivPossibility.Item3 > ivPossibility.Item1) && (ivPossibility.Item3 > ivPossibility.Item2); } else if (!attack.Checked && defense.Checked && !stamina.Checked) { refine = (ivPossibility.Item2 > ivPossibility.Item1) && (ivPossibility.Item2 > ivPossibility.Item3); } else if (!attack.Checked && defense.Checked && stamina.Checked) { refine = (ivPossibility.Item2 > ivPossibility.Item1) && (ivPossibility.Item2 == ivPossibility.Item3); } else if (attack.Checked && !defense.Checked && !stamina.Checked) { refine = (ivPossibility.Item1 > ivPossibility.Item2) && (ivPossibility.Item1 > ivPossibility.Item3); } else if (attack.Checked && !defense.Checked && stamina.Checked) { refine = (ivPossibility.Item1 > ivPossibility.Item2) && (ivPossibility.Item1 == ivPossibility.Item3); } else if (attack.Checked && defense.Checked && !stamina.Checked) { refine = (ivPossibility.Item1 > ivPossibility.Item3) && (ivPossibility.Item1 == ivPossibility.Item2); } else if (attack.Checked && defense.Checked && stamina.Checked) { refine = (ivPossibility.Item1 == ivPossibility.Item2) && (ivPossibility.Item1 == ivPossibility.Item3); } } return(refine); }).ToArray(); // Sort and limit number matchingIVs = matchingIVs.OrderByDescending(iv => iv.Item1 + iv.Item2 + iv.Item3).ToArray(); // Update UI assistantLayout.Post(() => { if (matchingIVs.Length == 0) { averageValue.Text = "?"; } else { averageValue.Text = ((int)matchingIVs.Average(t => (t.Item1 + t.Item2 + t.Item3) * 100f / 45)) + " %"; } while (ivTable.ChildCount > 1) { ivTable.RemoveViewAt(1); } Action <string, string, string, string> addRow = (attack, defense, stamina, perfection) => { TableRow tableRow = new TableRow(Context); tableRow.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.MatchParent, TableRow.LayoutParams.WrapContent); TextView spacerView1 = new TextView(Context); spacerView1.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.WrapContent, TableRow.LayoutParams.MatchParent, 1); tableRow.AddView(spacerView1); TextView attackView = new TextView(Context); attackView.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.WrapContent, TableRow.LayoutParams.MatchParent, 1); attackView.Text = attack; attackView.Gravity = GravityFlags.CenterHorizontal; attackView.SetTextColor(Color.Black); tableRow.AddView(attackView); TextView defenseView = new TextView(Context); defenseView.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.WrapContent, TableRow.LayoutParams.MatchParent, 1); defenseView.Text = defense; defenseView.Gravity = GravityFlags.CenterHorizontal; defenseView.SetTextColor(Color.Black); tableRow.AddView(defenseView); TextView staminaView = new TextView(Context); staminaView.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.WrapContent, TableRow.LayoutParams.MatchParent, 1); staminaView.Text = stamina; staminaView.Gravity = GravityFlags.CenterHorizontal; staminaView.SetTextColor(Color.Black); tableRow.AddView(staminaView); TextView perfectionView = new TextView(Context); perfectionView.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.WrapContent, TableRow.LayoutParams.MatchParent, 1); perfectionView.Text = perfection; perfectionView.Gravity = GravityFlags.CenterHorizontal; perfectionView.SetTextColor(Color.Black); tableRow.AddView(perfectionView); TextView spacerView2 = new TextView(Context); spacerView2.LayoutParameters = new TableRow.LayoutParams(TableRow.LayoutParams.WrapContent, TableRow.LayoutParams.MatchParent, 1); tableRow.AddView(spacerView2); ivTable.AddView(tableRow, new TableLayout.LayoutParams(TableLayout.LayoutParams.MatchParent, TableLayout.LayoutParams.WrapContent)); }; for (int i = 0; i < matchingIVs.Length; i++) { if (matchingIVs.Length > 8 && i >= 4 && i < matchingIVs.Length - 4) { addRow("...", "...", "...", "..."); i = matchingIVs.Length - 4; } Tuple <int, int, int> ivTuple = matchingIVs[i]; addRow(ivTuple.Item1.ToString(), ivTuple.Item2.ToString(), ivTuple.Item3.ToString(), ((ivTuple.Item1 + ivTuple.Item2 + ivTuple.Item3) * 100 / 45) + " %"); } }); }); }